public void AddEdgeTo(ControlFlowNode target)
 {
     this.Successors.Add(target);
     target.Predecessors.Add(this);
 }
Exemple #2
0
        /// <summary>
        /// Computes the dominator tree.
        /// </summary>
        /// <remarks>
        /// Precondition: the dominance tree is not already computed for some nodes reachable from entryPoint
        /// (i.e. ImmediateDominator and DominatorTreeChildren are both null),
        /// and the visited flag is false for any nodes reachable from entryPoint.
        ///
        /// Postcondition: a dominator tree is constructed for all nodes reachable from entryPoint,
        /// and the visited flag remains false.
        /// </remarks>
        public static void ComputeDominance(ControlFlowNode entryPoint, CancellationToken cancellationToken = default(CancellationToken))
        {
            // A Simple, Fast Dominance Algorithm
            // Keith D. Cooper, Timothy J. Harvey and Ken Kennedy

            var nodes = new List <ControlFlowNode>();

            entryPoint.TraversePostOrder(n => n.Successors, nodes.Add);
            Debug.Assert(nodes.Last() == entryPoint);
            for (int i = 0; i < nodes.Count; i++)
            {
                nodes[i].PostOrderNumber = i;
            }

            // For the purpose of this algorithm, make the entry point its own dominator.
            // We'll reset it back to null at the end of this function.
            entryPoint.ImmediateDominator = entryPoint;
            bool changed;

            do
            {
                changed = false;

                cancellationToken.ThrowIfCancellationRequested();

                // For all nodes b except the entry point (in reverse post-order)
                for (int i = nodes.Count - 2; i >= 0; i--)
                {
                    ControlFlowNode b = nodes[i];
                    // Compute new immediate dominator:
                    ControlFlowNode newIdom = null;
                    foreach (var p in b.Predecessors)
                    {
                        // Ignore predecessors that were not processed yet
                        if (p.ImmediateDominator != null)
                        {
                            if (newIdom == null)
                            {
                                newIdom = p;
                            }
                            else
                            {
                                newIdom = FindCommonDominator(p, newIdom);
                            }
                        }
                    }
                    // The reverse post-order ensures at least one of our predecessors was processed.
                    Debug.Assert(newIdom != null);
                    if (newIdom != b.ImmediateDominator)
                    {
                        b.ImmediateDominator = newIdom;
                        changed = true;
                    }
                }
            } while(changed);
            // Create dominator tree for all reachable nodes:
            foreach (ControlFlowNode node in nodes)
            {
                if (node.ImmediateDominator != null)
                {
                    node.DominatorTreeChildren = new List <ControlFlowNode>();
                }
            }
            entryPoint.ImmediateDominator = null;
            foreach (ControlFlowNode node in nodes)
            {
                // Create list of children in dominator tree
                if (node.ImmediateDominator != null)
                {
                    node.ImmediateDominator.DominatorTreeChildren.Add(node);
                }
                // Also reset the visited flag
                node.Visited = false;
            }
        }