Exemplo n.º 1
0
 private void RemoveBackEdgesFromSwitchConstructs(ILogicalConstruct theConstruct)
 {
     V_0 = DFSTBuilder.BuildTree(theConstruct).get_BackEdges().GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             V_1 = V_0.get_Current();
             V_2 = V_1.get_Start().get_Construct() as ILogicalConstruct;
             if (V_2 as ConditionLogicalConstruct != null)
             {
                 continue;
             }
             V_3 = V_2 as CFGBlockLogicalConstruct;
             if (V_3 == null || V_3.get_TheBlock().get_Last().get_OpCode().get_Code() != 68)
             {
                 continue;
             }
             this.MarkAsGotoEdge(V_2, V_1.get_End().get_Construct() as ILogicalConstruct);
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     return;
 }
Exemplo n.º 2
0
        /// <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);
        }
Exemplo n.º 3
0
 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);
 }
Exemplo n.º 4
0
 private List <IntervalConstruct> SortIntervalList(List <IntervalConstruct> intervals)
 {
     V_0 = new IntervalConstruct(intervals.get_Item(0));
     V_2 = intervals.GetEnumerator();
     try
     {
         while (V_2.MoveNext())
         {
             V_3       = V_2.get_Current();
             dummyVar0 = V_0.get_Children().Add(V_3);
         }
     }
     finally
     {
         ((IDisposable)V_2).Dispose();
     }
     stackVariable15 = DFSTBuilder.BuildTree(V_0);
     V_1             = new List <IntervalConstruct>();
     V_4             = stackVariable15.get_ReversePostOrder().GetEnumerator();
     try
     {
         while (V_4.MoveNext())
         {
             V_5 = V_4.get_Current();
             V_1.Add(V_5.get_Construct() as IntervalConstruct);
         }
     }
     finally
     {
         ((IDisposable)V_4).Dispose();
     }
     return(V_1);
 }
Exemplo n.º 5
0
 private void CleanUpEdges(LoopLogicalConstruct loopConstruct)
 {
     V_0 = DFSTBuilder.BuildTree(loopConstruct.get_Parent()).get_ConstructToNodeMap().get_Item(loopConstruct);
     if (V_0.get_BackEdgeSuccessors().get_Count() == 0)
     {
         return;
     }
     V_1 = V_0.get_BackEdgeSuccessors().GetEnumerator();
     try
     {
         while (V_1.MoveNext())
         {
             V_2 = V_1.get_Current();
             if (V_2.get_Construct() as ILogicalConstruct as ConditionLogicalConstruct != null)
             {
                 continue;
             }
             this.MarkAsGotoEdge(loopConstruct, V_2.get_Construct() as ILogicalConstruct);
         }
     }
     finally
     {
         ((IDisposable)V_1).Dispose();
     }
     return;
 }
