Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
MBasicBlock *
MBasicBlock::NewPopN(MIRGraph &graph, CompileInfo &info,
                     MBasicBlock *pred, jsbytecode *entryPc, Kind kind, uint32_t popped)
{
    MBasicBlock *block = new MBasicBlock(graph, info, entryPc, kind);
    if (!block->init())
        return NULL;

    if (!block->inherit(pred, popped))
        return NULL;

    return block;
}
Example #4
0
MBasicBlock *
MBasicBlock::NewPopN(MIRGraph &graph, CompileInfo &info,
                     MBasicBlock *pred, const BytecodeSite &site, Kind kind, uint32_t popped)
{
    MBasicBlock *block = new(graph.alloc()) MBasicBlock(graph, info, site, kind);
    if (!block->init())
        return nullptr;

    if (!block->inherit(graph.alloc(), nullptr, pred, popped))
        return nullptr;

    return block;
}
Example #5
0
MBasicBlock *
MBasicBlock::New(MIRGraph &graph, CompileInfo &info,
                 MBasicBlock *pred, jsbytecode *entryPc, Kind kind)
{
    JS_ASSERT(entryPc != NULL);

    MBasicBlock *block = new MBasicBlock(graph, info, entryPc, kind);
    if (!block->init())
        return NULL;

    if (!block->inherit(pred, 0))
        return NULL;

    return block;
}
Example #6
0
MBasicBlock *
MBasicBlock::New(MIRGraph &graph, BytecodeAnalysis *analysis, CompileInfo &info,
                 MBasicBlock *pred, const BytecodeSite &site, Kind kind)
{
    JS_ASSERT(site.pc() != nullptr);

    MBasicBlock *block = new(graph.alloc()) MBasicBlock(graph, info, site, kind);
    if (!block->init())
        return nullptr;

    if (!block->inherit(graph.alloc(), analysis, pred, 0))
        return nullptr;

    return block;
}
Example #7
0
MBasicBlock*
MBasicBlock::New(MIRGraph& graph, size_t stackDepth, const CompileInfo& info,
                 MBasicBlock* maybePred, BytecodeSite* site, Kind kind)
{
    MOZ_ASSERT(site->pc() != nullptr);

    MBasicBlock* block = new(graph.alloc()) MBasicBlock(graph, info, site, kind);
    if (!block->init())
        return nullptr;

    if (!block->inherit(graph.alloc(), stackDepth, maybePred, 0))
        return nullptr;

    return block;
}
Example #8
0
MBasicBlock *
MBasicBlock::New(MIRGraph &graph, BytecodeAnalysis *analysis, CompileInfo &info,
                 MBasicBlock *pred, jsbytecode *entryPc, Kind kind)
{
    JS_ASSERT(entryPc != nullptr);

    MBasicBlock *block = new MBasicBlock(graph, info, entryPc, kind);
    if (!block->init())
        return nullptr;

    if (!block->inherit(analysis, pred, 0))
        return nullptr;

    return block;
}
Example #9
0
MBasicBlock *
MBasicBlock::NewPendingLoopHeader(MIRGraph &graph, CompileInfo &info,
                                  MBasicBlock *pred, const BytecodeSite &site,
                                  unsigned stackPhiCount)
{
    JS_ASSERT(site.pc() != nullptr);

    MBasicBlock *block = new(graph.alloc()) MBasicBlock(graph, info, site, PENDING_LOOP_HEADER);
    if (!block->init())
        return nullptr;

    if (!block->inherit(graph.alloc(), nullptr, pred, 0, stackPhiCount))
        return nullptr;

    return block;
}
Example #10
0
MBasicBlock *
MBasicBlock::NewWithResumePoint(MIRGraph &graph, CompileInfo &info,
                                MBasicBlock *pred, jsbytecode *entryPc,
                                MResumePoint *resumePoint)
{
    MBasicBlock *block = new MBasicBlock(graph, info, entryPc, NORMAL);

    resumePoint->block_ = block;
    block->entryResumePoint_ = resumePoint;

    if (!block->init())
        return NULL;

    if (!block->inheritResumePoint(pred))
        return NULL;

    return block;
}
Example #11
0
MBasicBlock *
MBasicBlock::NewWithResumePoint(MIRGraph &graph, CompileInfo &info,
                                MBasicBlock *pred, const BytecodeSite &site,
                                MResumePoint *resumePoint)
{
    MBasicBlock *block = new(graph.alloc()) MBasicBlock(graph, info, site, NORMAL);

    resumePoint->block_ = block;
    block->entryResumePoint_ = resumePoint;

    if (!block->init())
        return nullptr;

    if (!block->inheritResumePoint(pred))
        return nullptr;

    return block;
}
Example #12
0
MBasicBlock *
MBasicBlock::NewAbortPar(MIRGraph &graph, CompileInfo &info,
                         MBasicBlock *pred, jsbytecode *entryPc,
                         MResumePoint *resumePoint)
{
    MBasicBlock *block = new MBasicBlock(graph, info, entryPc, NORMAL);

    resumePoint->block_ = block;
    block->entryResumePoint_ = resumePoint;

    if (!block->init())
        return NULL;

    if (!block->addPredecessorWithoutPhis(pred))
        return NULL;

    block->end(new MAbortPar());
    return block;
}
Example #13
0
MBasicBlock *
MBasicBlock::NewAbortPar(MIRGraph &graph, CompileInfo &info,
                         MBasicBlock *pred, const BytecodeSite &site,
                         MResumePoint *resumePoint)
{
    MBasicBlock *block = new(graph.alloc()) MBasicBlock(graph, info, site, NORMAL);

    resumePoint->block_ = block;
    block->entryResumePoint_ = resumePoint;

    if (!block->init())
        return nullptr;

    if (!block->addPredecessorWithoutPhis(pred))
        return nullptr;

    block->end(MAbortPar::New(graph.alloc()));
    return block;
}
Example #14
0
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;
}
Example #15
0
MBasicBlock*
MBasicBlock::NewWithResumePoint(MIRGraph& graph, CompileInfo& info,
                                MBasicBlock* pred, BytecodeSite* site,
                                MResumePoint* resumePoint)
{
    MBasicBlock* block = new(graph.alloc()) MBasicBlock(graph, info, site, NORMAL);

    MOZ_ASSERT(!resumePoint->instruction());
    resumePoint->block()->discardResumePoint(resumePoint, RefType_None);
    resumePoint->block_ = block;
    block->addResumePoint(resumePoint);
    block->entryResumePoint_ = resumePoint;

    if (!block->init())
        return nullptr;

    if (!block->inheritResumePoint(pred))
        return nullptr;

    return block;
}
Example #16
0
MBasicBlock*
MBasicBlock::NewSplitEdge(MIRGraph& graph, MBasicBlock* pred, size_t predEdgeIdx, MBasicBlock* succ)
{
    MBasicBlock* split = nullptr;
    if (!succ->pc()) {
        // The predecessor does not have a PC, this is a Wasm compilation.
        split = MBasicBlock::New(graph, succ->info(), pred, SPLIT_EDGE);
        if (!split)
            return nullptr;
    } else {
        // The predecessor has a PC, this is an IonBuilder compilation.
        MResumePoint* succEntry = succ->entryResumePoint();

        BytecodeSite* site = new(graph.alloc()) BytecodeSite(succ->trackedTree(), succEntry->pc());
        split = new(graph.alloc()) MBasicBlock(graph, succ->info(), site, SPLIT_EDGE);

        if (!split->init())
            return nullptr;

        // A split edge is used to simplify the graph to avoid having a
        // predecessor with multiple successors as well as a successor with
        // multiple predecessors.  As instructions can be moved in this
        // split-edge block, we need to give this block a resume point. To do
        // so, we copy the entry resume points of the successor and filter the
        // phis to keep inputs from the current edge.

        // Propagate the caller resume point from the inherited block.
        split->callerResumePoint_ = succ->callerResumePoint();

        // Split-edge are created after the interpreter stack emulation. Thus,
        // there is no need for creating slots.
        split->stackPosition_ = succEntry->stackDepth();

        // Create a resume point using our initial stack position.
        MResumePoint* splitEntry = new(graph.alloc()) MResumePoint(split, succEntry->pc(),
                                                                   MResumePoint::ResumeAt);
        if (!splitEntry->init(graph.alloc()))
            return nullptr;
        split->entryResumePoint_ = splitEntry;

        // The target entry resume point might have phi operands, keep the
        // operands of the phi coming from our edge.
        size_t succEdgeIdx = succ->indexForPredecessor(pred);

        for (size_t i = 0, e = splitEntry->numOperands(); i < e; i++) {
            MDefinition* def = succEntry->getOperand(i);
            // This early in the pipeline, we have no recover instructions in
            // any entry resume point.
            MOZ_ASSERT_IF(def->block() == succ, def->isPhi());
            if (def->block() == succ)
                def = def->toPhi()->getOperand(succEdgeIdx);

            splitEntry->initOperand(i, def);
        }

        // This is done in the New variant for wasm, so we cannot keep this
        // line below, where the rest of the graph is modified.
        if (!split->predecessors_.append(pred))
            return nullptr;
    }

    split->setLoopDepth(succ->loopDepth());

    // Insert the split edge block in-between.
    split->end(MGoto::New(graph.alloc(), succ));

    graph.insertBlockAfter(pred, split);

    pred->replaceSuccessor(predEdgeIdx, split);
    succ->replacePredecessor(pred, split);
    return split;
}