Exemple #1
0
        public void Path()
        {
            // Artificially construct a path of four nodes in sequential order.
            var graph = TestGraphs.CreatePath();
            var n1    = graph.GetNodeByOffset(0);
            var n2    = graph.GetNodeByOffset(1);
            var n3    = graph.GetNodeByOffset(2);
            var n4    = graph.GetNodeByOffset(3);

            var dominatorTree = DominatorTree <DummyInstruction> .FromGraph(graph);

            Assert.Equal(graph.Entrypoint, dominatorTree.Root.OriginalNode);

            Assert.True(dominatorTree.Dominates(n1, n1));
            Assert.True(dominatorTree.Dominates(n1, n2));
            Assert.True(dominatorTree.Dominates(n1, n3));
            Assert.True(dominatorTree.Dominates(n1, n4));

            Assert.False(dominatorTree.Dominates(n2, n1));
            Assert.True(dominatorTree.Dominates(n2, n2));
            Assert.True(dominatorTree.Dominates(n2, n3));
            Assert.True(dominatorTree.Dominates(n2, n4));

            Assert.False(dominatorTree.Dominates(n3, n1));
            Assert.False(dominatorTree.Dominates(n3, n2));
            Assert.True(dominatorTree.Dominates(n3, n3));
            Assert.True(dominatorTree.Dominates(n3, n4));

            Assert.False(dominatorTree.Dominates(n4, n1));
            Assert.False(dominatorTree.Dominates(n4, n2));
            Assert.False(dominatorTree.Dominates(n4, n3));
            Assert.True(dominatorTree.Dominates(n4, n4));
        }
        /// <summary>
        /// Analyzes <paramref name="interval"/> and makes a loop from it, if possible.
        /// </summary>
        /// <param name="interval">The interval to be analyzed.</param>
        /// <returns>Returns true if a loop was made.</returns>
        private bool TryMakeLoop(IntervalConstruct interval, DominatorTree dominatorTree)
        {
            DFSTree dfsTree = DFSTBuilder.BuildTree(interval);

            if (dfsTree.BackEdges.Count == 0)
            {
                /// No back edges in the interval, so no loop can be made.
                return(false);
            }

            HashSet <ILogicalConstruct> loopBody;
            HashSet <ILogicalConstruct> possibleLatchingNodes = BuildLoop(dfsTree, out loopBody);
            ConditionLogicalConstruct   loopCondition;
            LoopType typeOfLoop = DetermineLoopType(loopBody, possibleLatchingNodes, interval, dominatorTree, out loopCondition);

            if (loopBody.Count > 0)
            {
                LoopLogicalConstruct loop = new LoopLogicalConstruct(interval.Entry as ILogicalConstruct, loopBody, typeOfLoop, loopCondition, typeSystem);

                CleanUpEdges(loop); /// Covers the case in IrregularbackedgeExitLoop
                UpdateDominatorTree(dominatorTree, loop);
                return(true);
            }
            else
            {
                /// Empty loops should not be created. Instead, backedges that form such loops will be marked as goto.
                foreach (DFSTEdge backedge in dfsTree.BackEdges)
                {
                    MarkAsGotoEdge(backedge.Start.Construct as ILogicalConstruct, backedge.End.Construct as ILogicalConstruct);
                }
            }
            return(false);
        }
Exemple #3
0
        public void Loop()
        {
            var cfg = new ControlFlowGraph <int>(IntArchitecture.Instance);

            var nodes = new ControlFlowNode <int> [4];

            for (int i = 0; i < nodes.Length; i++)
            {
                nodes[i] = new ControlFlowNode <int>(i, i);
                cfg.Nodes.Add(nodes[i]);
            }

            nodes[0].ConnectWith(nodes[2]);
            nodes[1].ConnectWith(nodes[2]);
            nodes[2].ConnectWith(nodes[1], ControlFlowEdgeType.Conditional);
            nodes[2].ConnectWith(nodes[3]);

            cfg.Entrypoint = nodes[0];

            var tree = DominatorTree.FromGraph(cfg);

            Assert.Equal(new HashSet <INode> {
                nodes[2]
            }, tree.GetDominanceFrontier(nodes[1]));
            Assert.Equal(new HashSet <INode> {
                nodes[2]
            }, tree.GetDominanceFrontier(nodes[2]));
        }
Exemple #4
0
    /*
     * Translate into SSA form
     */
    private static void ConvertIntoSSAForm(IRGraph graph)
    {
        DominatorTree dominatorTree = new DominatorTree(graph);

        InsertPhiFunctions(graph, dominatorTree);
        RenameVariables(graph, dominatorTree);
    }
