/// <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);
        }
 private ConditionLogicalConstruct GetLoopConditionWithMaxIndex(DFSTree dfsTree, HashSet <ILogicalConstruct> loopBody, HashSet <ILogicalConstruct> loopExits, ILogicalConstruct loopSuccessor)
 {
     V_0 = -1;
     V_1 = loopExits.GetEnumerator();
     try
     {
         while (V_1.MoveNext())
         {
             V_2 = V_1.get_Current();
             V_3 = dfsTree.get_ConstructToNodeMap().get_Item(V_2).get_ReversePostOrderIndex();
             if (!V_2.get_SameParentSuccessors().Contains(loopSuccessor) || V_3 <= V_0 || !this.CanBeLoopCondition(V_2, loopBody))
             {
                 continue;
             }
             V_0 = V_3;
         }
     }
     finally
     {
         ((IDisposable)V_1).Dispose();
     }
     if (V_0 <= -1)
     {
         return(null);
     }
     return(dfsTree.get_ReversePostOrder().get_Item(V_0).get_Construct() as ConditionLogicalConstruct);
 }
        /// <summary>
        /// Gets a collection of all possible latching nodes for a loop. Builds the body of the loop in the process.
        /// </summary>
        /// <param name="tree">The tree in which the loop was found.</param>
        /// <param name="loopBody">On exit contains the resulted loop body.</param>
        /// <returns>Returns collection of all possible latching nodes.</returns>
        private HashSet <ILogicalConstruct> BuildLoop(DFSTree tree, out HashSet <ILogicalConstruct> loopBody)
        {
            loopBody = new HashSet <ILogicalConstruct>();
            HashSet <ILogicalConstruct> possibleLatchingNodes = new HashSet <ILogicalConstruct>();

            /// Loops are defined by their backedges.
            foreach (DFSTEdge edge in tree.BackEdges)
            {
                ILogicalConstruct header       = edge.End.Construct as ILogicalConstruct;
                ILogicalConstruct latchingNode = edge.Start.Construct as ILogicalConstruct;

                /// The edge between the header and the latching node was marked as goto-edge on an earlier step.
                if (removedEdges.ContainsKey(latchingNode) && removedEdges[latchingNode].Contains(header))
                {
                    continue;
                }

                ICollection <DFSTNode>          shortLoopBody          = tree.GetPath(edge.End, edge.Start);
                ICollection <DFSTNode>          fullLoopBody           = ExpandLoopBodyWithCrossEdges(shortLoopBody);
                ICollection <ILogicalConstruct> fullLoopBodyConstructs = GetConstructsCollection(fullLoopBody);

                if (CanBeLoop(header, latchingNode, fullLoopBody))
                {
                    possibleLatchingNodes.Add(latchingNode);
                    foreach (ILogicalConstruct construct in fullLoopBodyConstructs)
                    {
                        loopBody.Add(construct);
                    }
                }
            }

            return(possibleLatchingNodes);
        }
 private DFSTEdge[] GetForwardFlowEdges(DFSTree dfsTree)
 {
     V_0 = new DFSTEdge[dfsTree.get_TreeEdges().get_Count() + dfsTree.get_ForwardEdges().get_Count() + dfsTree.get_CrossEdges().get_Count()];
     V_1 = 0;
     this.FillEdgesArray(V_0, dfsTree.get_TreeEdges(), ref V_1);
     this.FillEdgesArray(V_0, dfsTree.get_ForwardEdges(), ref V_1);
     this.FillEdgesArray(V_0, dfsTree.get_CrossEdges(), ref V_1);
     return(V_0);
 }