Exemplo n.º 6
0
 private Dictionary <ILogicalConstruct, HashSet <ISingleEntrySubGraph> > GetValidCases(DominatorTree dominatorTree, ILogicalConstruct switchCFGBlock)
 {
     V_0 = new SwitchBuilder.u003cu003ec__DisplayClass9_0();
     V_0.caseEntriesToDominatedNodesMap = new Dictionary <ILogicalConstruct, HashSet <ISingleEntrySubGraph> >();
     V_1       = new HashSet <ISingleEntrySubGraph>();
     dummyVar0 = V_1.Add(switchCFGBlock);
     V_4       = switchCFGBlock.get_SameParentSuccessors().GetEnumerator();
     try
     {
         while (V_4.MoveNext())
         {
             V_5 = (ILogicalConstruct)V_4.get_Current();
             if (V_5 == switchCFGBlock || dominatorTree.GetImmediateDominator(V_5) != switchCFGBlock)
             {
                 continue;
             }
             V_6 = dominatorTree.GetDominatedNodes(V_5);
             V_0.caseEntriesToDominatedNodesMap.Add(V_5, V_6);
             V_1.UnionWith(V_6);
         }
     }
     finally
     {
         ((IDisposable)V_4).Dispose();
     }
     stackVariable34 = DFSTBuilder.BuildTree(switchCFGBlock.get_Parent(), switchCFGBlock).get_ReversePostOrder();
     stackVariable35 = SwitchBuilder.u003cu003ec.u003cu003e9__9_0;
     if (stackVariable35 == null)
     {
         dummyVar1       = stackVariable35;
         stackVariable35 = new Func <DFSTNode, ILogicalConstruct>(SwitchBuilder.u003cu003ec.u003cu003e9.u003cGetValidCasesu003eb__9_0);
         SwitchBuilder.u003cu003ec.u003cu003e9__9_0 = stackVariable35;
     }
     V_2 = new List <ILogicalConstruct>(stackVariable34.Select <DFSTNode, ILogicalConstruct>(stackVariable35).Where <ILogicalConstruct>(new Func <ILogicalConstruct, bool>(V_0.u003cGetValidCasesu003eb__1)));
     do
     {
         V_3 = false;
         V_7 = V_2.GetEnumerator();
         try
         {
             while (V_7.MoveNext())
             {
                 V_8 = V_7.get_Current();
                 if (!V_0.caseEntriesToDominatedNodesMap.TryGetValue(V_8, out V_9) || this.IsCaseValid(V_8, V_1))
                 {
                     continue;
                 }
                 V_1.ExceptWith(V_9);
                 dummyVar2 = V_0.caseEntriesToDominatedNodesMap.Remove(V_8);
                 V_3       = true;
             }
         }
         finally
         {
             ((IDisposable)V_7).Dispose();
         }
     }while (V_3);
     return(V_0.caseEntriesToDominatedNodesMap);
 }
Exemplo n.º 7
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);
            }
        }
        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);
            }
        }
        /// <summary>
        /// Creates a subgraph of the specified <paramref name="graph"/>.
        /// </summary>
        /// <remarks>
        /// The subgraph has the same vertices as the original. The difference is that the subgraph does not contain the back edges
        /// found by the dfs traversal of the <paramref name="graph"/>.
        /// </remarks>
        /// <param name="graph"></param>
        private void GetVerticesAndAdjacencyMatrix(ILogicalConstruct graph)
        {
            DFSTree dfsTree = DFSTBuilder.BuildTree(graph);

            orderedVertexArray = new ILogicalConstruct[dfsTree.ReversePostOrder.Count];
            for (int i = 0; i < orderedVertexArray.Length; i++)
            {
                orderedVertexArray[i] = dfsTree.ReversePostOrder[i].Construct as ILogicalConstruct;
            }

            BuildAdjacencyMatrix(dfsTree);
        }
        /// <summary>
        /// Gets the CFGBlockLC children of theBlock sorted in reverse post order.
        /// </summary>
        private void GetOrderedCFGNodes()
        {
            DFSTree dfsTree = DFSTBuilder.BuildTree(theBlock);

            foreach (DFSTNode node in dfsTree.ReversePostOrder)
            {
                CFGBlockLogicalConstruct cfgConstruct = node.Construct as CFGBlockLogicalConstruct;
                if (cfgConstruct != null)
                {
                    orderedCFGNodes.Add(cfgConstruct);
                }
            }
        }
 private void GetVerticesAndAdjacencyMatrix(ILogicalConstruct graph)
 {
     V_0 = DFSTBuilder.BuildTree(graph);
     this.orderedVertexArray = new ILogicalConstruct[V_0.get_ReversePostOrder().get_Count()];
     V_1 = 0;
     while (V_1 < (int)this.orderedVertexArray.Length)
     {
         this.orderedVertexArray[V_1] = V_0.get_ReversePostOrder().get_Item(V_1).get_Construct() as ILogicalConstruct;
         V_1 = V_1 + 1;
     }
     this.BuildAdjacencyMatrix(V_0);
     return;
 }
