diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index d86e311a44bc..b7a01387fd64 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -4682,7 +4682,13 @@ LIRGenerator::updateResumeState(MInstruction* ins) void LIRGenerator::updateResumeState(MBasicBlock* block) { - MOZ_ASSERT_IF(!mir()->compilingAsmJS(), block->entryResumePoint()); + // As Value Numbering phase can remove edges from the entry basic block to a + // code paths reachable from the OSR entry point, we have to add fixup + // blocks to keep the dominator tree organized the same way. These fixup + // blocks are flaged as unreachable, and should only exist iff the graph has + // an OSR block. + MOZ_ASSERT_IF(!mir()->compilingAsmJS() && !block->unreachable(), block->entryResumePoint()); + MOZ_ASSERT_IF(block->unreachable(), block->graph().osrBlock()); lastResumePoint_ = block->entryResumePoint(); if (JitSpewEnabled(JitSpew_IonSnapshots) && lastResumePoint_) SpewResumePoint(block, nullptr, lastResumePoint_); @@ -4696,6 +4702,10 @@ LIRGenerator::visitBlock(MBasicBlock* block) definePhis(); + // See fixup blocks added by Value Numbering, to keep the dominator relation + // modified by the presence of the OSR block. + MOZ_ASSERT_IF(block->unreachable(), *block->begin() == block->lastIns()); + MOZ_ASSERT_IF(block->unreachable(), block->graph().osrBlock()); for (MInstructionIterator iter = block->begin(); *iter != block->lastIns(); iter++) { if (!visitInstruction(*iter)) return false; diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp index 969e17d16a2c..983ad35f5c94 100644 --- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -2275,13 +2275,16 @@ RangeAnalysis::analyze() for (ReversePostorderIterator iter(graph_.rpoBegin()); iter != graph_.rpoEnd(); iter++) { MBasicBlock* block = *iter; - MOZ_ASSERT(!block->unreachable()); + // No blocks are supposed to be unreachable, except when we have an OSR + // block, in which case the Value Numbering phase add fixup blocks which + // are unreachable. + MOZ_ASSERT(!block->unreachable() || graph_.osrBlock()); // If the block's immediate dominator is unreachable, the block is // unreachable. Iterating in RPO, we'll always see the immediate // dominator before the block. if (block->immediateDominator()->unreachable()) { - block->setUnreachable(); + block->setUnreachableUnchecked(); continue; } @@ -3430,6 +3433,15 @@ RangeAnalysis::prepareForUCE(bool* shouldRemoveDeadCode) if (!block->unreachable()) continue; + // Filter out unreachable fake entries. + if (block->numPredecessors() == 0) { + // Ignore fixup blocks added by the Value Numbering phase, in order + // to keep the dominator tree as-is when we have OSR Block which are + // no longer reachable from the main entry point of the graph. + MOZ_ASSERT(graph_.osrBlock()); + continue; + } + MControlInstruction* cond = block->getPredecessor(0)->lastIns(); if (!cond->isTest()) continue; diff --git a/js/src/jit/ValueNumbering.cpp b/js/src/jit/ValueNumbering.cpp index b9bad2944c07..d51c6f374e96 100644 --- a/js/src/jit/ValueNumbering.cpp +++ b/js/src/jit/ValueNumbering.cpp @@ -440,6 +440,7 @@ ValueNumberer::fixupOSROnlyLoop(MBasicBlock* block, MBasicBlock* backedge) 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