Beispiel #5
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>
        /// Gets an array containing the tree, forward and cross edges of the given DFS traversal tree.
        /// </summary>
        /// <param name="dfsTree">The DFS traversal tree.</param>
        /// <returns></returns>
        private DFSTEdge[] GetForwardFlowEdges(DFSTree dfsTree)
        {
            DFSTEdge[] regularEdges = new DFSTEdge[dfsTree.TreeEdges.Count + dfsTree.ForwardEdges.Count + dfsTree.CrossEdges.Count];

            int index = 0;

            FillEdgesArray(regularEdges, dfsTree.TreeEdges, ref index);
            FillEdgesArray(regularEdges, dfsTree.ForwardEdges, ref index);
            FillEdgesArray(regularEdges, dfsTree.CrossEdges, ref index);
            return(regularEdges);
        }
        /// <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 HashSet <ILogicalConstruct> BuildLoop(DFSTree tree, out HashSet <ILogicalConstruct> loopBody)
 {
     loopBody = new HashSet <ILogicalConstruct>();
     V_0      = new HashSet <ILogicalConstruct>();
     V_1      = tree.get_BackEdges().GetEnumerator();
     try
     {
         while (V_1.MoveNext())
         {
             V_2 = V_1.get_Current();
             V_3 = V_2.get_End().get_Construct() as ILogicalConstruct;
             V_4 = V_2.get_Start().get_Construct() as ILogicalConstruct;
             if (this.removedEdges.ContainsKey(V_4) && this.removedEdges.get_Item(V_4).Contains(V_3))
             {
                 continue;
             }
             V_5 = tree.GetPath(V_2.get_End(), V_2.get_Start());
             V_6 = this.ExpandLoopBodyWithCrossEdges(V_5);
             V_7 = this.GetConstructsCollection(V_6);
             if (!this.CanBeLoop(V_3, V_4, V_6))
             {
                 continue;
             }
             dummyVar0 = V_0.Add(V_4);
             V_8       = V_7.GetEnumerator();
             try
             {
                 while (V_8.MoveNext())
                 {
                     V_9       = V_8.get_Current();
                     dummyVar1 = loopBody.Add(V_9);
                 }
             }
             finally
             {
                 if (V_8 != null)
                 {
                     V_8.Dispose();
                 }
             }
         }
     }
     finally
     {
         ((IDisposable)V_1).Dispose();
     }
     return(V_0);
 }
        /// <summary>
        /// Builds the adjacency matrix of the subgraph by using the given <paramref name="dfsTree"/>.
        /// </summary>
        /// <remarks>
        /// The back edges are not included in the built subgraph.
        /// </remarks>
        /// <param name="dfsTree"></param>
        private void BuildAdjacencyMatrix(DFSTree dfsTree)
        {
            DFSTEdge[] edgeArray = GetForwardFlowEdges(dfsTree);
            adjacencyMatrix = new int[orderedVertexArray.Length, orderedVertexArray.Length];

            foreach (DFSTEdge edge in edgeArray)
            {
                int startIndex = edge.Start.ReversePostOrderIndex;
                int endIndex   = edge.End.ReversePostOrderIndex;

                if (startIndex == endIndex)
                {
                    continue;
                }

                int weight = GetWeight(edge.Start.Construct as ILogicalConstruct, edge.End.Construct as ILogicalConstruct);
                adjacencyMatrix[startIndex, endIndex] = weight;
            }
        }
        /// <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);
        }
        /// <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);
                }
            }
        }
        /// <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;
                    }
                }
            }
        }
        /// <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);
                }
            }
        }
 private void BuildAdjacencyMatrix(DFSTree dfsTree)
 {
     stackVariable2       = this.GetForwardFlowEdges(dfsTree);
     this.adjacencyMatrix = new int[(int)this.orderedVertexArray.Length, (int)this.orderedVertexArray.Length];
     V_0 = stackVariable2;
     V_1 = 0;
     while (V_1 < (int)V_0.Length)
     {
         V_2 = V_0[V_1];
         V_3 = V_2.get_Start().get_ReversePostOrderIndex();
         V_4 = V_2.get_End().get_ReversePostOrderIndex();
         if (V_3 != V_4)
         {
             V_5 = this.GetWeight(V_2.get_Start().get_Construct() as ILogicalConstruct, V_2.get_End().get_Construct() as ILogicalConstruct);
             this.adjacencyMatrix[V_3, V_4] = V_5;
         }
         V_1 = V_1 + 1;
     }
     return;
 }
        /// <summary>
        /// Returns the condition loop exit with the greatest post order index, that has the <paramref name="loopSuccessor"/> as successor.
        /// </summary>
        /// <param name="dfsTree"></param>
        /// <param name="loopBody"></param>
        /// <param name="loopExits"></param>
        /// <param name="loopSuccessor"></param>
        /// <returns></returns>
        private ConditionLogicalConstruct GetLoopConditionWithMaxIndex(DFSTree dfsTree, HashSet <ILogicalConstruct> loopBody, HashSet <ILogicalConstruct> loopExits,
                                                                       ILogicalConstruct loopSuccessor)
        {
            int maxOrderIndexOfExit = -1;

            foreach (ILogicalConstruct loopExit in loopExits)
            {
                int currentOrderIndex = dfsTree.ConstructToNodeMap[loopExit].ReversePostOrderIndex;
                if (loopExit.SameParentSuccessors.Contains(loopSuccessor) && currentOrderIndex > maxOrderIndexOfExit && CanBeLoopCondition(loopExit, loopBody))
                {
                    maxOrderIndexOfExit = currentOrderIndex;
                }
            }

            if (maxOrderIndexOfExit > -1)
            {
                return(dfsTree.ReversePostOrder[maxOrderIndexOfExit].Construct as ConditionLogicalConstruct);
            }

            return(null);
        }
        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);
        }
