MBasicBlock * MBasicBlock::NewAsmJS(MIRGraph &graph, CompileInfo &info, MBasicBlock *pred, Kind kind) { MBasicBlock *block = new MBasicBlock(graph, info, /* entryPC = */ NULL, kind); if (!block->init()) return NULL; if (pred) { block->stackPosition_ = pred->stackPosition_; if (block->kind_ == PENDING_LOOP_HEADER) { for (size_t i = 0; i < block->stackPosition_; i++) { MDefinition *predSlot = pred->getSlot(i); JS_ASSERT(predSlot->type() != MIRType_Value); MPhi *phi = MPhi::New(i, predSlot->type()); JS_ALWAYS_TRUE(phi->reserveLength(2)); phi->addInput(predSlot); block->addPhi(phi); block->setSlot(i, phi); } } else { block->copySlots(pred); } if (!block->predecessors_.append(pred)) return NULL; } return block; }
MBasicBlock* MBasicBlock::New(MIRGraph& graph, const CompileInfo& info, MBasicBlock* pred, Kind kind) { BytecodeSite* site = new(graph.alloc()) BytecodeSite(); MBasicBlock* block = new(graph.alloc()) MBasicBlock(graph, info, site, kind); if (!block->init()) return nullptr; if (pred) { block->stackPosition_ = pred->stackPosition_; if (block->kind_ == PENDING_LOOP_HEADER) { size_t nphis = block->stackPosition_; size_t nfree = graph.phiFreeListLength(); TempAllocator& alloc = graph.alloc(); MPhi* phis = nullptr; if (nphis > nfree) { phis = alloc.allocateArray<MPhi>(nphis - nfree); if (!phis) return nullptr; } // Note: Phis are inserted in the same order as the slots. for (size_t i = 0; i < nphis; i++) { MDefinition* predSlot = pred->getSlot(i); MOZ_ASSERT(predSlot->type() != MIRType::Value); MPhi* phi; if (i < nfree) phi = graph.takePhiFromFreeList(); else phi = phis + (i - nfree); new(phi) MPhi(alloc, predSlot->type()); phi->addInlineInput(predSlot); // Add append Phis in the block. block->addPhi(phi); block->setSlot(i, phi); } } else { block->copySlots(pred); } if (!block->predecessors_.append(pred)) return nullptr; } return block; }
// 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; }
MBasicBlock * MBasicBlock::NewAsmJS(MIRGraph &graph, CompileInfo &info, MBasicBlock *pred, Kind kind) { MBasicBlock *block = new(graph.alloc()) MBasicBlock(graph, info, BytecodeSite(), kind); if (!block->init()) return nullptr; if (pred) { block->stackPosition_ = pred->stackPosition_; if (block->kind_ == PENDING_LOOP_HEADER) { size_t nphis = block->stackPosition_; TempAllocator &alloc = graph.alloc(); MPhi *phis = (MPhi*)alloc.allocateArray<sizeof(MPhi)>(nphis); if (!phis) return nullptr; // Note: Phis are inserted in the same order as the slots. for (size_t i = 0; i < nphis; i++) { MDefinition *predSlot = pred->getSlot(i); JS_ASSERT(predSlot->type() != MIRType_Value); MPhi *phi = new(phis + i) MPhi(alloc, predSlot->type()); JS_ALWAYS_TRUE(phi->reserveLength(2)); phi->addInput(predSlot); // Add append Phis in the block. block->addPhi(phi); block->setSlot(i, phi); } } else { block->copySlots(pred); } if (!block->predecessors_.append(pred)) return nullptr; } return block; }