public void CreatesMultipleBasicBlocksWhenBranchingInstructionsArePresent() { // Arrange. var instructions = new InstructionBase[] { new NormalInstruction(), new NormalInstruction(), new BranchingInstruction { BranchType = BranchType.Conditional }, new NormalInstruction() }; // Act. var controlFlowGraph = ControlFlowGraph.FromInstructions(instructions); // Assert. Assert.That(controlFlowGraph.BasicBlocks, Is.Not.Null); Assert.That(controlFlowGraph.BasicBlocks, Has.Count.EqualTo(2)); Assert.That(controlFlowGraph.BasicBlocks[0].Position, Is.EqualTo(0)); Assert.That(controlFlowGraph.BasicBlocks[0].Instructions, Has.Count.EqualTo(3)); Assert.That(controlFlowGraph.BasicBlocks[0].Successors, Has.Count.EqualTo(1)); Assert.That(controlFlowGraph.BasicBlocks[0].Successors[0], Is.EqualTo(controlFlowGraph.BasicBlocks[1])); Assert.That(controlFlowGraph.BasicBlocks[1].Position, Is.EqualTo(1)); Assert.That(controlFlowGraph.BasicBlocks[1].Instructions, Has.Count.EqualTo(1)); Assert.That(controlFlowGraph.BasicBlocks[1].Successors, Is.Empty); }
public void SetsNextProgramCounterForEveryInstruction() { // Arrange. var instructions = new List <InstructionBase> { CreateInstruction <NormalInstruction>(), // 0 CreateInstruction <BranchingInstruction>(), // 1 Unconditional branch to [3] CreateInstruction <NormalInstruction>(), // 2 Skipped CreateInstruction <BranchingInstruction>(), // 3 Conditional branch to [5] CreateInstruction <NormalInstruction>(), // 4 CreateInstruction <NormalInstruction>() // 5 }; ((BranchingInstruction)instructions[1]).BranchType = BranchType.Unconditional; ((BranchingInstruction)instructions[1]).BranchTarget = instructions[3]; ((BranchingInstruction)instructions[3]).BranchType = BranchType.Conditional; ((BranchingInstruction)instructions[3]).BranchTarget = instructions[5]; var controlFlowGraph = ControlFlowGraph.FromInstructions(instructions); // Act. var executableInstructions = ExecutableInstructionRewriter.Rewrite(controlFlowGraph).ToList(); // Assert. Assert.That(executableInstructions, Has.Count.EqualTo(6)); Assert.That(((NonDivergentExecutableInstruction)executableInstructions[0]).NextPC, Is.EqualTo(1)); Assert.That(((NonDivergentExecutableInstruction)executableInstructions[1]).NextPC, Is.EqualTo(3)); Assert.That(((NonDivergentExecutableInstruction)executableInstructions[2]).NextPC, Is.EqualTo(3)); Assert.That(((DivergentExecutableInstruction)executableInstructions[3]).NextPCs, Is.EquivalentTo(new[] { 4, 5 })); Assert.That(((DivergentExecutableInstruction)executableInstructions[3]).ReconvergencePC, Is.EqualTo(5)); Assert.That(((NonDivergentExecutableInstruction)executableInstructions[4]).NextPC, Is.EqualTo(5)); Assert.That(((NonDivergentExecutableInstruction)executableInstructions[5]).NextPC, Is.EqualTo(6)); }
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 CreatesSingleBasicBlockWhenNoBranchingInstructions() { // Arrange. var instructions = new[] { new NormalInstruction(), new NormalInstruction(), new NormalInstruction() }; // Act. var controlFlowGraph = ControlFlowGraph.FromInstructions(instructions); // Assert. Assert.That(controlFlowGraph.BasicBlocks, Is.Not.Null); Assert.That(controlFlowGraph.BasicBlocks, Has.Count.EqualTo(1)); Assert.That(controlFlowGraph.BasicBlocks[0].Position, Is.EqualTo(0)); Assert.That(controlFlowGraph.BasicBlocks[0].Instructions, Has.Count.EqualTo(3)); Assert.That(controlFlowGraph.BasicBlocks[0].Successors, Is.Empty); }
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]; }