Exemple #5
0
        public void Loop()
        {
            // Artificially construct a looping construct.
            var graph = TestGraphs.CreateLoop();
            var n1    = graph.GetNodeByOffset(0);
            var n2    = graph.GetNodeByOffset(1);
            var n3    = graph.GetNodeByOffset(2);
            var n4    = graph.GetNodeByOffset(4);

            var dominatorTree = DominatorTree <DummyInstruction> .FromGraph(graph);

            Assert.Equal(graph.Entrypoint, dominatorTree.Root.OriginalNode);

            Assert.True(dominatorTree.Dominates(n1, n1));
            Assert.True(dominatorTree.Dominates(n1, n2));
            Assert.True(dominatorTree.Dominates(n1, n3));
            Assert.True(dominatorTree.Dominates(n1, n4));

            Assert.False(dominatorTree.Dominates(n2, n1));
            Assert.True(dominatorTree.Dominates(n2, n2));
            Assert.False(dominatorTree.Dominates(n2, n3));
            Assert.False(dominatorTree.Dominates(n2, n4));

            Assert.False(dominatorTree.Dominates(n3, n1));
            Assert.True(dominatorTree.Dominates(n3, n2));
            Assert.True(dominatorTree.Dominates(n3, n3));
            Assert.True(dominatorTree.Dominates(n3, n4));

            Assert.False(dominatorTree.Dominates(n4, n1));
            Assert.False(dominatorTree.Dominates(n4, n2));
            Assert.False(dominatorTree.Dominates(n4, n3));
            Assert.True(dominatorTree.Dominates(n4, n4));
        }
 private bool TryMakeLoop(IntervalConstruct interval, DominatorTree dominatorTree)
 {
     V_0 = DFSTBuilder.BuildTree(interval);
     if (V_0.get_BackEdges().get_Count() == 0)
     {
         return(false);
     }
     V_2 = this.BuildLoop(V_0, out V_1);
     V_4 = this.DetermineLoopType(V_1, V_2, interval, dominatorTree, out V_3);
     if (V_1.get_Count() > 0)
     {
         V_5 = new LoopLogicalConstruct(interval.get_Entry() as ILogicalConstruct, V_1, V_4, V_3, this.typeSystem);
         this.CleanUpEdges(V_5);
         this.UpdateDominatorTree(dominatorTree, V_5);
         return(true);
     }
     V_6 = V_0.get_BackEdges().GetEnumerator();
     try
     {
         while (V_6.MoveNext())
         {
             V_7 = V_6.get_Current();
             this.MarkAsGotoEdge(V_7.get_Start().get_Construct() as ILogicalConstruct, V_7.get_End().get_Construct() as ILogicalConstruct);
         }
     }
     finally
     {
         ((IDisposable)V_6).Dispose();
     }
     return(false);
 }
Exemple #7
0
        public void SingleNode()
        {
            var graph = TestGraphs.CreateSingularGraph();

            var dominatorTree = DominatorTree <DummyInstruction> .FromGraph(graph);

            Assert.Equal(graph.Entrypoint, dominatorTree.Root.OriginalNode);
            Assert.True(dominatorTree.Dominates(graph.Entrypoint, graph.Entrypoint));
        }
Exemple #8
0
        /// <summary>
        /// Builds if constructs in the specified construct.
        /// </summary>
        /// <param name="construct"></param>
        private void BuildIfConstructs(ILogicalConstruct construct)
        {
            DominatorTree dominatorTree = GetDominatorTreeFromContext(construct);
            DFSTree       dfsTree       = DFSTBuilder.BuildTree(construct);

            foreach (ConditionLogicalConstruct condition in GetPostOrderedIfConditionCandidates(dfsTree))
            {
                TryBuildIfConstruct(condition, dominatorTree, dfsTree);
            }
        }
