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); }
/// <summary> /// Creates the graph between the interval constructs in <paramref name="intervals"/>. /// </summary> private void CreateGraph(IEnumerable <IntervalConstruct> intervals) { /// Traverse each interval foreach (IntervalConstruct interval in intervals) { /// Traverse each logical construct, part of the interval foreach (ILogicalConstruct node in interval.Children) { IEnumerable <ILogicalConstruct> nodeSuccessorsCollection = GetNodeSuccessors(node); /// Traverse each of the construct's successors foreach (ILogicalConstruct nodeSuccessor in nodeSuccessorsCollection) { if (nodeToInterval.ContainsKey(nodeSuccessor) && nodeToInterval[nodeSuccessor] != interval) { /// The current successor is not part of the construct's interval /// Thus, the interval that holds the successor must succeed the current construct's interval IntervalConstruct successingInterval = nodeToInterval[nodeSuccessor]; if (interval.SameParentSuccessors.Contains(successingInterval)) { /// The relation has already been added continue; } interval.SameParentSuccessors.Add(successingInterval); successingInterval.SameParentPredecessors.Add(interval); } } } } }
private void AddNewHeaders(ILogicalConstruct currentHeader, IntervalConstruct currentInterval) { V_0 = new Stack <ILogicalConstruct>(); V_1 = new HashSet <ILogicalConstruct>(); V_0.Push(currentHeader); while (V_0.get_Count() > 0) { V_2 = V_0.Pop(); if (V_1.Contains(V_2)) { continue; } dummyVar0 = V_1.Add(V_2); V_3 = this.GetNodeSuccessors(V_2).GetEnumerator(); try { while (V_3.MoveNext()) { V_4 = V_3.get_Current(); this.CheckAndAddPossibleHeader(V_4, currentInterval, V_0); } } finally { if (V_3 != null) { V_3.Dispose(); } } } return; }
/// <summary> /// Fills <paramref name="interval"/> with the nodes, that belong to it. /// </summary> /// <param name="intervalHeader">The header node of <paramref name="interval"/>.</param> /// <param name="interval">The interval to be filled with nodes.</param> private void FillInterval(ILogicalConstruct intervalHeader, IntervalConstruct interval) { /// For more clarifications on the algorithm, see "6.3.3 Interval Theory" of <see cref="Reverse Compilation Techniques.pdf"/>. nodeToInterval.Add(intervalHeader, interval); Queue <ILogicalConstruct> possibleNodes = new Queue <ILogicalConstruct>(); IEnumerable <ILogicalConstruct> currentNodeSuccessors = GetNodeSuccessors(intervalHeader); foreach (ILogicalConstruct successor in currentNodeSuccessors) { /// Check if the successor is from the graph that is being analysed /// This check is needed, because GetNodeSuccessors returns all successors, even the one that have been marked only as goto reachable. if (availableNodes.Contains(successor)) { possibleNodes.Enqueue(successor); } } while (possibleNodes.Count > 0) { ILogicalConstruct currentNode = possibleNodes.Dequeue(); //check if the node is in any interval if (nodeToInterval.ContainsKey(currentNode)) { continue; } bool addInInterval = true; IEnumerable <ILogicalConstruct> currentNodePredecessorsCollection = GetNodePredecessors(currentNode); foreach (ILogicalConstruct predecessor in currentNodePredecessorsCollection) { if (!nodeToInterval.ContainsKey(predecessor) || nodeToInterval[predecessor] != interval) { /// The construct has a predecessor, that is not from the current interval. /// Thus, the construct is not dominated by the interval header, and isnt part of the interval addInInterval = false; break; } } if (addInInterval) { /// Add the node to the interval and update the corresponding collections. interval.Children.Add(currentNode); nodeToInterval.Add(currentNode, interval); currentNodeSuccessors = GetNodeSuccessors(currentNode); /// Update the possible nodes collection with all the successors of the current node. foreach (ILogicalConstruct successor in currentNodeSuccessors) { if (availableNodes.Contains(successor)) { possibleNodes.Enqueue(successor); } } } } }
/// <summary> /// Fills <paramref name="interval"/> with the nodes, that belong to it. /// </summary> /// <param name="intervalHeader">The header node of <paramref name="interval"/>.</param> /// <param name="interval">The interval to be filled with nodes.</param> private void FillInterval(ILogicalConstruct intervalHeader, IntervalConstruct interval) { /// For more clarifications on the algorithm, see "6.3.3 Interval Theory" of <see cref="Reverse Compilation Techniques.pdf"/>. nodeToInterval.Add(intervalHeader, interval); Queue<ILogicalConstruct> possibleNodes = new Queue<ILogicalConstruct>(); IEnumerable<ILogicalConstruct> currentNodeSuccessors = GetNodeSuccessors(intervalHeader); foreach (ILogicalConstruct successor in currentNodeSuccessors) { /// Check if the successor is from the graph that is being analysed /// This check is needed, because GetNodeSuccessors returns all successors, even the one that have been marked only as goto reachable. if (availableNodes.Contains(successor)) { possibleNodes.Enqueue(successor); } } while (possibleNodes.Count > 0) { ILogicalConstruct currentNode = possibleNodes.Dequeue(); //check if the node is in any interval if (nodeToInterval.ContainsKey(currentNode)) { continue; } bool addInInterval = true; IEnumerable<ILogicalConstruct> currentNodePredecessorsCollection = GetNodePredecessors(currentNode); foreach (ILogicalConstruct predecessor in currentNodePredecessorsCollection) { if (!nodeToInterval.ContainsKey(predecessor) || nodeToInterval[predecessor] != interval) { /// The construct has a predecessor, that is not from the current interval. /// Thus, the construct is not dominated by the interval header, and isnt part of the interval addInInterval = false; break; } } if (addInInterval) { /// Add the node to the interval and update the corresponding collections. interval.Children.Add(currentNode); nodeToInterval.Add(currentNode, interval); currentNodeSuccessors = GetNodeSuccessors(currentNode); /// Update the possible nodes collection with all the successors of the current node. foreach (ILogicalConstruct successor in currentNodeSuccessors) { if (availableNodes.Contains(successor)) { possibleNodes.Enqueue(successor); } } } } }
public List <IntervalConstruct> ReduceCfg() { this.headers.Enqueue(this.entryPoint); while (this.headers.get_Count() > 0) { V_0 = this.headers.Dequeue(); V_1 = new IntervalConstruct(V_0); this.intervals.Add(V_1); this.FillInterval(V_0, V_1); this.AddNewHeaders(V_0, V_1); } this.CreateGraph(this.intervals); return(this.SortIntervalList(this.intervals)); }
private void CheckAndAddPossibleHeader(ILogicalConstruct node, IntervalConstruct currentInterval, Stack <ILogicalConstruct> st) { if (!this.nodeToInterval.ContainsKey(node)) { if (!this.headers.Contains(node)) { this.headers.Enqueue(node); } return; } if (this.nodeToInterval.get_Item(node) == currentInterval) { st.Push(node); } return; }
/// <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> /// Checks if <paramref name="node"/> is new header. If it is, it's added to 'headers' collection. If it isn't, /// it's pushed in <paramref name="st"/>. /// </summary> /// <param name="node">The node in question.</param> /// <param name="currentInterval">The interval, that looks for successor headers.</param> /// <param name="st">The stack of the recursion.</param> private void CheckAndAddPossibleHeader(ILogicalConstruct node, IntervalConstruct currentInterval, Stack <ILogicalConstruct> st) { /// st should be the stack of AddNewHeaders method if (!nodeToInterval.ContainsKey(node)) { if (!headers.Contains(node)) { /// The node is not in any interval, and not marked as header yet. headers.Enqueue(node); } return; } if (nodeToInterval[node] == currentInterval) { /// The node is part of the interval being inspected. /// The node's children might be headers, so it's added. st.Push(node); } }
/// <summary> /// The entry point of the class. Performs one reducing step on the graph. /// </summary> /// <returns>Returns list of all the intervals.</returns> public List <IntervalConstruct> ReduceCfg() { headers.Enqueue(entryPoint); while (headers.Count > 0) { /// Construct new interval from the header. ILogicalConstruct currentHeader = headers.Dequeue(); IntervalConstruct currentInterval = new IntervalConstruct(currentHeader); intervals.Add(currentInterval); /// Fill the newly constructed interval with the nodes that belong to it. FillInterval(currentHeader, currentInterval); /// Add the headers to the remaining intervals in the graph to 'headers' collection AddNewHeaders(currentHeader, currentInterval); } /// Update the relations between the intervals, based on the nodes they contain. /// Doesn't destroy the relations between the nested nodes themselves. CreateGraph(intervals); return(SortIntervalList(intervals)); }
/// <summary> /// Adds entries to headers collection after the completion of an interval. /// </summary> /// <param name="currentHeader">The header of the completed interval.</param> /// <param name="currentInterval">The completed interval.</param> private void AddNewHeaders(ILogicalConstruct currentHeader, IntervalConstruct currentInterval) { /// Perform DFS on the headers. Stack <ILogicalConstruct> st = new Stack <ILogicalConstruct>(); HashSet <ILogicalConstruct> checkedHeaders = new HashSet <ILogicalConstruct>(); st.Push(currentHeader); while (st.Count > 0) { ILogicalConstruct currentNode = st.Pop(); if (checkedHeaders.Contains(currentNode)) { continue; } checkedHeaders.Add(currentNode); IEnumerable <ILogicalConstruct> currentNodeSuccessorsCollection = GetNodeSuccessors(currentNode); foreach (ILogicalConstruct node in currentNodeSuccessorsCollection) { CheckAndAddPossibleHeader(node, currentInterval, st); } } }
/// <summary> /// The entry point of the class. Performs one reducing step on the graph. /// </summary> /// <returns>Returns list of all the intervals.</returns> public List<IntervalConstruct> ReduceCfg() { headers.Enqueue(entryPoint); while (headers.Count > 0) { /// Construct new interval from the header. ILogicalConstruct currentHeader = headers.Dequeue(); IntervalConstruct currentInterval = new IntervalConstruct(currentHeader); intervals.Add(currentInterval); /// Fill the newly constructed interval with the nodes that belong to it. FillInterval(currentHeader, currentInterval); /// Add the headers to the remaining intervals in the graph to 'headers' collection AddNewHeaders(currentHeader, currentInterval); } /// Update the relations between the intervals, based on the nodes they contain. /// Doesn't destroy the relations between the nested nodes themselves. CreateGraph(intervals); return SortIntervalList(intervals); }
private void FillInterval(ILogicalConstruct intervalHeader, IntervalConstruct interval) { this.nodeToInterval.Add(intervalHeader, interval); V_0 = new Queue <ILogicalConstruct>(); V_1 = this.GetNodeSuccessors(intervalHeader).GetEnumerator(); try { while (V_1.MoveNext()) { V_2 = V_1.get_Current(); if (!this.availableNodes.Contains(V_2)) { continue; } V_0.Enqueue(V_2); } } finally { if (V_1 != null) { V_1.Dispose(); } } while (V_0.get_Count() > 0) { V_3 = V_0.Dequeue(); if (this.nodeToInterval.ContainsKey(V_3)) { continue; } V_4 = true; V_1 = this.GetNodePredecessors(V_3).GetEnumerator(); try { while (V_1.MoveNext()) { V_5 = V_1.get_Current(); if (this.nodeToInterval.ContainsKey(V_5) && this.nodeToInterval.get_Item(V_5) == interval) { continue; } V_4 = false; goto Label0; } } finally { if (V_1 != null) { V_1.Dispose(); } } Label0: if (!V_4) { continue; } dummyVar0 = interval.get_Children().Add(V_3); this.nodeToInterval.Add(V_3, interval); V_1 = this.GetNodeSuccessors(V_3).GetEnumerator(); try { while (V_1.MoveNext()) { V_6 = V_1.get_Current(); if (!this.availableNodes.Contains(V_6)) { continue; } V_0.Enqueue(V_6); } } finally { if (V_1 != null) { V_1.Dispose(); } } } return; }
/// <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> /// Checks if <paramref name="node"/> is new header. If it is, it's added to 'headers' collection. If it isn't, /// it's pushed in <paramref name="st"/>. /// </summary> /// <param name="node">The node in question.</param> /// <param name="currentInterval">The interval, that looks for successor headers.</param> /// <param name="st">The stack of the recursion.</param> private void CheckAndAddPossibleHeader(ILogicalConstruct node, IntervalConstruct currentInterval, Stack<ILogicalConstruct> st) { /// st should be the stack of AddNewHeaders method if (!nodeToInterval.ContainsKey(node)) { if (!headers.Contains(node)) { /// The node is not in any interval, and not marked as header yet. headers.Enqueue(node); } return; } if (nodeToInterval[node] == currentInterval) { /// The node is part of the interval being inspected. /// The node's children might be headers, so it's added. st.Push(node); } }
/// <summary> /// Adds entries to headers collection after the completion of an interval. /// </summary> /// <param name="currentHeader">The header of the completed interval.</param> /// <param name="currentInterval">The completed interval.</param> private void AddNewHeaders(ILogicalConstruct currentHeader, IntervalConstruct currentInterval) { /// Perform DFS on the headers. Stack<ILogicalConstruct> st = new Stack<ILogicalConstruct>(); HashSet<ILogicalConstruct> checkedHeaders = new HashSet<ILogicalConstruct>(); st.Push(currentHeader); while (st.Count > 0) { ILogicalConstruct currentNode = st.Pop(); if (checkedHeaders.Contains(currentNode)) { continue; } checkedHeaders.Add(currentNode); IEnumerable<ILogicalConstruct> currentNodeSuccessorsCollection = GetNodeSuccessors(currentNode); foreach (ILogicalConstruct node in currentNodeSuccessorsCollection) { CheckAndAddPossibleHeader(node, currentInterval, st); } } }