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>()); }
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]; }