/// <summary>
        /// Expands <paramref name="nodesInLoop"/> with the cross edges exiting from it.
        /// </summary>
        /// <param name="nodesInLoop">The nodes, already part of the loop.</param>
        /// <returns>Returns the expanded collection of nodes.</returns>
        private ICollection <DFSTNode> ExpandLoopBodyWithCrossEdges(ICollection <DFSTNode> nodesInLoop)
        {
            HashSet <DFSTNode> hashetNodes = new HashSet <DFSTNode>(nodesInLoop);
            Queue <DFSTNode>   queue       = new Queue <DFSTNode>(nodesInLoop);

            /// Perform BFS on the nodes.
            while (queue.Count > 0)
            {
                DFSTNode currentNode = queue.Dequeue();
                /// Traversing the predecessors.
                /// Traverse predecessors instead of successors for two reasons
                /// 1) Predecessors are sure to be part of the loop, since the node it precedes is in the loop, thus the predecessor
                ///     is dominated by the ehader node as well.
                /// 2) For CrossEdge successors, this statement is not valid. Both the node and the successor have common dominator,
                ///     but this might not be the loop header node.
                foreach (DFSTNode predecessor in currentNode.CrossEdgePredecessors)
                {
                    if (!hashetNodes.Contains(predecessor))
                    {
                        hashetNodes.Add(predecessor);
                        queue.Enqueue(predecessor);
                    }
                }

                DFSTNode nodePredecessor = currentNode.Predecessor as DFSTNode;

                if (nodePredecessor != null && !hashetNodes.Contains(nodePredecessor))
                {
                    hashetNodes.Add(nodePredecessor);
                    queue.Enqueue(nodePredecessor);
                }
            }
            return(hashetNodes);
        }
        /// <summary>
        /// Recursively traverses the nodes and adds them to the tree. Also determines the type of each edge.
        /// </summary>
        /// <param name="currentNode"></param>
        private void DFSBuild(DFSTNode currentNode)
        {
            traversedNodes.Add(currentNode);

            //The current path is the set of all nodes on the DFS tree path from the root to the current node.
            currentPath.Add(currentNode);

            foreach (ISingleEntrySubGraph successorConstruct in LogicalFlowUtilities.GetTraversableSuccessors(currentNode.Construct))
            {
                DFSTNode successor;
                if(!constructToNodeMap.TryGetValue(successorConstruct, out successor))
                {
                    //Special case for interval constructs
                    continue;
                }

                if (!traversedNodes.Contains(successor))
                {
                    //If the successor is not traversed then the edge between the two nodes is a tree edge.
                    successor.Predecessor = currentNode;
                    currentNode.TreeEdgeSuccessors.Add(successor);
                    theTree.TreeEdges.Add(new DFSTEdge(currentNode, successor));

                    //We continue the build from this successor.
                    DFSBuild(successor);
                }
                else if(currentPath.Contains(successor))
                {
                    //If the successor is traversed and is on the current path then the edge between the nodes is a back edge.
                    successor.BackEdgePredecessors.Add(currentNode);
                    currentNode.BackEdgeSuccessors.Add(successor);
                    theTree.BackEdges.Add(new DFSTEdge(currentNode, successor));
                }
                else if (IsAncestor(successor, currentNode))
                {
                    //If the successor is traversed and the current node is its ancestor, then the edge is a forward edge.
                    successor.ForwardEdgePredecessors.Add(currentNode);
                    currentNode.ForwardEdgeSucessors.Add(successor);
                    theTree.ForwardEdges.Add(new DFSTEdge(currentNode, successor));
                }
                else
                {
                    //Otherwise the edge between the nodes is a cross edge.
                    successor.CrossEdgePredecessors.Add(currentNode);
                    currentNode.CrossEdgeSuccessors.Add(successor);
                    theTree.CrossEdges.Add(new DFSTEdge(currentNode, successor));
                }
            }

            currentPath.Remove(currentNode);

            //Adding the nodes in post order.
            theTree.ReversePostOrder.Add(currentNode);
        }
        private List <DFSTNode> GetPredecessors(DFSTNode node)
        {
            List <DFSTNode> result = new List <DFSTNode>();

            if (node.Predecessor != null)
            {
                result.Add(node.Predecessor as DFSTNode);
            }
            result.AddRange(node.ForwardEdgePredecessors);
            result.AddRange(node.CrossEdgePredecessors);
            result.AddRange(node.BackEdgePredecessors);
            return(result);
        }
        /// <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);
                }
            }
        }
Example #5
0
        /// <summary>
        /// Gets the path in the tree between two nodes. The <paramref name="ancestorNode"/>
        /// must be on the path from the root to the <paramref name="descenderNode"/>.
        /// </summary>
        /// <param name="ancestorNode"></param>
        /// <param name="descenderNode"></param>
        /// <returns></returns>
        public List<DFSTNode> GetPath(DFSTNode ancestorNode, DFSTNode descenderNode)
        {
            List<DFSTNode> path = new List<DFSTNode>();
            DFSTNode currentNodeOnPath = descenderNode;
            while (currentNodeOnPath != null && currentNodeOnPath != ancestorNode)
            {
                path.Add(currentNodeOnPath);
                currentNodeOnPath = (DFSTNode)currentNodeOnPath.Predecessor;
            }

            if (currentNodeOnPath != null)
            {
                path.Add(currentNodeOnPath);
            }
            else
            {
                //sanity check
                throw new Exception("No path between the two nodes.");
            }

            path.Reverse();
            return path;
        }
        /// <summary>
        /// Determines whether <paramref name="supposedAncestor"/> is on the tree path from the root to <paramref name="node"/>
        /// </summary>
        /// <param name="node"></param>
        /// <param name="supposedAncestor"></param>
        /// <returns></returns>
        private bool IsAncestor(DFSTNode node, DFSTNode supposedAncestor)
        {
            DFSTNode currentAncestor = (DFSTNode)node.Predecessor;

            while (currentAncestor != null)
            {
                if (currentAncestor == supposedAncestor)
                {
                    return true;
                }

                currentAncestor = (DFSTNode)currentAncestor.Predecessor;
            }
            return false;
        }
 private List<DFSTNode> GetPredecessors(DFSTNode node)
 {
     List<DFSTNode> result = new List<DFSTNode>();
     if (node.Predecessor != null)
     {
         result.Add(node.Predecessor as DFSTNode);
     }
     result.AddRange(node.ForwardEdgePredecessors);
     result.AddRange(node.CrossEdgePredecessors);
     result.AddRange(node.BackEdgePredecessors);
     return result;
 }