public void AddEdgeTo(ControlFlowNode target) { this.Successors.Add(target); target.Predecessors.Add(this); }
/// <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; } }