private static int GetReconvergencePoint(ControlFlowGraph cfg, BranchingInstruction branchingInstruction) { // Find BasicBlock that contains the branching instruction. var sourceBasicBlock = cfg.BasicBlocks.Single(x => x.Instructions.Contains(branchingInstruction)); // Get first instruction in the immediate post dominator block. var firstInstruction = sourceBasicBlock.ImmediatePostDominator.Instructions.First(); // Return index of this instruction. return GetInstructionIndex(cfg.AllInstructions, firstInstruction); }
public static ControlFlowGraph FromInstructions(IEnumerable<InstructionBase> instructions) { var instructionsList = instructions.ToList(); var result = new ControlFlowGraph(instructionsList); // The following algorithm is from "Analyzing Control Flow in Java Bytecode" by Jianjun Zhao. // Determine the basic blocks by finding the set of leaders: // - The first instruction is a leader. // - Each instruction that is the target of an unconditional branch is a leader. // - Each instruction that is the target of a conditional branch is a leader. // - Each instruction that immediately follows a conditional or unconditional branch is a leader. // - TODO: switch statements. // Each leader gives rise to a basic block consisting of all instructions up to the next leader // or the end of the bytecode. var blockInstructions = new List<InstructionBase>(); int position = 0; for (int i = 0; i < instructionsList.Count; i++) { if (IsLeader(instructionsList, i) && blockInstructions.Any()) { result.BasicBlocks.Add(new BasicBlock(position++, blockInstructions)); blockInstructions = new List<InstructionBase>(); } blockInstructions.Add(instructionsList[i]); } result.BasicBlocks.Add(new BasicBlock(position, blockInstructions)); // Now we can use the following rules to construct the CFG. // Given that u and v are basic blocks: // - Add an edge (u,v) if v follows u in the bytecode and u does not terminate in an unconditional branch. // - Add an edge (u,v) if the last instruction of u is a conditional or unconditional branch to the first // instruction of v. // - TODO: switch statements. foreach (var u in result.BasicBlocks) { foreach (var v in result.BasicBlocks.Where(x => x != u)) { if ((v.Position == u.Position + 1 && !u.Instructions.Last().IsUnconditionalBranch) || u.Instructions.Last().BranchesTo(v.Instructions.First())) u.Successors.Add(v); } } result.ComputePostDominators(); return result; }
public static IEnumerable<ExecutableInstruction> Rewrite(ControlFlowGraph controlFlowGraph) { foreach (var explicitBranchingInstruction in controlFlowGraph.AllInstructions) { int thisPC = GetInstructionIndex(controlFlowGraph.AllInstructions, explicitBranchingInstruction); if (explicitBranchingInstruction is BranchingInstruction && !explicitBranchingInstruction.IsUnconditionalBranch) { var branchingInstruction = (BranchingInstruction) explicitBranchingInstruction; yield return new DivergentExecutableInstruction(explicitBranchingInstruction.InstructionToken, branchingInstruction.BranchIfPositive) { ReconvergencePC = GetReconvergencePoint(controlFlowGraph, branchingInstruction), NextPCs = new List<int> { GetInstructionIndex(controlFlowGraph.AllInstructions, ((BranchingInstruction) explicitBranchingInstruction).BranchTarget), thisPC + 1 }, OpcodeType = ExecutableOpcodeType.BranchC }; } else { ExecutableOpcodeType opcodeType; int nextPC; if (explicitBranchingInstruction.IsUnconditionalBranch) { opcodeType = ExecutableOpcodeType.Branch; nextPC = GetInstructionIndex(controlFlowGraph.AllInstructions, ((BranchingInstruction) explicitBranchingInstruction).BranchTarget); } else { opcodeType = MapOpcodeType(explicitBranchingInstruction.InstructionToken.Header.OpcodeType); nextPC = thisPC + 1; } yield return new NonDivergentExecutableInstruction(explicitBranchingInstruction.InstructionToken) { NextPC = nextPC, OpcodeType = opcodeType, }; } } }
public void CanComputePostDominators() { // Arrange. // A // |\ // | \ // B C // | \ // | \ // D__>__E // | / // | / // | / // | / // |/ // F var blockA = new BasicBlock(0, null); var blockB = new BasicBlock(1, null); var blockC = new BasicBlock(2, null); var blockD = new BasicBlock(3, null); var blockE = new BasicBlock(4, null); var blockF = new BasicBlock(5, null); blockA.Successors.AddRange(new[] { blockB, blockC }); blockB.Successors.AddRange(new[] { blockD }); blockC.Successors.AddRange(new[] { blockE }); blockD.Successors.AddRange(new[] { blockE, blockF }); blockE.Successors.AddRange(new[] { blockF }); var controlFlowGraph = new ControlFlowGraph(null) { BasicBlocks = { blockA, blockB, blockC, blockD, blockE, blockF } }; // Act. controlFlowGraph.ComputePostDominators(); // Assert. Assert.That(blockA.ImmediatePostDominator, Is.EqualTo(blockF)); Assert.That(blockB.ImmediatePostDominator, Is.EqualTo(blockD)); Assert.That(blockC.ImmediatePostDominator, Is.EqualTo(blockE)); Assert.That(blockD.ImmediatePostDominator, Is.EqualTo(blockF)); Assert.That(blockE.ImmediatePostDominator, Is.EqualTo(blockF)); Assert.That(blockF.ImmediatePostDominator, Is.Null); }