GetBasicBlockLinearIrInstructions(CilBasicBlock basicBlock) { var result = new List <LinearIrInstruction>(); foreach (var instruction in basicBlock.Instructions) { result.Add(GetLinearIrInstructionFrom(instruction)); } return(result); }
/// <summary> /// Recursive implementation of a DFS traversal on the control flow graph. /// Recursion enables us to easily save the number of elements on the /// evaluation stack before traversing a path. This way we know the /// state of the evaluation stack after the control flow path is examined, /// and we can move on with a valid evaluation stack to the other paths. /// </summary> /// <param name="basicBlock"> The starting basic block </param> /// <param name="visited"> /// A map of visited nodes to their respective linear ir code string /// </param> private void RecursiveDFS(CilBasicBlock basicBlock) { visited.Add(basicBlock, GetBasicBlockLinearIrInstructions(basicBlock)); int evaluationStackSizeSnapshot = evaluationStackSize; foreach (var outBasicBlock in basicBlock.OutBasicBlocks) { evaluationStackSize = evaluationStackSizeSnapshot; if (!visited.ContainsKey(outBasicBlock)) { RecursiveDFS(outBasicBlock); } } }
/// <summary> /// Performs a pass over the method body instructions and identifies the basic blocks. /// This pass essentially generates the nodes of the graph. /// </summary> private void ConstructBasicBlocks() { int basicBlockId = 0; var currentBasicBlock = new CilBasicBlock(basicBlockId); foreach (var instruction in instructions) { currentBasicBlock.Instructions.Add(instruction); // Update the dictionary for the branch target instructions. if (branchTargetInstructionDictionary.ContainsKey(instruction)) { branchTargetInstructionDictionary[instruction] = currentBasicBlock; } if (instruction.Next == null || branchTargetInstructionDictionary.ContainsKey(instruction.Next) || // Next BB starts at branch target. instruction.IsControlFlowInstruction()) // BB ends at branch. { // When we reach the end of the Basic block // we add it to the result list. BasicBlocks.Add(currentBasicBlock); currentBasicBlock = new CilBasicBlock(++basicBlockId); } } }