Beispiel #19
0
 private IEnumerable <ConditionLogicalConstruct> GetPostOrderedIfConditionCandidates(DFSTree dfsTree)
 {
     stackVariable1 = new IfBuilder.u003cGetPostOrderedIfConditionCandidatesu003ed__5(-2);
     stackVariable1.u003cu003e3__dfsTree = dfsTree;
     return(stackVariable1);
 }
Beispiel #20
0
 private ILogicalConstruct CheckSuccessor(ILogicalConstruct condition, ILogicalConstruct conditionSuccessor, HashSet <ISingleEntrySubGraph> otherSuccessorFrontier, DFSTree dfsTree)
 {
     if (otherSuccessorFrontier.Contains(conditionSuccessor) && !dfsTree.get_ConstructToNodeMap().TryGetValue(conditionSuccessor, out V_0) || dfsTree.get_ConstructToNodeMap().get_Item(condition).CompareTo(V_0) < 0)
     {
         return(conditionSuccessor);
     }
     return(null);
 }
Beispiel #21
0
        /// <summary>
        /// Tries to build an if construct with condition - the specified condition.
        /// </summary>
        /// <remarks>
        /// The idea is to get the dominated nodes of the true successor to create the then block and the dominated nodes of the false successor
        /// to create the else block.
        /// If both the then and else blocks have successors, then they must have a common successor to create the if construct.
        /// </remarks>
        /// <param name="condition"></param>
        /// <returns>True on success.</returns>
        private bool TryBuildIfConstruct(ConditionLogicalConstruct condition, DominatorTree dominatorTree, DFSTree dfsTree)
        {
            //Store the true and false successors for optimization.
            ILogicalConstruct falseSuccessor = condition.FalseSuccessor;
            ILogicalConstruct trueSuccessor  = condition.TrueSuccessor;

            HashSet <ISingleEntrySubGraph> falseSuccessorFrontier = dominatorTree.GetDominanceFrontier(falseSuccessor);
            HashSet <ISingleEntrySubGraph> trueSuccessorFrontier  = dominatorTree.GetDominanceFrontier(trueSuccessor);

            ILogicalConstruct exitSuccessor = CheckSuccessor(condition, trueSuccessor, falseSuccessorFrontier, dfsTree) ??
                                              CheckSuccessor(condition, falseSuccessor, trueSuccessorFrontier, dfsTree);

            HashSet <ISingleEntrySubGraph> frontierIntersection = new HashSet <ISingleEntrySubGraph>(trueSuccessorFrontier);

            frontierIntersection.IntersectWith(falseSuccessorFrontier);

            if (exitSuccessor == null && falseSuccessorFrontier.Count > 0 && trueSuccessorFrontier.Count > 0 && frontierIntersection.Count == 0)
            {
                //If none of the successors can be a proper exit and the false and true successor frontiers are not empty but have no common node,
                //then we do not make the if since it will not have a common exit.
                return(false);
            }

            HashSet <ILogicalConstruct> thenBody = GetBlockBody(dominatorTree, trueSuccessor, condition);
            HashSet <ILogicalConstruct> elseBody = GetBlockBody(dominatorTree, falseSuccessor, condition);

            if (thenBody == null && elseBody == null)
            {
                return(false);
            }
            else if (thenBody == null)
            {
                condition.Negate(typeSystem);

                ILogicalConstruct swapHelper = trueSuccessor;
                trueSuccessor  = falseSuccessor;
                falseSuccessor = swapHelper;

                thenBody = elseBody;
                elseBody = null;
            }

            //If the else body is null but the false successor is not a successor of the then body then we do not make the if.
            if (elseBody == null && !CheckSuccessors(thenBody, falseSuccessor))
            {
                return(false);
            }

            if (ShouldInvertIfAndRemoveElse(thenBody, trueSuccessor, elseBody, falseSuccessor))
            {
                ///This is performed for cosmetic reasons.
                condition.Negate(typeSystem);

                ILogicalConstruct successorSwapHelper = trueSuccessor;
                trueSuccessor  = falseSuccessor;
                falseSuccessor = successorSwapHelper;

                HashSet <ILogicalConstruct> swapHelper = thenBody;
                thenBody = elseBody;
                elseBody = swapHelper;
                elseBody = null;
            }
            if (elseBody != null && !HasSuccessors(thenBody) &&
                SubtreeEndsInInstructionCode(trueSuccessor.FirstBlock.TheBlock, new Code[] { Code.Ret, Code.Throw }))             // check if all ends are throw and/or return -> allow mixed ends as well
            {
                // we don't need the else
                elseBody = null;
            }

            BlockLogicalConstruct theThenBlock = new BlockLogicalConstruct(trueSuccessor, thenBody);
            BlockLogicalConstruct theElseBlock = elseBody != null ? new BlockLogicalConstruct(falseSuccessor, elseBody) : null;

            IfLogicalConstruct theIfConstruct = IfLogicalConstruct.GroupInIfConstruct(condition, theThenBlock, theElseBlock);

            UpdateDominatorTree(dominatorTree, theIfConstruct);
            return(true);
        }