Exemplo n.º 12
0
        private void RemoveBlockingEdges(List <IntervalConstruct> intervals)
        {
            V_0 = new IntervalConstruct(intervals.get_Item(0));
            V_5 = 1;
            while (V_5 < intervals.get_Count())
            {
                dummyVar0 = V_0.get_Children().Add(intervals.get_Item(V_5));
                V_5       = V_5 + 1;
            }
            V_1 = DFSTBuilder.BuildTree(V_0);
            V_2 = V_1.get_BackEdges().FirstOrDefault <DFSTEdge>();
            if (V_2 == null)
            {
                V_2 = V_1.get_CrossEdges().FirstOrDefault <DFSTEdge>();
            }
            V_3 = V_2.get_Start().get_Construct() as IntervalConstruct;
            V_4 = V_2.get_End().get_Construct() as IntervalConstruct;
            V_6 = V_4.get_Entry().get_SameParentPredecessors().GetEnumerator();
            try
            {
                while (V_6.MoveNext())
                {
                    V_7 = (ILogicalConstruct)V_6.get_Current();
                    if (!V_3.get_Children().Contains(V_7))
                    {
                        continue;
                    }
                    V_8 = V_7;
                    V_9 = V_4.get_Entry() as ILogicalConstruct;
                    if (this.removedEdges.TryGetValue(V_8, out V_10) && V_10.Contains(V_9))
                    {
                        continue;
                    }
                    this.MarkAsGotoEdge(V_8, V_9);
                    goto Label0;
                }
            }
            finally
            {
                ((IDisposable)V_6).Dispose();
            }
Label0:
            return;
        }
        protected override void FindImmediateDominators()
        {
            List <DFSTNode> reversePostOrderMap = DFSTBuilder.BuildTree(originalGraph).ReversePostOrder;

            List <DFSTNode>[] predecessorsCache = InitializePredecessors(reversePostOrderMap);
            int count = reversePostOrderMap.Count;

            InitializeDominators(count);

            bool changed;

            do
            {
                changed = false;
                for (int i = 1; i < count; i++)
                {
                    List <DFSTNode> predecessors = predecessorsCache[i];
                    int             newImmDom    = GetPredecessor(predecessors, node => node.ReversePostOrderIndex != i && dominators[node.ReversePostOrderIndex] != -1);
                    foreach (DFSTNode predecessor in predecessors)
                    {
                        int index = predecessor.ReversePostOrderIndex;
                        if (index != i && dominators[index] != -1)
                        {
                            newImmDom = Intersect(index, newImmDom);
                        }
                    }

                    if (dominators[i] != newImmDom)
                    {
                        dominators[i] = newImmDom;
                        changed       = true;
                    }
                }
            }while (changed);

            for (int i = 1; i < count; i++)
            {
                DTNode node   = constructToNodeMap[reversePostOrderMap[i].Construct];
                DTNode immDom = constructToNodeMap[reversePostOrderMap[dominators[i]].Construct];
                node.Predecessor = immDom;
                immDom.TreeEdgeSuccessors.Add(node);
            }
        }
        /// <summary>
        /// Sorts the intervals in Reverse post order.
        /// </summary>
        /// <param name="intervals">The intervals to be sorted.</param>
        /// <returns>Returns sorted list of intervals.</returns>
        private List <IntervalConstruct> SortIntervalList(List <IntervalConstruct> intervals)
        {
            IntervalConstruct intervalGraph = new IntervalConstruct(intervals[0]);

            foreach (ISingleEntrySubGraph interval in intervals)
            {
                intervalGraph.Children.Add(interval);
            }
            DFSTree dfsTree = DFSTBuilder.BuildTree(intervalGraph);

            List <IntervalConstruct> sortedList = new List <IntervalConstruct>();

            foreach (DFSTNode node in dfsTree.ReversePostOrder)
            {
                sortedList.Add(node.Construct as IntervalConstruct);
            }

            return(sortedList);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Removes back edges from switch blocks. Switch cases can not form a loop. If the control flow forms a loop, it should be represented by goto-label contructs.
        /// </summary>
        /// <param name="theConstruct">The construct, that might contain switches.</param>
        private void RemoveBackEdgesFromSwitchConstructs(ILogicalConstruct theConstruct)
        {
            DFSTree dfsTree = DFSTBuilder.BuildTree(theConstruct);

            foreach (DFSTEdge edge in dfsTree.BackEdges)
            {
                ILogicalConstruct startConstruct = edge.Start.Construct as ILogicalConstruct;
                if (startConstruct is ConditionLogicalConstruct)
                {
                    continue;
                }

                CFGBlockLogicalConstruct startCfgConstruct = startConstruct as CFGBlockLogicalConstruct;
                if ((startCfgConstruct != null && startCfgConstruct.TheBlock.Last.OpCode.Code == Mono.Cecil.Cil.Code.Switch))
                {
                    MarkAsGotoEdge(startConstruct, edge.End.Construct as ILogicalConstruct);
                }
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Removes and edge, that is preventing the reducibillity of the graph.
        /// </summary>
        /// <param name="intervals">The graph, that can't be reduced.</param>
        private void RemoveBlockingEdges(List <IntervalConstruct> intervals)
        {
            //Creating this interval, so that it holds the interval tree
            //This way we can use the DFSTree.
            IntervalConstruct allIntervals = new IntervalConstruct(intervals[0]);

            for (int i = 1; i < intervals.Count; i++)
            {
                allIntervals.Children.Add(intervals[i]);
            }

            DFSTree dfsTree = DFSTBuilder.BuildTree(allIntervals);

            /// Blocking edge can be either cross edge or back edge.
            /// If a backedge is detected, that means it wasn't converted in loop, so it must be marked as goto.
            DFSTEdge edgeToDelete = dfsTree.BackEdges.FirstOrDefault();

            if (edgeToDelete == null)
            {
                edgeToDelete = dfsTree.CrossEdges.FirstOrDefault();
            }

            //both should not be null, since the DFS was ran onto intervals tree
            IntervalConstruct edgeStart = edgeToDelete.Start.Construct as IntervalConstruct;
            IntervalConstruct edgeEnd   = edgeToDelete.End.Construct as IntervalConstruct;

            //Find all logical constructs that make the intervals have this edge between them.
            foreach (ILogicalConstruct edgeEndPredecessor in edgeEnd.Entry.SameParentPredecessors)
            {
                if (edgeStart.Children.Contains(edgeEndPredecessor))
                {
                    ILogicalConstruct constructEdgeStart = edgeEndPredecessor;
                    ILogicalConstruct constructEdgeEnd   = edgeEnd.Entry as ILogicalConstruct;

                    HashSet <ILogicalConstruct> removedEdgeInfo;
                    if (!removedEdges.TryGetValue(constructEdgeStart, out removedEdgeInfo) || !removedEdgeInfo.Contains(constructEdgeEnd))
                    {
                        MarkAsGotoEdge(constructEdgeStart, constructEdgeEnd);
                        return;
                    }
                }
            }
        }
Exemplo n.º 17
0
        /// <summary>
        /// Removes backedges exiting from <paramref name="loopConstruct"/>.
        /// </summary>
        /// <param name="loopConstruct">The loop construct.</param>
        private void CleanUpEdges(LoopLogicalConstruct loopConstruct)
        {
            DFSTree  dfsTree  = DFSTBuilder.BuildTree(loopConstruct.Parent);
            DFSTNode loopNode = dfsTree.ConstructToNodeMap[loopConstruct];

            if (loopNode.BackEdgeSuccessors.Count == 0)
            {
                return;
            }

            foreach (DFSTNode backedgeSuccessor in loopNode.BackEdgeSuccessors)
            {
                ILogicalConstruct edgeEndConstruct = backedgeSuccessor.Construct as ILogicalConstruct;
                if (!(edgeEndConstruct is ConditionLogicalConstruct)) /// if the target is ConditionLogicalConstruct, it can probably be a header of outer loop
                {
                    MarkAsGotoEdge(loopConstruct, backedgeSuccessor.Construct as ILogicalConstruct);
                }
            }
        }
Exemplo n.º 18
0
 private void ProcessSwitchConstructs(ILogicalConstruct parent, List <CFGBlockLogicalConstruct> switchBlocks)
 {
     V_0         = new SwitchBuilder.u003cu003ec__DisplayClass5_0();
     V_1         = this.GetDominatorTreeFromContext(parent);
     V_0.dfsTree = DFSTBuilder.BuildTree(parent);
     switchBlocks.Sort(new Comparison <CFGBlockLogicalConstruct>(V_0.u003cProcessSwitchConstructsu003eb__0));
     V_2 = switchBlocks.GetEnumerator();
     try
     {
         while (V_2.MoveNext())
         {
             V_3 = V_2.get_Current();
             this.CreateSwitchConstruct(V_3, parent, this.logicalContext.get_CFG().get_SwitchBlocksInformation().get_Item(V_3.get_TheBlock()), V_1);
         }
     }
     finally
     {
         ((IDisposable)V_2).Dispose();
     }
     return;
 }
 private void GetOrderedCFGNodes()
 {
     V_0 = DFSTBuilder.BuildTree(this.theBlock).get_ReversePostOrder().GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             V_1 = V_0.get_Current().get_Construct() as CFGBlockLogicalConstruct;
             if (V_1 == null)
             {
                 continue;
             }
             this.orderedCFGNodes.Add(V_1);
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     return;
 }
Exemplo n.º 20
0
        private Dictionary <ILogicalConstruct, HashSet <ISingleEntrySubGraph> > GetValidCases(DominatorTree dominatorTree, ILogicalConstruct switchCFGBlock)
        {
            Dictionary <ILogicalConstruct, HashSet <ISingleEntrySubGraph> > caseEntriesToDominatedNodesMap = new Dictionary <ILogicalConstruct, HashSet <ISingleEntrySubGraph> >();
            HashSet <ISingleEntrySubGraph> legalPredecessors = new HashSet <ISingleEntrySubGraph>();

            legalPredecessors.Add(switchCFGBlock);

            foreach (ILogicalConstruct successor in switchCFGBlock.SameParentSuccessors)
            {
                if (successor != switchCFGBlock && dominatorTree.GetImmediateDominator(successor) == switchCFGBlock)
                {
                    HashSet <ISingleEntrySubGraph> dominatedNodes = dominatorTree.GetDominatedNodes(successor);
                    caseEntriesToDominatedNodesMap.Add(successor, dominatedNodes);
                    legalPredecessors.UnionWith(dominatedNodes);
                }
            }

            DFSTree dfsTree = DFSTBuilder.BuildTree(switchCFGBlock.Parent, switchCFGBlock);
            List <ILogicalConstruct> orderedCaseEntries =
                new List <ILogicalConstruct>(dfsTree.ReversePostOrder.Select(node => node.Construct as ILogicalConstruct).Where(construct => caseEntriesToDominatedNodesMap.ContainsKey(construct)));

            bool changed;

            do
            {
                changed = false;
                foreach (ILogicalConstruct caseEntry in orderedCaseEntries)
                {
                    HashSet <ISingleEntrySubGraph> dominatedNodes;
                    if (caseEntriesToDominatedNodesMap.TryGetValue(caseEntry, out dominatedNodes) && !IsCaseValid(caseEntry, legalPredecessors))
                    {
                        legalPredecessors.ExceptWith(dominatedNodes);
                        caseEntriesToDominatedNodesMap.Remove(caseEntry);
                        changed = true;
                    }
                }
            } while (changed);

            return(caseEntriesToDominatedNodesMap);
        }
Exemplo n.º 21
0
 private void BuildIfConstructs(ILogicalConstruct construct)
 {
     V_0 = this.GetDominatorTreeFromContext(construct);
     V_1 = DFSTBuilder.BuildTree(construct);
     V_2 = this.GetPostOrderedIfConditionCandidates(V_1).GetEnumerator();
     try
     {
         while (V_2.MoveNext())
         {
             V_3       = V_2.get_Current();
             dummyVar0 = this.TryBuildIfConstruct(V_3, V_0, V_1);
         }
     }
     finally
     {
         if (V_2 != null)
         {
             V_2.Dispose();
         }
     }
     return;
 }
Exemplo n.º 22
0
        private LoopType DetermineLoopType(HashSet <ILogicalConstruct> loopBody, HashSet <ILogicalConstruct> latchingNodes, IntervalConstruct interval, DominatorTree dominatorTree, out ConditionLogicalConstruct loopCondition)
        {
            V_0       = interval.get_Entry() as ILogicalConstruct;
            V_1       = new HashSet <ILogicalConstruct>(latchingNodes);
            dummyVar0 = V_1.Add(V_0);
            V_2       = DFSTBuilder.BuildTree(V_0.get_Parent() as ILogicalConstruct);
            V_3       = new HashSet <ILogicalConstruct>();
            V_4       = loopBody.GetEnumerator();
            try
            {
                while (V_4.MoveNext())
                {
                    V_5 = V_4.get_Current();
                    V_6 = dominatorTree.GetDominanceFrontier(V_5).GetEnumerator();
                    try
                    {
                        while (V_6.MoveNext())
                        {
                            V_7 = (ILogicalConstruct)V_6.get_Current();
                            if (!interval.get_Children().Contains(V_7) || loopBody.Contains(V_7))
                            {
                                continue;
                            }
                            dummyVar1 = V_3.Add(V_7);
                        }
                    }
                    finally
                    {
                        ((IDisposable)V_6).Dispose();
                    }
                }
            }
            finally
            {
                ((IDisposable)V_4).Dispose();
            }
            if (V_3.get_Count() == 0)
            {
                V_8 = V_2.get_ReversePostOrder().GetEnumerator();
                try
                {
                    while (V_8.MoveNext())
                    {
                        V_9 = V_8.get_Current().get_Construct() as ILogicalConstruct;
                        if (loopBody.Contains(V_9))
                        {
                            continue;
                        }
                        loopCondition = this.GetLoopConditionWithMaxIndex(V_2, loopBody, V_1, V_9);
                        if (loopCondition == null)
                        {
                            continue;
                        }
                        this.ExpandLoopBody(interval, loopBody, V_9);
                        if (loopCondition != V_0)
                        {
                            V_10 = 2;
                            goto Label1;
                        }
                        else
                        {
                            V_10 = 1;
                            goto Label1;
                        }
                    }
                    goto Label0;
                }
                finally
                {
                    ((IDisposable)V_8).Dispose();
                }
Label1:
                return(V_10);
            }
            V_11 = V_2.get_ReversePostOrder().get_Count();
            V_4  = V_3.GetEnumerator();
            try
            {
                while (V_4.MoveNext())
                {
                    V_13 = V_4.get_Current();
                    V_14 = V_2.get_ConstructToNodeMap().get_Item(V_13).get_ReversePostOrderIndex();
                    if (V_14 >= V_11)
                    {
                        continue;
                    }
                    V_11 = V_14;
                }
            }
            finally
            {
                ((IDisposable)V_4).Dispose();
            }
            V_12          = V_2.get_ReversePostOrder().get_Item(V_11).get_Construct() as ILogicalConstruct;
            loopCondition = this.GetLoopConditionWithMaxIndex(V_2, loopBody, V_1, V_12);
            this.ExpandLoopBody(interval, loopBody, V_12);
            if (loopCondition == null)
            {
                return(0);
            }
            if (loopCondition == V_0)
            {
                return(1);
            }
            return(2);

Label0:
            if (!this.CanBeLoopCondition(V_0, loopBody))
            {
                loopCondition = null;
                return(0);
            }
            loopCondition = V_0 as ConditionLogicalConstruct;
            return(1);
        }
Exemplo n.º 23
0
        /// <summary>
        /// Determines the type of the loop and the condition of the loop. Adds additional nodes into the loop body.
        /// </summary>
        /// <param name="loopBody"></param>
        /// <param name="header"></param>
        /// <param name="latchingNodes"></param>
        /// <param name="interval"></param>
        /// <param name="loopCondition"></param>
        /// <returns></returns>
        private LoopType DetermineLoopType(HashSet <ILogicalConstruct> loopBody, HashSet <ILogicalConstruct> latchingNodes,
                                           IntervalConstruct interval, DominatorTree dominatorTree, out ConditionLogicalConstruct loopCondition)
        {
            ILogicalConstruct           header     = interval.Entry as ILogicalConstruct;
            HashSet <ILogicalConstruct> legalExits = new HashSet <ILogicalConstruct>(latchingNodes);

            legalExits.Add(header);

            ILogicalConstruct parentConstruct = header.Parent as ILogicalConstruct;
            DFSTree           dfsTree         = DFSTBuilder.BuildTree(parentConstruct);

            //B - nodes in the loop body (= loopBody)
            //I - nodes in the interval (= interval.Children)
            //U - union of all of the dominance frontiers of the nodes in B
            //exitDominanceFrontier = (U n I) \ B
            //If a node is in the exitDominanceFrontier, then it is dominated by the header and is a successor (not necessarily direct) of more than one
            //node in the loop body.
            HashSet <ILogicalConstruct> exitDominanceFrontier = new HashSet <ILogicalConstruct>();

            foreach (ILogicalConstruct loopNode in loopBody)
            {
                foreach (ILogicalConstruct frontierNode in dominatorTree.GetDominanceFrontier(loopNode))
                {
                    if (interval.Children.Contains(frontierNode) && !loopBody.Contains(frontierNode))
                    {
                        exitDominanceFrontier.Add(frontierNode);
                    }
                }
            }

            //This is leftover heuristic, that was used for determining a suitable successor that is going to be follow node of the loop.
            //Changing it now will break a good number of the tests. Since the produced output is acceptable, until a better heuristic is found
            //there is no need to change it.
            if (exitDominanceFrontier.Count == 0)
            {
                //If the exit dominance frontier is empty then we look for the node, with minimum post order index, that is a successor of a condition loop exit.
                //The desired exit should be a condition in order to reduce the number of infinite loops (heuristic).
                foreach (DFSTNode dfsNode in dfsTree.ReversePostOrder)
                {
                    ILogicalConstruct construct = dfsNode.Construct as ILogicalConstruct;
                    if (loopBody.Contains(construct))
                    {
                        continue;
                    }

                    loopCondition = GetLoopConditionWithMaxIndex(dfsTree, loopBody, legalExits, construct);
                    //By taking the successor with the minimum post order index and the loop exit with the maximum post order index, we ensure that
                    //the produced construct will always be the same, since the post order in our case is a total order.
                    //There are other various ways of finding the exit-successor pair that can bring consistent output, but none of them is found to yield
                    //better results than the rest.
                    if (loopCondition != null)
                    {
                        //We expand the loop body only when we've found a condition successor of the loop.
                        //This is done in order to avoid adding all of the dominated nodes of an infinite loop to the body. (Better readability of the final code.)
                        //E.g.: An infinite loop on the top level of the logical tree (i.e. child of the method block construct). If it dominates all of its
                        //succeeding nodes then they will be in its interval, which means that they will be added to the loop. As a result there will
                        //be an infinite loop at the end of the method, that encloses a cood part of the code, for no apparent reason.
                        ExpandLoopBody(interval, loopBody, construct);

                        if (loopCondition == header)
                        {
                            return(LoopType.PreTestedLoop);
                        }
                        else
                        {
                            return(LoopType.PostTestedLoop);
                        }
                    }
                }

                if (CanBeLoopCondition(header, loopBody))
                {
                    loopCondition = header as ConditionLogicalConstruct;
                    return(LoopType.PreTestedLoop);
                }
                else
                {
                    loopCondition = null;
                    return(LoopType.InfiniteLoop);
                }
            }
            else
            {
                //If there are nodes in the exitDominanceFrontier, then we choose the one with the minimum postorder index for successor of the loop.
                //Then we try to find a condition exit of the loop, with maximum post order index, that is predecessor of the successor node.
                int minOrderIndexOfSuccessor = dfsTree.ReversePostOrder.Count;
                foreach (ILogicalConstruct successor in exitDominanceFrontier)
                {
                    int currentOrderIndex = dfsTree.ConstructToNodeMap[successor].ReversePostOrderIndex;

                    if (currentOrderIndex < minOrderIndexOfSuccessor)
                    {
                        minOrderIndexOfSuccessor = currentOrderIndex;
                    }
                }

                ILogicalConstruct loopSuccessor = dfsTree.ReversePostOrder[minOrderIndexOfSuccessor].Construct as ILogicalConstruct;

                loopCondition = GetLoopConditionWithMaxIndex(dfsTree, loopBody, legalExits, loopSuccessor);

                ExpandLoopBody(interval, loopBody, loopSuccessor);

                if (loopCondition != null)
                {
                    if (loopCondition == header)
                    {
                        return(LoopType.PreTestedLoop);
                    }
                    else
                    {
                        return(LoopType.PostTestedLoop);
                    }
                }
                else
                {
                    return(LoopType.InfiniteLoop);
                }
            }
        }