/// <summary> /// Generates the loops in the graph with entry point <paramref name="construct"/>. /// </summary> /// <param name="construct">The entry point of the graph.</param> private void ProcessLogicalConstruct(ILogicalConstruct construct) { DominatorTree dominatorTree = GetDominatorTreeFromContext(construct); int lastIterationIntervalsCount = int.MaxValue; RemoveBackEdgesFromSwitchConstructs(construct); while (lastIterationIntervalsCount > 1) { IntervalAnalyzer ia = new IntervalAnalyzer(construct, removedEdges); List<IntervalConstruct> intervals = ia.ReduceCfg(); List<IntervalConstruct> reverseIntervals = new List<IntervalConstruct>(intervals); reverseIntervals.Reverse(); /// Make only one loop at a time, since the newly made loop can be the header node of a bigger loop (if they are nested so). bool madeLoop = false; foreach (IntervalConstruct interval in reverseIntervals) { if (TryMakeLoop(interval, dominatorTree)) { madeLoop = true; break; } } if(madeLoop) { lastIterationIntervalsCount = intervals.Count; continue; } /// No loop was made in the last iteration and the interval count wasn't reduced. Then, an edge must be deleted from the graph, /// to ensure the reducibility. if (intervals.Count == lastIterationIntervalsCount) { RemoveBlockingEdges(intervals); } /// This is sanity check. Intervals are supposed to decrease in count, or stay the same with each iteration if (intervals.Count > lastIterationIntervalsCount) { throw new Exception("Intervails are more than in the last iteration."); } lastIterationIntervalsCount = intervals.Count; } }
/// <summary> /// Generates the loops in the graph with entry point <paramref name="construct"/>. /// </summary> /// <param name="construct">The entry point of the graph.</param> private void ProcessLogicalConstruct(ILogicalConstruct construct) { DominatorTree dominatorTree = GetDominatorTreeFromContext(construct); int lastIterationIntervalsCount = int.MaxValue; RemoveBackEdgesFromSwitchConstructs(construct); while (lastIterationIntervalsCount > 1) { IntervalAnalyzer ia = new IntervalAnalyzer(construct, removedEdges); List <IntervalConstruct> intervals = ia.ReduceCfg(); List <IntervalConstruct> reverseIntervals = new List <IntervalConstruct>(intervals); reverseIntervals.Reverse(); /// Make only one loop at a time, since the newly made loop can be the header node of a bigger loop (if they are nested so). bool madeLoop = false; foreach (IntervalConstruct interval in reverseIntervals) { if (TryMakeLoop(interval, dominatorTree)) { madeLoop = true; break; } } if (madeLoop) { lastIterationIntervalsCount = intervals.Count; continue; } /// No loop was made in the last iteration and the interval count wasn't reduced. Then, an edge must be deleted from the graph, /// to ensure the reducibility. if (intervals.Count == lastIterationIntervalsCount) { RemoveBlockingEdges(intervals); } /// This is sanity check. Intervals are supposed to decrease in count, or stay the same with each iteration if (intervals.Count > lastIterationIntervalsCount) { throw new Exception("Intervails are more than in the last iteration."); } lastIterationIntervalsCount = intervals.Count; } }