static void ComputeImmediateDominators(MIRGraph &graph) { // The default start block is a root and therefore only self-dominates. MBasicBlock *startBlock = *graph.begin(); startBlock->setImmediateDominator(startBlock); // Any OSR block is a root and therefore only self-dominates. MBasicBlock *osrBlock = graph.osrBlock(); if (osrBlock) osrBlock->setImmediateDominator(osrBlock); bool changed = true; while (changed) { changed = false; ReversePostorderIterator block = graph.rpoBegin(); // For each block in RPO, intersect all dominators. for (; block != graph.rpoEnd(); block++) { // If a node has once been found to have no exclusive dominator, // it will never have an exclusive dominator, so it may be skipped. if (block->immediateDominator() == *block) continue; MBasicBlock *newIdom = block->getPredecessor(0); // Find the first common dominator. for (size_t i = 1; i < block->numPredecessors(); i++) { MBasicBlock *pred = block->getPredecessor(i); if (pred->immediateDominator() != NULL) newIdom = IntersectDominators(pred, newIdom); // If there is no common dominator, the block self-dominates. if (newIdom == NULL) { block->setImmediateDominator(*block); changed = true; break; } } if (newIdom && block->immediateDominator() != newIdom) { block->setImmediateDominator(newIdom); changed = true; } } } #ifdef DEBUG // Assert that all blocks have dominator information. for (MBasicBlockIterator block(graph.begin()); block != graph.end(); block++) { JS_ASSERT(block->immediateDominator() != NULL); } #endif }
// A loop is about to be made reachable only through an OSR entry into one of // its nested loops. Fix everything up. bool ValueNumberer::fixupOSROnlyLoop(MBasicBlock* block, MBasicBlock* backedge) { // Create an empty and unreachable(!) block which jumps to |block|. This // allows |block| to remain marked as a loop header, so we don't have to // worry about moving a different block into place as the new loop header, // which is hard, especially if the OSR is into a nested loop. Doing all // that would produce slightly more optimal code, but this is so // extraordinarily rare that it isn't worth the complexity. MBasicBlock* fake = MBasicBlock::New(graph_, block->info(), nullptr, MBasicBlock::NORMAL); if (fake == nullptr) return false; graph_.insertBlockBefore(block, fake); fake->setImmediateDominator(fake); fake->addNumDominated(1); fake->setDomIndex(fake->id()); fake->setUnreachable(); // Create zero-input phis to use as inputs for any phis in |block|. // Again, this is a little odd, but it's the least-odd thing we can do // without significant complexity. for (MPhiIterator iter(block->phisBegin()), end(block->phisEnd()); iter != end; ++iter) { MPhi* phi = *iter; MPhi* fakePhi = MPhi::New(graph_.alloc(), phi->type()); fake->addPhi(fakePhi); if (!phi->addInputSlow(fakePhi)) return false; } fake->end(MGoto::New(graph_.alloc(), block)); if (!block->addPredecessorWithoutPhis(fake)) return false; // Restore |backedge| as |block|'s loop backedge. block->clearLoopHeader(); block->setLoopHeader(backedge); JitSpew(JitSpew_GVN, " Created fake block%u", fake->id()); hasOSRFixups_ = true; return true; }