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); }
private HashSet <ILogicalConstruct> GetIntervalSuccessors(IntervalConstruct interval, ILogicalConstruct startNode) { V_0 = new HashSet <ILogicalConstruct>(); if (!interval.get_Children().Contains(startNode)) { return(V_0); } V_1 = new Queue <ILogicalConstruct>(); V_1.Enqueue(startNode); V_2 = new HashSet <ILogicalConstruct>(); dummyVar0 = V_2.Add(startNode); while (V_1.get_Count() > 0) { V_3 = V_1.Dequeue().get_SameParentSuccessors().GetEnumerator(); try { while (V_3.MoveNext()) { V_4 = (ILogicalConstruct)V_3.get_Current(); if (V_2.Contains(V_4) || !interval.get_Children().Contains(V_4) || !V_0.Add(V_4)) { continue; } dummyVar1 = V_2.Add(V_4); V_1.Enqueue(V_4); } } finally { ((IDisposable)V_3).Dispose(); } } return(V_0); }
/// <summary> /// Gets the successors (direct or indirect) of the given <paramref name="startNode"/>, /// that are in the specified <paramref name="interval"/>. /// </summary> /// <remarks> /// If the start node is not in the interval, then it will not be traversed. This is a corner case for entwined loops. /// The start node will not be included in the result, even if it is its own successor. /// </remarks> /// <returns></returns> private HashSet <ILogicalConstruct> GetIntervalSuccessors(IntervalConstruct interval, ILogicalConstruct startNode) { HashSet <ILogicalConstruct> intervalSuccessors = new HashSet <ILogicalConstruct>(); if (!interval.Children.Contains(startNode)) { return(intervalSuccessors); } Queue <ILogicalConstruct> traversalQueue = new Queue <ILogicalConstruct>(); traversalQueue.Enqueue(startNode); HashSet <ILogicalConstruct> traversedNodes = new HashSet <ILogicalConstruct>(); traversedNodes.Add(startNode); while (traversalQueue.Count > 0) { ILogicalConstruct currentNode = traversalQueue.Dequeue(); foreach (ILogicalConstruct successor in currentNode.SameParentSuccessors) { if (!traversedNodes.Contains(successor) && interval.Children.Contains(successor) && intervalSuccessors.Add(successor)) { traversedNodes.Add(successor); traversalQueue.Enqueue(successor); } } } return(intervalSuccessors); }
/// <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); }
/// <summary> /// Adds all of the nodes from the <paramref name="interval"/>, that are not preceded by the <paramref name="loopSuccessor"/>, /// to the <paramref name="loopBody"/>. /// </summary> /// <remarks> /// Does not add the <paramref name="loopSuccessor"/>. /// </remarks> private void ExpandLoopBody(IntervalConstruct interval, HashSet <ILogicalConstruct> loopBody, ILogicalConstruct loopSuccessor) { HashSet <ILogicalConstruct> nodesToSkip = GetIntervalSuccessors(interval, loopSuccessor); nodesToSkip.Add(loopSuccessor); foreach (LogicalConstructBase node in interval.Children) { if (!nodesToSkip.Contains(node)) { loopBody.Add(node); } } }
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; }
/// <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; } } } }
private void ExpandLoopBody(IntervalConstruct interval, HashSet <ILogicalConstruct> loopBody, ILogicalConstruct loopSuccessor) { V_0 = this.GetIntervalSuccessors(interval, loopSuccessor); dummyVar0 = V_0.Add(loopSuccessor); V_1 = interval.get_Children().GetEnumerator(); try { while (V_1.MoveNext()) { V_2 = (LogicalConstructBase)V_1.get_Current(); if (V_0.Contains(V_2)) { continue; } dummyVar1 = loopBody.Add(V_2); } } finally { ((IDisposable)V_1).Dispose(); } return; }
/// <summary> /// Gets the successors (direct or indirect) of the given <paramref name="startNode"/>, /// that are in the specified <paramref name="interval"/>. /// </summary> /// <remarks> /// If the start node is not in the interval, then it will not be traversed. This is a corner case for entwined loops. /// The start node will not be included in the result, even if it is its own successor. /// </remarks> /// <returns></returns> private HashSet<ILogicalConstruct> GetIntervalSuccessors(IntervalConstruct interval, ILogicalConstruct startNode) { HashSet<ILogicalConstruct> intervalSuccessors = new HashSet<ILogicalConstruct>(); if (!interval.Children.Contains(startNode)) { return intervalSuccessors; } Queue<ILogicalConstruct> traversalQueue = new Queue<ILogicalConstruct>(); traversalQueue.Enqueue(startNode); HashSet<ILogicalConstruct> traversedNodes = new HashSet<ILogicalConstruct>(); traversedNodes.Add(startNode); while(traversalQueue.Count > 0) { ILogicalConstruct currentNode = traversalQueue.Dequeue(); foreach (ILogicalConstruct successor in currentNode.SameParentSuccessors) { if(!traversedNodes.Contains(successor) && interval.Children.Contains(successor) && intervalSuccessors.Add(successor)) { traversedNodes.Add(successor); traversalQueue.Enqueue(successor); } } } return intervalSuccessors; }
/// <summary> /// Adds all of the nodes from the <paramref name="interval"/>, that are not preceded by the <paramref name="loopSuccessor"/>, /// to the <paramref name="loopBody"/>. /// </summary> /// <remarks> /// Does not add the <paramref name="loopSuccessor"/>. /// </remarks> private void ExpandLoopBody(IntervalConstruct interval, HashSet<ILogicalConstruct> loopBody, ILogicalConstruct loopSuccessor) { HashSet<ILogicalConstruct> nodesToSkip = GetIntervalSuccessors(interval, loopSuccessor); nodesToSkip.Add(loopSuccessor); foreach (LogicalConstructBase node in interval.Children) { if (!nodesToSkip.Contains(node)) { loopBody.Add(node); } } }
/// <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; } } }
/// <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; }
/// <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; } } } }
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); }
/// <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); } } }