bool ion::BuildDominatorTree(MIRGraph &graph) { ComputeImmediateDominators(graph); // Traversing through the graph in post-order means that every use // of a definition is visited before the def itself. Since a def // dominates its uses, by the time we reach a particular // block, we have processed all of its dominated children, so // block->numDominated() is accurate. for (PostorderIterator i(graph.poBegin()); i != graph.poEnd(); i++) { MBasicBlock *child = *i; MBasicBlock *parent = child->immediateDominator(); // If the block only self-dominates, it has no definite parent. if (child == parent) continue; if (!parent->addImmediatelyDominatedBlock(child)) return false; // An additional +1 for the child block. parent->addNumDominated(child->numDominated() + 1); } #ifdef DEBUG // If compiling with OSR, many blocks will self-dominate. // Without OSR, there is only one root block which dominates all. if (!graph.osrBlock()) JS_ASSERT(graph.begin()->numDominated() == graph.numBlocks() - 1); #endif // Now, iterate through the dominator tree and annotate every // block with its index in the pre-order traversal of the // dominator tree. Vector<MBasicBlock *, 1, IonAllocPolicy> worklist; // The index of the current block in the CFG traversal. size_t index = 0; // Add all self-dominating blocks to the worklist. // This includes all roots. Order does not matter. for (MBasicBlockIterator i(graph.begin()); i != graph.end(); i++) { MBasicBlock *block = *i; if (block->immediateDominator() == block) { if (!worklist.append(block)) return false; } } // Starting from each self-dominating block, traverse the CFG in pre-order. while (!worklist.empty()) { MBasicBlock *block = worklist.popCopy(); block->setDomIndex(index); for (size_t i = 0; i < block->numImmediatelyDominatedBlocks(); i++) { if (!worklist.append(block->getImmediatelyDominatedBlock(i))) return false; } index++; } return true; }