private void cfgWidget1_BranchSelected(object sender, BasicBlock BranchBlock, IBranchInstruction branch) { ClearSelectedInstructions(); foreach (IInstruction i in BranchBlock.Instructions) { SelectInstruction(i); } IBranchInstruction br = BranchBlock.LastInstruction as IBranchInstruction; if (br.IfTarget.Block != br.Block.PostDominator) { SelectDominatedInstructions(br.IfTarget.Block); } if (br.ElseTarget.Block != br.Block.PostDominator) { SelectDominatedInstructions(br.ElseTarget.Block); } txtLoopCount.Visible = false; lblIterations.Visible = false; chkTaken.Visible = true; chkTaken.Checked = m_TakenBranches.Contains(branch); }
private void BuildBranchNodes(Graph g) { // lay out the dag nodes in order List <Node> Nodes = g.ReversePostOrder(); // Figure out dominance Dictionary <Node, Node> IDOM = g.Dominators(Nodes); for (int i = 0; i < Nodes.Count; i++) { Node n = Nodes[i]; if (n is LoopNode) { // descend into loop nodes BuildBranchNodes((n as LoopNode).SubGraph); } else { LeafNode leaf = n as LeafNode; BasicBlock bl = leaf.Block; // mark break, branch, and continue nodes as such if (bl.LastInstruction is IBranchInstruction) { IBranchInstruction branch = bl.LastInstruction as IBranchInstruction; if (branch.Category == BranchCategory.BREAK_BRANCH) { leaf.NodeType = "break"; } else if (branch.Category == BranchCategory.CONTINUE_BRANCH) { leaf.NodeType = "continue"; } else if (branch.Category == BranchCategory.LOOPSKIP_BRANCH) { leaf.NodeType = "node"; } else if (branch.Category == BranchCategory.SKIP_BRANCH) { leaf.NodeType = "skip"; } else { leaf.NodeType = "branch"; } } else { // mark continue nodes as such if (bl.InnerMostLoop != null && bl.Successors.First() == bl.InnerMostLoop.Header) { n.NodeType = "continue"; } } } } int k = 0; while (k < Nodes.Count) { if (Nodes[k] is LeafNode && Nodes[k].NodeType.Equals("branch")) { BranchNode br = new BranchNode((Nodes[k] as LeafNode)); List <Node> descendents = new List <Node>(g.ChildrenOf(Nodes[k])); Graph[] branchGraphs = new Graph[2]; branchGraphs[0] = br.IfGraph; branchGraphs[1] = br.ElseGraph; for (int k0 = k + 1; k0 < Nodes.Count; k0++) { Node n = Nodes[k0]; for (int j = 0; j < descendents.Count; j++) { if (Algorithms.Dominates(descendents[j], n, IDOM)) { branchGraphs[j].AddNode(n); } } } br.OwnedNodes.AddRange(branchGraphs[0].Nodes); br.OwnedNodes.AddRange(branchGraphs[1].Nodes); Graph branchGraph = new Graph(); g.CombineNodes(br.OwnedNodes, br, branchGraph); branchGraph.TransferEdgesToSubgraph(branchGraphs[0]); branchGraph.TransferEdgesToSubgraph(branchGraphs[1]); // do this recursively on the if/else branches BuildBranchNodes(br.IfGraph); BuildBranchNodes(br.ElseGraph); // start over k = 0; Nodes = g.ReversePostOrder(); } else if (Nodes[k] is LeafNode && Nodes[k].NodeType.Equals("skip")) { Dictionary <Node, Node> PDOM = g.PostDominators(Nodes); // find nodes to put into the sub-graph // these are all the nodes which are skipped // nodes are skipped if they are post-dominated by the convergence node (which post-dominates the test) Node joinPoint = PDOM[Nodes[k]]; Graph branchGraph = new Graph(); for (int k0 = k + 1; Nodes[k0] != joinPoint; k0++) { Node n = Nodes[k0]; if (Algorithms.Dominates(joinPoint, Nodes[k0], PDOM)) { branchGraph.AddNode(Nodes[k0]); } } SkipNode sk = new SkipNode((Nodes[k] as LeafNode), branchGraph); // now make a graph containing both test node and all skipped nodes // combine these into one skip node List <Node> ownedNodes = new List <Node>(branchGraph.Nodes); ownedNodes.Add(Nodes[k]); Graph tmpGraph = new Graph(); g.CombineNodes(ownedNodes, sk, tmpGraph); tmpGraph.TransferEdgesToSubgraph(branchGraph); // do this recursively on the skipped nodes BuildBranchNodes(sk.BranchGraph); // start over k = 0; Nodes = g.ReversePostOrder(); } else { k++; } } }
public static List <BasicBlock> BuildBasicBlocks(List <IInstruction> ops) { // collect set of branch targets HashSet <IInstruction> BranchTargets = new HashSet <IInstruction>(); foreach (IInstruction op in ops) { if (op is IJumpInstruction) { IJumpInstruction it = op as IJumpInstruction; BranchTargets.Add(it.Target); } else if (op is IBranchInstruction) { IBranchInstruction it = op as IBranchInstruction; BranchTargets.Add(it.IfTarget); BranchTargets.Add(it.ElseTarget); } } // walk instruction list and split off blocks at branches or branch targets List <BasicBlock> Blocks = new List <BasicBlock>(); int nInstructions = ops.Count; int i = 0; do { BasicBlock block = new BasicBlock(); Blocks.Add(block); do { IInstruction op = ops[i++]; block.AddInstruction(op); op.Block = block; // stop if we just added a branch/jump op if (op is IJumpInstruction || op is IBranchInstruction) { break; } // stop if next instruction is a branch target if (i < nInstructions && BranchTargets.Contains(ops[i])) { break; } } while (i < nInstructions); } while (i < nInstructions); // construct CFG edges for (int b = 0; b < Blocks.Count; b++) { IInstruction op = Blocks[b].LastInstruction; if (op is IBranchInstruction) { IBranchInstruction branch = op as IBranchInstruction; if (branch.IfTarget != null) { branch.Block.AddSuccessor(branch.IfTarget.Block); branch.IfTarget.Block.AddPredecessor(branch.Block); } if (branch.ElseTarget != null) { branch.Block.AddSuccessor(branch.ElseTarget.Block); branch.ElseTarget.Block.AddPredecessor(branch.Block); } } else if (op is IJumpInstruction) { // unconditional branch or jump, add target as one and only successor IJumpInstruction jmp = op as IJumpInstruction; if (jmp.Target != null) { jmp.Block.AddSuccessor(jmp.Target.Block); jmp.Target.Block.AddPredecessor(jmp.Block); } } else if (b < Blocks.Count - 1) { // Block ends in something other than a branch or jump // add next block as successor Blocks[b].AddSuccessor(Blocks[b + 1]); Blocks[b + 1].AddPredecessor(Blocks[b]); } } return(Blocks); }
public static List <IInstruction> DoTrace(List <IInstruction> ops, List <BasicBlock> blocks, List <Loop> loops, HashSet <IInstruction> takenBranches) { List <IInstruction> Exec = new List <IInstruction>(); Dictionary <Loop, int> LoopCounts = new Dictionary <Loop, int>(); foreach (Loop l in loops) { LoopCounts.Add(l, 0); } BasicBlock b = blocks.First(); do { // execute all instructions in current block Exec.AddRange(b.Instructions); // if block ends in a branch, determine which edge to take IInstruction blockEnd = b.LastInstruction; BasicBlock next = null; if (blockEnd is IBranchInstruction) { IBranchInstruction branch = blockEnd as IBranchInstruction; if (branch.Category == BranchCategory.BREAK_BRANCH) { // take a break branch as soon as the iteration count reaches zero BasicBlock exit = branch.IfTarget.Block; BasicBlock noexit = branch.ElseTarget.Block; if (exit.InnerMostLoop == b.InnerMostLoop) { exit = branch.ElseTarget.Block; noexit = branch.IfTarget.Block; } if (LoopCounts[b.InnerMostLoop] >= b.InnerMostLoop.DesiredIterations) { LoopCounts[b.InnerMostLoop] = 0; next = exit; } else { next = noexit; } } else if (branch.Category == BranchCategory.LOOPSKIP_BRANCH) { // don't enter unless the loop's iteration count is non-zero BasicBlock loop; BasicBlock noloop; if (branch.IfTarget.Block.InnerMostLoop != branch.Block.InnerMostLoop) { loop = branch.IfTarget.Block; noloop = branch.ElseTarget.Block; } else { loop = branch.ElseTarget.Block; noloop = branch.IfTarget.Block; } if (loop.InnerMostLoop.DesiredIterations > 0) { next = loop; } else { next = noloop; } } else if (branch.Category == BranchCategory.CONTINUE_BRANCH) { // do NOT take a continue branch if the count's up BasicBlock go = branch.IfTarget.Block; BasicBlock nogo = branch.ElseTarget.Block; if (nogo == b.InnerMostLoop.Header) { go = branch.ElseTarget.Block; nogo = branch.IfTarget.Block; // swap if needed } if (LoopCounts[b.InnerMostLoop] >= b.InnerMostLoop.DesiredIterations) { next = nogo; } else { next = go; } } else { if (takenBranches.Contains(branch)) { next = branch.IfTarget.Block; } else { next = branch.ElseTarget.Block; } } } else if (blockEnd is IJumpInstruction) { // if block ends in a jump, then jump IJumpInstruction jump = blockEnd as IJumpInstruction; next = jump.Target.Block; } else { // otherwise, proceed to next successor block if (b.SuccessorCount > 0) { next = b.Successors.First(); } } // increment loop count every time we pass a loop header if (b.InnerMostLoop != null && b.InnerMostLoop.Header == b) { LoopCounts[b.InnerMostLoop]++; } b = next; } while (b != null); return(Exec); }
static public void ClassifyBranches(List <IInstruction> ops) { // It can be shown (I think) that, given our irreducible graph/nested loop structure // for any branch node n in loop L // at least one of N's two edges must be to a node also in L // // This follows from the construction of the loops // The loop set is the set of nodes dominated by the header // having paths to the header using only nodes in the loop set // // // Note that it is still possible to have a branch that descends into one of two different // nested sub-loops // We can thus classify branch instructions into two types: // - Fork // * both targets are nested within the containing block's loop // // - Break branch // * At most one target is outside the containing block's loop // foreach (IInstruction op in ops) { if (!(op is IBranchInstruction)) { continue; } IBranchInstruction branch = op as IBranchInstruction; Loop ifLoop = branch.IfTarget.Block.InnerMostLoop; Loop elseLoop = branch.ElseTarget.Block.InnerMostLoop; Loop blockLoop = op.Block.InnerMostLoop; if (blockLoop == null) { branch.Category = BranchCategory.FORK_BRANCH; } else { if (ifLoop == null && elseLoop == null) { branch.Category = BranchCategory.FORK_BRANCH; } else if (ifLoop == null && elseLoop != null) { branch.Category = BranchCategory.BREAK_BRANCH; } else if (ifLoop != null && elseLoop == null) { branch.Category = BranchCategory.BREAK_BRANCH; } else if (ifLoop.IsNestedIn(blockLoop) && elseLoop.IsNestedIn(blockLoop)) { branch.Category = BranchCategory.FORK_BRANCH; } else if (ifLoop.IsNestedIn(blockLoop) || elseLoop.IsNestedIn(blockLoop)) { branch.Category = BranchCategory.BREAK_BRANCH; } else { throw new System.Exception("Ooops"); } } // A "fork branch" can, in turn, be classified as: // - continue (conditional jump back to header) // - skip (jumps directly to branch's post-dominator) // - fork (everything else) if (branch.Category == BranchCategory.FORK_BRANCH) { if (blockLoop != null && (branch.IfTarget == blockLoop.Header || branch.ElseTarget == blockLoop.Header)) { branch.Category = BranchCategory.CONTINUE_BRANCH; } if (branch.IfTarget.Block == branch.Block.PostDominator || branch.ElseTarget.Block == branch.Block.PostDominator) { branch.Category = BranchCategory.SKIP_BRANCH; // a skip branch that jumps around a loop is yet another special case if (branch.IfTarget.Block != branch.Block.PostDominator && branch.IfTarget.Block.InnerMostLoop != blockLoop) { branch.Category = BranchCategory.LOOPSKIP_BRANCH; } else if (branch.ElseTarget.Block != branch.Block.PostDominator && branch.ElseTarget.Block.InnerMostLoop != blockLoop) { branch.Category = BranchCategory.LOOPSKIP_BRANCH; } } } } }
private void cfgWidget1_BranchSelected(object sender, BasicBlock BranchBlock, IBranchInstruction branch) { ClearSelectedInstructions(); foreach (IInstruction i in BranchBlock.Instructions) SelectInstruction(i); IBranchInstruction br = BranchBlock.LastInstruction as IBranchInstruction; if( br.IfTarget.Block != br.Block.PostDominator ) SelectDominatedInstructions(br.IfTarget.Block); if (br.ElseTarget.Block != br.Block.PostDominator) SelectDominatedInstructions(br.ElseTarget.Block); txtLoopCount.Visible = false; lblIterations.Visible = false; chkTaken.Visible = true; chkTaken.Checked = m_TakenBranches.Contains(branch); }