Exemple #9
0
    /*
     * Test find reachable blocks methods
     */
    private static void TestFindReachableBlocks(int index, SortedSet <int> expected)
    {
        IRGraph             cfg       = BuildSampleCFG();
        SortedSet <IRBlock> result    = DominatorTree.FindReachableBlocks(cfg, index);
        SortedSet <int>     intResult = ConvertToIndexSet(result);

        if (!intResult.SetEquals(expected))
        {
            throw new Exception("Reachable blocks for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected));
        }
    }
        private void ProcessSwitchConstructs(ILogicalConstruct parent, List <CFGBlockLogicalConstruct> switchBlocks)
        {
            DominatorTree dominatorTree = GetDominatorTreeFromContext(parent);
            DFSTree       dfsTree       = DFSTBuilder.BuildTree(parent);

            switchBlocks.Sort((x, y) => dfsTree.ConstructToNodeMap[y].ReversePostOrderIndex.CompareTo(dfsTree.ConstructToNodeMap[x].ReversePostOrderIndex));
            foreach (CFGBlockLogicalConstruct switchBlock in switchBlocks)
            {
                CreateSwitchConstruct(switchBlock, parent, this.logicalContext.CFG.SwitchBlocksInformation[switchBlock.TheBlock], dominatorTree);
            }
        }
Exemple #11
0
 private void UpdateDominatorTree(DominatorTree dominatorTree, IfLogicalConstruct theIfConstruct)
 {
     V_0       = new HashSet <ISingleEntrySubGraph>();
     dummyVar0 = V_0.Add(theIfConstruct.get_Condition());
     V_0.UnionWith(theIfConstruct.get_Then().get_Children());
     if (theIfConstruct.get_Else() != null)
     {
         V_0.UnionWith(theIfConstruct.get_Else().get_Children());
     }
     dominatorTree.MergeNodes(V_0, theIfConstruct.get_Condition(), theIfConstruct);
     return;
 }
Exemple #12
0
        public void Simple()
        {
            var cfg = new ControlFlowGraph <int>(IntArchitecture.Instance);

            var n = new ControlFlowNode <int>(0, 0);

            cfg.Nodes.Add(n);
            cfg.Entrypoint = n;

            var tree = DominatorTree.FromGraph(cfg);

            Assert.Empty(tree.GetDominanceFrontier(n));
        }
Exemple #13
0
        private void UpdateDominatorTree(DominatorTree dominatorTree, IfLogicalConstruct theIfConstruct)
        {
            HashSet <ISingleEntrySubGraph> ifNodes = new HashSet <ISingleEntrySubGraph>();

            ifNodes.Add(theIfConstruct.Condition);
            ifNodes.UnionWith(theIfConstruct.Then.Children);
            if (theIfConstruct.Else != null)
            {
                ifNodes.UnionWith(theIfConstruct.Else.Children);
            }

            dominatorTree.MergeNodes(ifNodes, theIfConstruct.Condition, theIfConstruct);
        }
Exemple #14
0
    /*
     * Test Building Full Dominator Tree
     */
    private static void TestCalculatingDominanceFrontier(int index, SortedSet <int> expected)
    {
        // Build Dominator Tree
        IRGraph       cfg           = BuildSampleCFG();
        DominatorTree dominatorTree = new DominatorTree(cfg);

        SortedSet <IRBlock> result    = dominatorTree.GetDominanceFrontier(cfg.GetBlock(index));
        SortedSet <int>     intResult = ConvertToIndexSet(result);

        if (!intResult.SetEquals(expected))
        {
            throw new Exception("Dominance frontier for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected));
        }
    }
Exemple #15
0
        private static void CFGReducibility_DominatorTree_PrettyPrinter_Demonstration()
        {
            string fpath = @"..\..\..\CodeSamples\reducibilityBadSample.txt";

            astRoot = AST(fpath);
            if (astRoot == null)
            {
                return;
            }
            var tacodeVisitor = new TACodeVisitor();

            astRoot.Visit(tacodeVisitor);
            var prettyPrinter = new PrettyPrintVisitor();

            astRoot.Visit(prettyPrinter);
            var cfg     = new ControlFlowGraph(tacodeVisitor.Code);
            var domTree = new DominatorTree(cfg);

            Console.WriteLine("###### CFG Reducibility(#59 by APC TEAM) based on DominatorTree(#56 by ДВП)");
            Console.WriteLine("###### and PrettyPrinter(#5 by APC TEAM) DEMONSTARTION:");
            Console.WriteLine("######       Sample 1:");
            Console.WriteLine(prettyPrinter.Text);
            Console.WriteLine("###### Dominator Tree Matrix:");
            Console.WriteLine(domTree.ToString());
            Console.WriteLine($"###### CFG is reducible: {cfg.IsReducible}");
            Console.WriteLine($"###### CFG depth is: {cfg.Depth}");


            fpath   = @"..\..\..\CodeSamples\reducibilityGoodSample.txt";
            astRoot = null;
            astRoot = AST(fpath);
            if (astRoot == null)
            {
                return;
            }
            tacodeVisitor = new TACodeVisitor();
            astRoot.Visit(tacodeVisitor);
            prettyPrinter = new PrettyPrintVisitor();
            astRoot.Visit(prettyPrinter);
            cfg     = new ControlFlowGraph(tacodeVisitor.Code);
            domTree = new DominatorTree(cfg);
            Console.WriteLine("###########################################");
            Console.WriteLine("######       Sample 2:");
            Console.WriteLine("###### Program text from PrettyPrinter:\n");
            Console.WriteLine(prettyPrinter.Text);
            Console.WriteLine("###### Dominator Tree Matrix:");
            Console.WriteLine(domTree.ToString());
            Console.WriteLine($"###### CFG is reducible: {cfg.IsReducible}");
        }
        /// <summary>
        /// Generates the loops in the graph with entry point <paramref name="construct"/>.
        /// </summary>
        /// <param name="construct">The entry point of the graph.</param>
        private void ProcessLogicalConstruct(ILogicalConstruct construct)
        {
            DominatorTree dominatorTree = GetDominatorTreeFromContext(construct);
            int           lastIterationIntervalsCount = int.MaxValue;

            RemoveBackEdgesFromSwitchConstructs(construct);

            while (lastIterationIntervalsCount > 1)
            {
                IntervalAnalyzer         ia        = new IntervalAnalyzer(construct, removedEdges);
                List <IntervalConstruct> intervals = ia.ReduceCfg();

                List <IntervalConstruct> reverseIntervals = new List <IntervalConstruct>(intervals);
                reverseIntervals.Reverse();

                /// Make only one loop at a time, since the newly made loop can be the header node of a bigger loop (if they are nested so).
                bool madeLoop = false;
                foreach (IntervalConstruct interval in reverseIntervals)
                {
                    if (TryMakeLoop(interval, dominatorTree))
                    {
                        madeLoop = true;
                        break;
                    }
                }

                if (madeLoop)
                {
                    lastIterationIntervalsCount = intervals.Count;
                    continue;
                }

                /// No loop was made in the last iteration and the interval count wasn't reduced. Then, an edge must be deleted from the graph,
                /// to ensure the reducibility.
                if (intervals.Count == lastIterationIntervalsCount)
                {
                    RemoveBlockingEdges(intervals);
                }

                /// This is sanity check. Intervals are supposed to decrease in count, or stay the same with each iteration
                if (intervals.Count > lastIterationIntervalsCount)
                {
                    throw new Exception("Intervails are more than in the last iteration.");
                }

                lastIterationIntervalsCount = intervals.Count;
            }
        }
        private void CreateSwitchConstruct(CFGBlockLogicalConstruct switchBlock, ILogicalConstruct parentConstruct,
                                           SwitchData switchData, DominatorTree dominatorTree)
        {
            List <KeyValuePair <CFGBlockLogicalConstruct, List <int> > >    cfgSuccessorToLabelsMap           = GetOrderedCFGSuccessorToLabelsMap(switchData);
            Dictionary <ILogicalConstruct, HashSet <ISingleEntrySubGraph> > validCaseEntryToDominatedNodesMap = GetValidCases(dominatorTree, switchBlock);

            List <CaseLogicalConstruct> orderedCaseConstructs = new List <CaseLogicalConstruct>();
            PairList <List <int>, CFGBlockLogicalConstruct> labelsToCFGSuccessorsList = new PairList <List <int>, CFGBlockLogicalConstruct>();

            foreach (KeyValuePair <CFGBlockLogicalConstruct, List <int> > cfgSuccessorToLabelsPair in cfgSuccessorToLabelsMap)
            {
                ILogicalConstruct successor;
                HashSet <ISingleEntrySubGraph> dominatedNodes;
                if (LogicalFlowUtilities.TryGetParentConstructWithGivenParent(cfgSuccessorToLabelsPair.Key, parentConstruct, out successor) &&
                    validCaseEntryToDominatedNodesMap.TryGetValue(successor, out dominatedNodes))
                {
                    CaseLogicalConstruct newCaseConstruct = new CaseLogicalConstruct(successor);
                    newCaseConstruct.CaseNumbers.AddRange(cfgSuccessorToLabelsPair.Value);
                    newCaseConstruct.Body.UnionWith(dominatedNodes.Cast <ILogicalConstruct>());
                    newCaseConstruct.AttachCaseConstructToGraph();
                    orderedCaseConstructs.Add(newCaseConstruct);
                }
                else
                {
                    labelsToCFGSuccessorsList.Add(cfgSuccessorToLabelsPair.Value, cfgSuccessorToLabelsPair.Key);
                }
            }

            CaseLogicalConstruct           defaultCase         = null;
            CFGBlockLogicalConstruct       defaultCFGSuccessor = GetCFGLogicalConstructFromBlock(switchData.DefaultCase);
            ILogicalConstruct              defaultSuccessor;
            HashSet <ISingleEntrySubGraph> defaultCaseNodes;

            if (LogicalFlowUtilities.TryGetParentConstructWithGivenParent(defaultCFGSuccessor, parentConstruct, out defaultSuccessor) &&
                validCaseEntryToDominatedNodesMap.TryGetValue(defaultSuccessor, out defaultCaseNodes))
            {
                defaultCase = new CaseLogicalConstruct(defaultSuccessor);
                if (HasSuccessors(defaultCaseNodes))
                {
                    defaultCase.Body.UnionWith(defaultCaseNodes.Cast <ILogicalConstruct>());
                }
                defaultCase.AttachCaseConstructToGraph();
            }

            SwitchLogicalConstruct theSwitch = SwitchLogicalConstruct.GroupInSwitchConstruct(switchBlock, orderedCaseConstructs, labelsToCFGSuccessorsList, defaultCase, defaultCFGSuccessor);

            UpdateDominatorTree(dominatorTree, theSwitch);
        }
Exemple #18
0
    private static void RenameVariables(IRGraph graph, DominatorTree dominatorTree)
    {
        // setup data structures
        Dictionary <Ident, int>          count = new Dictionary <Ident, int>();
        Dictionary <Ident, Stack <int> > stack = new Dictionary <Ident, Stack <int> >();

        foreach (Ident ident in graph.GetDefinedVars())
        {
            count[ident] = 0;
            stack[ident] = new Stack <int>();
            stack[ident].Push(0);
        }

        // recursively walk the dominator tree in-order starting with the root node
        Search(graph.GetGraphHead(), dominatorTree, count, stack);
    }
        private void UpdateDominatorTree(DominatorTree dominatorTree, LoopLogicalConstruct theLoopConstruct)
        {
            HashSet <ISingleEntrySubGraph> loopNodes = new HashSet <ISingleEntrySubGraph>();

            if (theLoopConstruct.LoopCondition != null)
            {
                loopNodes.Add(theLoopConstruct.LoopCondition);
            }
            if (theLoopConstruct.LoopBodyBlock != null)
            {
                loopNodes.UnionWith(theLoopConstruct.LoopBodyBlock.Children);
            }

            ISingleEntrySubGraph loopEntry = (theLoopConstruct.LoopType == LoopType.PreTestedLoop) ? theLoopConstruct.LoopCondition : theLoopConstruct.LoopBodyBlock.Entry;

            dominatorTree.MergeNodes(loopNodes, loopEntry, theLoopConstruct);
        }
        private void UpdateDominatorTree(DominatorTree dominatorTree, SwitchLogicalConstruct theSwitchConstruct)
        {
            HashSet <ISingleEntrySubGraph> switchNodes = new HashSet <ISingleEntrySubGraph>();

            switchNodes.Add(theSwitchConstruct.Entry);
            foreach (CaseLogicalConstruct @case in theSwitchConstruct.ConditionCases)
            {
                switchNodes.UnionWith(@case.Children);
            }

            if (theSwitchConstruct.DefaultCase != null)
            {
                switchNodes.UnionWith(theSwitchConstruct.DefaultCase.Children);
            }

            dominatorTree.MergeNodes(switchNodes, theSwitchConstruct.Entry, theSwitchConstruct);
        }
Exemple #21
0
    /*
     * Test the dominance set
     */
    private static void TestDomaintes(int index, SortedSet <int> expected)
    {
        IRGraph cfg = BuildSampleCFG();

        SortedSet <IRBlock> V      = cfg.GetSetOfAllBlocks();
        SortedSet <IRBlock> VSansR = new SortedSet <IRBlock>();

        VSansR.UnionWith(V);
        VSansR.Remove(cfg.GetGraphHead());

        SortedSet <IRBlock> result    = DominatorTree.CalculateDominatesSet(cfg, V, VSansR, cfg.GetBlock(index));
        SortedSet <int>     intResult = ConvertToIndexSet(result);

        if (!intResult.SetEquals(expected))
        {
            throw new Exception("Dominates blocks for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected));
        }
    }
 private void UpdateDominatorTree(DominatorTree dominatorTree, SwitchLogicalConstruct theSwitchConstruct)
 {
     V_0       = new HashSet <ISingleEntrySubGraph>();
     dummyVar0 = V_0.Add(theSwitchConstruct.get_Entry());
     V_1       = theSwitchConstruct.get_ConditionCases();
     V_2       = 0;
     while (V_2 < (int)V_1.Length)
     {
         V_0.UnionWith(V_1[V_2].get_Children());
         V_2 = V_2 + 1;
     }
     if (theSwitchConstruct.get_DefaultCase() != null)
     {
         V_0.UnionWith(theSwitchConstruct.get_DefaultCase().get_Children());
     }
     dominatorTree.MergeNodes(V_0, theSwitchConstruct.get_Entry(), theSwitchConstruct);
     return;
 }
Exemple #23
0
        public void ExceptionHandler()
        {
            var cfg = new ControlFlowGraph <int>(IntArchitecture.Instance);

            for (int i = 0; i < 7; i++)
            {
                cfg.Nodes.Add(new ControlFlowNode <int>(i));
            }

            cfg.Entrypoint = cfg.Nodes[0];

            cfg.Nodes[0].ConnectWith(cfg.Nodes[1]);
            cfg.Nodes[1].ConnectWith(cfg.Nodes[2], ControlFlowEdgeType.Conditional);
            cfg.Nodes[1].ConnectWith(cfg.Nodes[3], ControlFlowEdgeType.FallThrough);
            cfg.Nodes[2].ConnectWith(cfg.Nodes[4], ControlFlowEdgeType.Unconditional);
            cfg.Nodes[3].ConnectWith(cfg.Nodes[4], ControlFlowEdgeType.FallThrough);
            cfg.Nodes[4].ConnectWith(cfg.Nodes[6], ControlFlowEdgeType.Unconditional);
            cfg.Nodes[5].ConnectWith(cfg.Nodes[6], ControlFlowEdgeType.Unconditional);

            var ehRegion = new ExceptionHandlerRegion <int>();

            cfg.Regions.Add(ehRegion);

            ehRegion.ProtectedRegion.Entrypoint = cfg.Nodes[1];
            ehRegion.ProtectedRegion.Nodes.AddRange(new[]
            {
                cfg.Nodes[1],
                cfg.Nodes[2],
                cfg.Nodes[3],
                cfg.Nodes[4],
            });

            var handler = new HandlerRegion <int>();

            ehRegion.Handlers.Add(handler);
            handler.Contents.Nodes.Add(cfg.Nodes[5]);
            handler.Contents.Entrypoint = cfg.Nodes[5];

            var tree = DominatorTree <int> .FromGraph(cfg);

            Assert.True(tree.Dominates(cfg.Nodes[1], cfg.Nodes[6]));
            Assert.False(tree.Dominates(cfg.Nodes[4], cfg.Nodes[6]));
            Assert.False(tree.Dominates(cfg.Nodes[5], cfg.Nodes[6]));
        }
    /*
       * Test Building Full Dominator Tree
       */
    public static void TestBuildFullTree()
    {
        // Build Dominator Tree
        IRGraph cfg = BuildSampleCFG();
        DominatorTree dominatorTree = new DominatorTree(cfg);

        // Expected
        DominatorTreeNode expected = BuildExpectedDominatorTree();

        // Compare Result to Expected
        if(!dominatorTree.GetRoot().Equals(expected)) {
          Console.WriteLine("\n\n *** RESULT ***");
          printTree(dominatorTree.GetRoot());

          Console.WriteLine("\n\n *** EXPECTED ***");
          printTree(expected);

          throw new Exception("Dominator Tree built doesn't match expected dominator tree");
        }
    }
Exemple #25
0
    /*
     * Test Building Full Dominator Tree
     */
    public static void TestBuildFullTree()
    {
        // Build Dominator Tree
        IRGraph       cfg           = BuildSampleCFG();
        DominatorTree dominatorTree = new DominatorTree(cfg);

        // Expected
        DominatorTreeNode expected = BuildExpectedDominatorTree();

        // Compare Result to Expected
        if (!dominatorTree.GetRoot().Equals(expected))
        {
            Console.WriteLine("\n\n *** RESULT ***");
            printTree(dominatorTree.GetRoot());

            Console.WriteLine("\n\n *** EXPECTED ***");
            printTree(expected);

            throw new Exception("Dominator Tree built doesn't match expected dominator tree");
        }
    }
Exemple #26
0
        public void Path()
        {
            var cfg = new ControlFlowGraph <int>(IntArchitecture.Instance);

            var nodes = new ControlFlowNode <int> [3];

            for (int i = 0; i < nodes.Length; i++)
            {
                nodes[i] = new ControlFlowNode <int>(i, i);
                cfg.Nodes.Add(nodes[i]);
                if (i > 0)
                {
                    nodes[i - 1].ConnectWith(nodes[i]);
                }
            }

            cfg.Entrypoint = nodes[0];

            var tree = DominatorTree.FromGraph(cfg);

            Assert.All(nodes, n => Assert.Empty(tree.GetDominanceFrontier(n)));
        }
 private void UpdateDominatorTree(DominatorTree dominatorTree, LoopLogicalConstruct theLoopConstruct)
 {
     V_0 = new HashSet <ISingleEntrySubGraph>();
     if (theLoopConstruct.get_LoopCondition() != null)
     {
         dummyVar0 = V_0.Add(theLoopConstruct.get_LoopCondition());
     }
     if (theLoopConstruct.get_LoopBodyBlock() != null)
     {
         V_0.UnionWith(theLoopConstruct.get_LoopBodyBlock().get_Children());
     }
     if (theLoopConstruct.get_LoopType() == 1)
     {
         stackVariable10 = theLoopConstruct.get_LoopCondition();
     }
     else
     {
         stackVariable10 = theLoopConstruct.get_LoopBodyBlock().get_Entry();
     }
     dominatorTree.MergeNodes(V_0, stackVariable10, theLoopConstruct);
     return;
 }
Exemple #28
0
        private HashSet <ILogicalConstruct> GetBlockBody(DominatorTree dominatorTree, ILogicalConstruct conditionSuccessor, ConditionLogicalConstruct theCondition)
        {
            if (conditionSuccessor == dominatorTree.get_RootConstruct())
            {
                return(null);
            }
            V_0 = null;
            if (conditionSuccessor.get_AllPredecessors().get_Count() == 1)
            {
                V_0 = new HashSet <ILogicalConstruct>();
                V_1 = dominatorTree.GetDominatedNodes(conditionSuccessor).GetEnumerator();
                try
                {
                    while (V_1.MoveNext())
                    {
                        V_2 = (ILogicalConstruct)V_1.get_Current();
                        if (V_2 != theCondition)
                        {
                            dummyVar0 = V_0.Add(V_2);
                        }
                        else
                        {
                            V_3 = null;
                            goto Label1;
                        }
                    }
                    goto Label0;
                }
                finally
                {
                    ((IDisposable)V_1).Dispose();
                }
Label1:
                return(V_3);
            }
Label0:
            return(V_0);
        }
        public void DominatorTree()
        {
            var program   = @"
var a;
input(a);
1: if a == 0
    goto 2;
if a == 1
    goto 2;
a = 2;
2: a = 3;
";
            var graph     = GenCFG(program);
            var algorithm = new DominatorTree();

            _ = algorithm.Execute(graph);
            var iterationsFast = algorithm.Iterations;

            _ = algorithm.Execute(graph, false);
            var iterationsSlow = algorithm.Iterations;

            Assert.LessOrEqual(iterationsFast, iterationsSlow);
        }
Exemple #30
0
        private void TestInternal(ControlFlowGraph graph,
                                  DominatorDictionary expectedDoms,
                                  ParentsDictionary expectedParents,
                                  ChildrenDictionary expectedChildren)
        {
            var dt         = new DominatorTree();
            var dominators = dt.GetDominators(graph);
            var tree       = dt.Execute(graph);
            var blocks     = graph.GetCurrentBasicBlocks();

            Assert.AreEqual(blocks.Count, dominators.Count(), "Dominators count and blocks count are different");

            for (var i = 0; i < blocks.Count(); ++i)
            {
                CollectionAssert.AreEquivalent(expectedDoms[i], dominators[blocks[i]], $"Check dominators: error for block #{i}");
            }

            for (var i = 0; i < blocks.Count(); ++i)
            {
                Assert.AreEqual(expectedParents[i], tree.Parent(blocks[i]), $"Check parents: error for block #{i}");
                CollectionAssert.AreEquivalent(expectedChildren[i], tree.Children(blocks[i]), $"Check children: error for block #{i}");
            }
        }
Exemple #31
0
        /// <summary>
        /// Gets the dominated nodes of the condition successor, only if they can form a legal block for the if construct.
        /// </summary>
        /// <param name="dominatorTree"></param>
        /// <param name="conditionSuccessor"></param>
        /// <returns>On success - a set of the nodes fo the block. Otherwise it returns null.</returns>
        private HashSet <ILogicalConstruct> GetBlockBody(DominatorTree dominatorTree, ILogicalConstruct conditionSuccessor, ConditionLogicalConstruct theCondition)
        {
            if (conditionSuccessor == dominatorTree.RootConstruct) //Corner case - the successor cannot be the entry of the construct.
            {
                return(null);
            }

            HashSet <ILogicalConstruct> body = null;

            if (conditionSuccessor.AllPredecessors.Count == 1) //The condition successor must have only one predecessor - the condition.
            {
                body = new HashSet <ILogicalConstruct>();
                foreach (ILogicalConstruct node in dominatorTree.GetDominatedNodes(conditionSuccessor))
                {
                    if (node == theCondition)
                    {
                        return(null);
                    }
                    body.Add(node);
                }
            }

            return(body);
        }
    /*
       * Test Building Full Dominator Tree
       */
    private static void TestCalculatingDominanceFrontier(int index, SortedSet<int> expected)
    {
        // Build Dominator Tree
        IRGraph cfg = BuildSampleCFG();
        DominatorTree dominatorTree = new DominatorTree(cfg);

        SortedSet<IRBlock> result = dominatorTree.GetDominanceFrontier(cfg.GetBlock(index));
        SortedSet<int> intResult = ConvertToIndexSet(result);

        if(!intResult.SetEquals(expected)) {
          throw new Exception("Dominance frontier for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected));
        }
    }
Exemple #33
0
    private static void RenameVariables(IRGraph graph, DominatorTree dominatorTree)
    {
        // setup data structures
        Dictionary<Ident, int> count = new Dictionary<Ident, int>();
        Dictionary<Ident, Stack<int>> stack = new Dictionary<Ident, Stack<int>>();

        foreach (Ident ident in graph.GetDefinedVars())
        {
          count[ident] = 0;
          stack[ident] = new Stack<int>();
          stack[ident].Push(0);
        }

        // recursively walk the dominator tree in-order starting with the root node
        Search(graph.GetGraphHead(), dominatorTree, count, stack);
    }
Exemple #34
0
    private static void Search(IRBlock block, DominatorTree dominatorTree, Dictionary<Ident, int> count, Dictionary<Ident, Stack<int>> stack)
    {
        // Algorithm from Ron Cytron et al to rename variables into SSA form
        foreach (IRTuple irt in block.GetStatements())
        {
          Console.Write("Type: " + irt.GetType() + " ");
          irt.Print();
          Console.WriteLine();

          if (irt.getOp() != IrOp.PHI) {
        foreach (Ident v in irt.GetUsedVars()) {
          Console.WriteLine("Renaming variable: " + v);
          int i = stack[v].Peek();
          RenameTupleSourcesHelper(irt, v, i); // replace uses of v with vi in statement
        }
          }

          foreach (Ident a in irt.GetDefinedVars()) {
        count[a] = count[a] + 1;
        int i = count[a];
        stack[a].Push(i);
        irt.setDest(RenameVar(a, i)); // replace definitions of a with ai in statement
          }
        }

        // rename Phi function arguments in the successors
        List<IRBlock> successors = block.GetSuccessors();
        for (int i = 0; i < successors.Count; i++)
        {
          foreach (IRTuple stmt in block.GetStatements())
          {
        if (stmt.getOp() == IrOp.PHI)
        {
          IRTupleManyOp phi = (IRTupleManyOp)stmt;
          Ident v = phi.GetSources()[i];
          int numbering = stack[v].Peek();
          phi.SetSource(i, RenameVar(v, numbering));
        }
          }
        }

        // for each descendant do the Search(X) renaming process
        DominatorTreeNode node = dominatorTree.GetNode(block);
        foreach (DominatorTreeNode descendant in node.GetDescendants())
        {
          Search(descendant.GetBlock(), dominatorTree, count, stack);
        }

        // pop stack phase
        foreach (IRTuple irt in block.GetStatements())
        {
          foreach (Ident v in irt.GetDefinedVars())
        stack[v].Pop();
        }
    }
Exemple #35
0
 /*
    * Translate into SSA form
    */
 private static void ConvertIntoSSAForm(IRGraph graph)
 {
     DominatorTree dominatorTree = new DominatorTree(graph);
     InsertPhiFunctions(graph, dominatorTree);
     RenameVariables(graph, dominatorTree);
 }
Exemple #36
0
    private static void InsertPhiFunctions(IRGraph graph, DominatorTree dominatorTree)
    {
        foreach (IRBlock block in graph.GetSetOfAllBlocks())
        {
          Console.WriteLine();
          Console.WriteLine("***");
          Console.WriteLine("Block: " + block.GetIndex());
          block.PrintStatements();

          Console.Write("Predecessors: ");
          foreach (IRBlock pred in graph.GetPredecessors(block))
        Console.Write(pred.GetIndex() + ", ");
          Console.WriteLine();

          Console.Write("Live in : ");
          foreach (Ident ident in block.GetLiveIn())
        Console.Write(ident + ", ");
          Console.WriteLine();

          Console.Write("Defined vars: ");
          foreach (Ident ident in block.GetDefinedVars())
        Console.Write(ident + ", ");
          Console.WriteLine();
        }

        foreach (Ident v in graph.GetDefinedVars())
        {
          // A(v) = blocks containing an assignment to v
          HashSet<IRBlock> Av = new HashSet<IRBlock>();
          foreach (IRBlock block in graph.GetSetOfAllBlocks())
          {
        if (block.GetDefinedVars().Contains(v) && block.GetLiveIn().Contains(v))
          Av.Add(block);
          }

          // place Phi tuple for each v in the iterated dominance frontier of A(v)
          HashSet<IRBlock> needsPhiFunction = new HashSet<IRBlock>();
          foreach (IRBlock Avblock in Av)
          {
        // create set of blocks that need phi functions
        foreach (IRBlock block in dominatorTree.GetDominanceFrontier(Avblock))
        {
          needsPhiFunction.Add(block);
        }
          }

          // only want one phi function per block for each variable where appropiate
          foreach (IRBlock block in needsPhiFunction)
          {
        // Phi function should have as many arguments as it does predecessors
        List<Ident> sources = new List<Ident>();
        foreach (IRBlock b in graph.GetPredecessors(block))
          sources.Add(v);

        IRTupleManyOp phi = new IRTupleManyOp(IrOp.PHI, v, sources);

        block.InsertStatement(phi, 0);
        Console.WriteLine("** SSA: Inserting phi function: " + phi.toString() + " into block " + block.GetIndex());
          }
        }
    }