コード例 #1
0
ファイル: ScrutinizerForm.cs プロジェクト: rodrigobmg/Pyramid
        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);
        }
コード例 #2
0
        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++;
                }
            }
        }
コード例 #3
0
ファイル: Algorithms.cs プロジェクト: kleopatra999/Pyramid
        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);
        }
コード例 #4
0
ファイル: Algorithms.cs プロジェクト: kleopatra999/Pyramid
        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);
        }
コード例 #5
0
ファイル: Algorithms.cs プロジェクト: kleopatra999/Pyramid
        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;
                        }
                    }
                }
            }
        }
コード例 #6
0
ファイル: ScrutinizerForm.cs プロジェクト: bobvodka/Pyramid
        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);
        }