/// <summary> /// Constructs the dominators for the given control flow graph. /// </summary> /// <param name="cfg">The control flow graph.</param> private Dominators(CFG cfg) { CFG = cfg ?? throw new ArgumentNullException(nameof(cfg)); idomsInRPO = new int[cfg.Count]; nodesInRPO = new CFG.Node[cfg.Count]; idomsInRPO[0] = 0; for (int i = 1, e = idomsInRPO.Length; i < e; ++i) { idomsInRPO[i] = -1; } bool changed; do { changed = false; using (var enumerator = cfg.GetEnumerator()) { enumerator.MoveNext(); var node = enumerator.Current; nodesInRPO[node.RPONumber] = node; while (enumerator.MoveNext()) { node = enumerator.Current; nodesInRPO[node.RPONumber] = node; int currentIdom = -1; foreach (var pred in node.Predecessors) { var predRPO = pred.RPONumber; if (idomsInRPO[predRPO] != -1) { currentIdom = predRPO; break; } } Debug.Assert(currentIdom != -1, "Invalid idom"); foreach (var pred in node.Predecessors) { var predRPO = pred.RPONumber; if (idomsInRPO[predRPO] != -1) { currentIdom = Intersect(currentIdom, predRPO); } } var rpoNumber = node.RPONumber; if (idomsInRPO[rpoNumber] != currentIdom) { idomsInRPO[rpoNumber] = currentIdom; changed = true; } } } }while (changed); }
/// <summary> /// Constructs the dominators for the given control-flow graph. /// </summary> /// <param name="cfg">The parent graph.</param> private Dominators(CFG <DominanceOrder, TDirection> cfg) { idomsInRPO = new int[cfg.Count]; nodesInRPO = new BasicBlock[cfg.Count]; CFG = cfg; Root = cfg.Root; idomsInRPO[0] = 0; for (int i = 1, e = idomsInRPO.Length; i < e; ++i) { idomsInRPO[i] = -1; } bool changed; do { changed = false; var enumerator = cfg.GetEnumerator(); enumerator.MoveNext(); var node = enumerator.Current; nodesInRPO[node.TraversalIndex] = node; while (enumerator.MoveNext()) { node = enumerator.Current; nodesInRPO[node.TraversalIndex] = node; int currentIdom = -1; foreach (var pred in node.Predecessors) { var predRPO = pred.TraversalIndex; if (idomsInRPO[predRPO] != -1) { currentIdom = predRPO; break; } } Debug.Assert(currentIdom != -1, "Invalid idom"); foreach (var pred in node.Predecessors) { var predRPO = pred.TraversalIndex; if (idomsInRPO[predRPO] != -1) { currentIdom = Intersect(currentIdom, predRPO); } } var rpoNumber = node.TraversalIndex; if (idomsInRPO[rpoNumber] != currentIdom) { idomsInRPO[rpoNumber] = currentIdom; changed = true; } } }while (changed); }