Beispiel #22
0
 private bool TryBuildIfConstruct(ConditionLogicalConstruct condition, DominatorTree dominatorTree, DFSTree dfsTree)
 {
     V_0             = condition.get_FalseSuccessor();
     V_1             = condition.get_TrueSuccessor();
     V_2             = dominatorTree.GetDominanceFrontier(V_0);
     V_3             = dominatorTree.GetDominanceFrontier(V_1);
     stackVariable15 = this.CheckSuccessor(condition, V_1, V_2, dfsTree);
     if (stackVariable15 == null)
     {
         dummyVar0       = stackVariable15;
         stackVariable15 = this.CheckSuccessor(condition, V_0, V_3, dfsTree);
     }
     V_4 = new HashSet <ISingleEntrySubGraph>(V_3);
     V_4.IntersectWith(V_2);
     if (stackVariable15 == null && V_2.get_Count() > 0 && V_3.get_Count() > 0 && V_4.get_Count() == 0)
     {
         return(false);
     }
     V_5 = this.GetBlockBody(dominatorTree, V_1, condition);
     V_6 = this.GetBlockBody(dominatorTree, V_0, condition);
     if (V_5 == null && V_6 == null)
     {
         return(false);
     }
     if (V_5 == null)
     {
         condition.Negate(this.typeSystem);
         stackVariable86 = V_1;
         V_1             = V_0;
         V_0             = stackVariable86;
         V_5             = V_6;
         V_6             = null;
     }
     if (V_6 == null && !this.CheckSuccessors(V_5, V_0))
     {
         return(false);
     }
     if (this.ShouldInvertIfAndRemoveElse(V_5, V_1, V_6, V_0))
     {
         condition.Negate(this.typeSystem);
         stackVariable73 = V_1;
         V_1             = V_0;
         V_0             = stackVariable73;
         stackVariable75 = V_5;
         V_5             = V_6;
         V_6             = stackVariable75;
         V_6             = null;
     }
     if (V_6 != null && !this.HasSuccessors(V_5))
     {
         stackVariable61    = V_1.get_FirstBlock().get_TheBlock();
         stackVariable63    = new Code[2];
         stackVariable63[0] = 41;
         stackVariable63[1] = 119;
         if (this.SubtreeEndsInInstructionCode(stackVariable61, stackVariable63))
         {
             V_6 = null;
         }
     }
     V_7 = new BlockLogicalConstruct(V_1, V_5);
     if (V_6 != null)
     {
         stackVariable46 = new BlockLogicalConstruct(V_0, V_6);
     }
     else
     {
         stackVariable46 = null;
     }
     this.UpdateDominatorTree(dominatorTree, IfLogicalConstruct.GroupInIfConstruct(condition, V_7, stackVariable46));
     return(true);
 }
