public void RewritesIfElsesToBranches()
        {
            // Arrange.
            var instructions = new[]
            {
                CreateInstruction(OpcodeType.Add),
                CreateInstruction(OpcodeType.If),
                CreateInstruction(OpcodeType.Add),
                CreateInstruction(OpcodeType.Else),
                CreateInstruction(OpcodeType.Mul),
                CreateInstruction(OpcodeType.EndIf),
                CreateInstruction(OpcodeType.Add)
            };

            // Act.
            var rewrittenInstructions = ExplicitBranchingRewriter.Rewrite(instructions).ToList();

            // Assert.
            Assert.That(rewrittenInstructions, Has.Count.EqualTo(6));
            Assert.That(rewrittenInstructions[0], Is.InstanceOf <NormalInstruction>());
            AssertBranchingInstruction(rewrittenInstructions[1], rewrittenInstructions[4], BranchType.Conditional);
            Assert.That(rewrittenInstructions[2], Is.InstanceOf <NormalInstruction>());
            AssertBranchingInstruction(rewrittenInstructions[3], rewrittenInstructions[5], BranchType.Unconditional);
            Assert.That(rewrittenInstructions[4], Is.InstanceOf <NormalInstruction>());
            Assert.That(rewrittenInstructions[5], Is.InstanceOf <NormalInstruction>());
        }
        public ControlFlowViewerViewModel(IExtendedShell extendedShell)
        {
            _graph = new CfgGraph();

            extendedShell.ActiveDocumentChanged += (sender, e) =>
            {
                Graph.RemoveVertexIf(x => true);
                Graph.Clear();

                var rewrittenInstructions = ExplicitBranchingRewriter.Rewrite(e.Editor.BytecodeContainer.Shader.InstructionTokens);
                var cfg = ControlFlowGraph.FromInstructions(rewrittenInstructions);

                var basicBlockLookup = cfg.BasicBlocks.ToDictionary(x => x, x => new BasicBlockViewModel(x));

                Graph.AddVertexRange(basicBlockLookup.Values);

                foreach (var basicBlock in cfg.BasicBlocks)
                {
                    foreach (var successor in basicBlock.Successors)
                    {
                        Graph.AddEdge(new CfgEdge(basicBlockLookup[basicBlock], basicBlockLookup[successor]));
                    }
                    if (basicBlock.ImmediatePostDominator != null)
                    {
                        Graph.AddEdge(new CfgEdge(basicBlockLookup[basicBlock],
                                                  basicBlockLookup[basicBlock.ImmediatePostDominator])
                        {
                            IsImmediatePostDominatorEdge = true
                        });
                    }
                }

                NotifyOfPropertyChange(() => LayoutAlgorithmType);
            };
        }
        public void HandlesNestedControlFlowStructures()
        {
            // Arrange.
            var instructions = new[]
            {
                CreateInstruction(OpcodeType.Add),                               // 0  => 0
                CreateInstruction(OpcodeType.Loop),                              // 1
                CreateInstruction(OpcodeType.Loop),                              // 2
                CreateInstruction(OpcodeType.BreakC),                            // 3  => 1
                CreateInstruction(OpcodeType.EndLoop),                           // 4  => 2
                CreateInstruction(OpcodeType.If),                                // 5  => 3
                CreateInstruction(OpcodeType.BreakC),                            // 6  => 4
                CreateInstruction(OpcodeType.EndIf),                             // 7
                CreateInstruction(OpcodeType.Loop),                              // 8
                CreateInstruction(OpcodeType.If),                                // 9  => 5
                CreateInstruction(OpcodeType.Break),                             // 10 => 6
                CreateInstruction(OpcodeType.Else),                              // 11 => 7
                CreateInstruction(OpcodeType.Mul),                               // 12 => 8
                CreateInstruction(OpcodeType.EndIf),                             // 13
                CreateInstruction(OpcodeType.EndLoop),                           // 14 => 9
                CreateInstruction(OpcodeType.EndLoop),                           // 15 => 10
                CreateInstruction(OpcodeType.Add)                                // 16 => 11
            };

            // Act.
            var rewrittenInstructions = ExplicitBranchingRewriter.Rewrite(instructions).ToList();

            // Assert.
            Assert.That(rewrittenInstructions, Has.Count.EqualTo(12));
            Assert.That(rewrittenInstructions[0], Is.InstanceOf <NormalInstruction>());
            AssertBranchingInstruction(rewrittenInstructions[1], rewrittenInstructions[3], BranchType.Conditional);
            AssertBranchingInstruction(rewrittenInstructions[2], rewrittenInstructions[1], BranchType.Unconditional);
            AssertBranchingInstruction(rewrittenInstructions[3], rewrittenInstructions[5], BranchType.Conditional);
            AssertBranchingInstruction(rewrittenInstructions[4], rewrittenInstructions[11], BranchType.Conditional);
            AssertBranchingInstruction(rewrittenInstructions[5], rewrittenInstructions[8], BranchType.Conditional);
            AssertBranchingInstruction(rewrittenInstructions[6], rewrittenInstructions[10], BranchType.Unconditional);
            AssertBranchingInstruction(rewrittenInstructions[7], rewrittenInstructions[9], BranchType.Unconditional);
            Assert.That(rewrittenInstructions[8], Is.InstanceOf <NormalInstruction>());
            AssertBranchingInstruction(rewrittenInstructions[9], rewrittenInstructions[5], BranchType.Unconditional);
            AssertBranchingInstruction(rewrittenInstructions[10], rewrittenInstructions[1], BranchType.Unconditional);
            Assert.That(rewrittenInstructions[11], Is.InstanceOf <NormalInstruction>());
        }
Exemple #4
0
        public VirtualMachine(BytecodeContainer bytecode, int numContexts)
        {
            if (bytecode.Shader.Version.ProgramType == ProgramType.PixelShader && numContexts % 4 != 0)
            {
                throw new ArgumentOutOfRangeException("numContexts", "numContexts must be a multiple of 4 for pixel shaders.");
            }

            _bytecode = bytecode;

            var instructionTokens     = bytecode.Shader.Tokens.OfType <InstructionToken>().ToArray();
            var branchingInstructions = ExplicitBranchingRewriter.Rewrite(instructionTokens);
            var controlFlowGraph      = ControlFlowGraph.FromInstructions(branchingInstructions);

            _executableInstructions = ExecutableInstructionRewriter.Rewrite(controlFlowGraph).ToArray();

            _requiredRegisters = RequiredRegisters.FromShader(bytecode.Shader);

            _executionContexts = new ExecutionContext[numContexts];
            for (int i = 0; i < _executionContexts.Length; i++)
            {
                _executionContexts[i] = new ExecutionContext(this, i, _requiredRegisters);
            }

            ConstantBuffers = new Number4[_requiredRegisters.ConstantBuffers.Count][];
            for (int i = 0; i < _requiredRegisters.ConstantBuffers.Count; i++)
            {
                ConstantBuffers[i] = new Number4[_requiredRegisters.ConstantBuffers[i]];
            }

            TextureSamplers = new TextureSampler[_requiredRegisters.Resources.Count];
            for (int i = 0; i < _requiredRegisters.Resources.Count; i++)
            {
                TextureSamplers[i] = TextureSamplerFactory.Create(_requiredRegisters.Resources[i]);
            }

            Textures = new ITexture[_requiredRegisters.Resources.Count];
            Samplers = new SamplerState[_requiredRegisters.Samplers];
        }