예제 #1
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);
 }
        /// <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);
                        }
                    }
                }
            }
        }
예제 #3
0
 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);
                        }
                    }
                }
            }
        }
예제 #6
0
 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));
 }
예제 #7
0
 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);
        }
예제 #13
0
        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);
                }
            }
        }