Beispiel #23
0
        /// <summary>
        /// Gets the candidates to become conditions of if constructs in postorder.
        /// </summary>
        /// <param name="construct"></param>
        /// <returns></returns>
        private IEnumerable <ConditionLogicalConstruct> GetPostOrderedIfConditionCandidates(DFSTree dfsTree)
        {
            //The post order is so that we start making the if constructs from the innermost nested first (if there is nesting).

            for (int i = dfsTree.ReversePostOrder.Count - 1; i >= 0; i--)
            {
                ConditionLogicalConstruct currentConstruct = dfsTree.ReversePostOrder[i].Construct as ConditionLogicalConstruct;

                //For candidates we take these conditions that have 2 same parent successors.
                //TODO: consider taking the conditions with 1 same parent successor.
                if (currentConstruct != null && currentConstruct.SameParentSuccessors.Count == 2)
                {
                    yield return(currentConstruct);
                }
            }
        }
        /// <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);
                }
            }
        }
Beispiel #25
0
        /// <summary>
        /// Checks if the specified condition successor can be successor of the if construct.
        /// </summary>
        /// <param name="condition">The condition.</param>
        /// <param name="conditionSuccessor">The condition successor.</param>
        /// <param name="otherSuccessorFrontier">The dominance frontier of the other successor.</param>
        /// <returns>On success - the successor. Otherwise null.</returns>
        private ILogicalConstruct CheckSuccessor(ILogicalConstruct condition, ILogicalConstruct conditionSuccessor,
                                                 HashSet <ISingleEntrySubGraph> otherSuccessorFrontier, DFSTree dfsTree)
        {
            //In order the condition successor to be successor of the if, it has to be in the dominance frontier of the other successor.
            //Also the edge between the condition and the successor should not be backedge or crossedge.
            DFSTNode successorNode;

            if (otherSuccessorFrontier.Contains(conditionSuccessor) &&
                (!dfsTree.ConstructToNodeMap.TryGetValue(conditionSuccessor, out successorNode) || dfsTree.ConstructToNodeMap[condition].CompareTo(successorNode) < 0))
            {
                return(conditionSuccessor);
            }

            return(null);
        }