Esempio n. 1
0
void
MBasicBlock::inheritPhis(MBasicBlock* header)
{
    MResumePoint* headerRp = header->entryResumePoint();
    size_t stackDepth = headerRp->stackDepth();
    for (size_t slot = 0; slot < stackDepth; slot++) {
        MDefinition* exitDef = getSlot(slot);
        MDefinition* loopDef = headerRp->getOperand(slot);
        if (loopDef->block() != header) {
            MOZ_ASSERT(loopDef->block()->id() < header->id());
            MOZ_ASSERT(loopDef == exitDef);
            continue;
        }

        // Phis are allocated by NewPendingLoopHeader.
        MPhi* phi = loopDef->toPhi();
        MOZ_ASSERT(phi->numOperands() == 2);

        // The entry definition is always the leftmost input to the phi.
        MDefinition* entryDef = phi->getOperand(0);

        if (entryDef != exitDef)
            continue;

        // If the entryDef is the same as exitDef, then we must propagate the
        // phi down to this successor. This chance was missed as part of
        // setBackedge() because exits are not captured in resume points.
        setSlot(slot, phi);
    }
}
Esempio n. 2
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;
}