当前位置: 首页>>代码示例>>C++>>正文


C++ MInstruction::resumePoint方法代码示例

本文整理汇总了C++中MInstruction::resumePoint方法的典型用法代码示例。如果您正苦于以下问题:C++ MInstruction::resumePoint方法的具体用法?C++ MInstruction::resumePoint怎么用?C++ MInstruction::resumePoint使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在MInstruction的用法示例。


在下文中一共展示了MInstruction::resumePoint方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: JitSpew

// Discard |def| and mine its operands for any subsequently dead defs.
bool
ValueNumberer::discardDef(MDefinition* def)
{
#ifdef JS_JITSPEW
    JitSpew(JitSpew_GVN, "      Discarding %s %s%u",
            def->block()->isMarked() ? "unreachable" : "dead",
            def->opName(), def->id());
#endif
#ifdef DEBUG
    MOZ_ASSERT(def != nextDef_, "Invalidating the MDefinition iterator");
    if (def->block()->isMarked()) {
        MOZ_ASSERT(!def->hasUses(), "Discarding def that still has uses");
    } else {
        MOZ_ASSERT(IsDiscardable(def), "Discarding non-discardable definition");
        MOZ_ASSERT(!values_.has(def), "Discarding a definition still in the set");
    }
#endif

    MBasicBlock* block = def->block();
    if (def->isPhi()) {
        MPhi* phi = def->toPhi();
        if (!releaseAndRemovePhiOperands(phi))
             return false;
        block->discardPhi(phi);
    } else {
        MInstruction* ins = def->toInstruction();
        if (MResumePoint* resume = ins->resumePoint()) {
            if (!releaseResumePointOperands(resume))
                return false;
        }
        if (!releaseOperands(ins))
             return false;
        block->discardIgnoreOperands(ins);
    }

    // If that was the last definition in the block, it can be safely removed
    // from the graph.
    if (block->phisEmpty() && block->begin() == block->end()) {
        MOZ_ASSERT(block->isMarked(), "Reachable block lacks at least a control instruction");

        // As a special case, don't remove a block which is a dominator tree
        // root so that we don't invalidate the iterator in visitGraph. We'll
        // check for this and remove it later.
        if (block->immediateDominator() != block) {
            JitSpew(JitSpew_GVN, "      Block block%u is now empty; discarding", block->id());
            graph_.removeBlock(block);
            blocksRemoved_ = true;
        } else {
            JitSpew(JitSpew_GVN, "      Dominator root block%u is now empty; will discard later",
                    block->id());
        }
    }

    return true;
}
开发者ID:subsevenx2001,项目名称:gecko-dev,代码行数:56,代码来源:ValueNumbering.cpp

示例2: operands


//.........这里部分代码省略.........
            // of the uses and the original instruction. This prevent moving the
            // computation of the arguments into an inline function if there is
            // no major win.
            MBasicBlock* lastJoin = usesDominator;
            while (*block != lastJoin && lastJoin->numPredecessors() == 1) {
                MOZ_ASSERT(lastJoin != lastJoin->immediateDominator());
                MBasicBlock* next = lastJoin->immediateDominator();
                if (next->numSuccessors() > 1)
                    break;
                lastJoin = next;
            }
            if (*block == lastJoin)
                continue;

            // Skip to the next instruction if we cannot find a common dominator
            // for all the uses of this instruction, or if the common dominator
            // correspond to the block of the current instruction.
            if (!usesDominator || usesDominator == *block)
                continue;

            // Only instruction which can be recovered on bailout and which are
            // sinkable can be moved into blocks which are below while filling
            // the resume points with a clone which is recovered on bailout.

            // If the instruction has live uses and if it is clonable, then we
            // can clone the instruction for all non-dominated uses and move the
            // instruction into the block which is dominating all live uses.
            if (!ins->canClone())
                continue;

            // If the block is a split-edge block, which is created for folding
            // test conditions, then the block has no resume point and has
            // multiple predecessors.  In such case, we cannot safely move
            // bailing instruction to these blocks as we have no way to bailout.
            if (!usesDominator->entryResumePoint() && usesDominator->numPredecessors() != 1)
                continue;

            JitSpewDef(JitSpew_Sink, "  Can Clone & Recover, sink instruction\n", ins);
            JitSpew(JitSpew_Sink, "  into Block %u", usesDominator->id());

            // Copy the arguments and clone the instruction.
            MDefinitionVector operands(alloc);
            for (size_t i = 0, end = ins->numOperands(); i < end; i++) {
                if (!operands.append(ins->getOperand(i)))
                    return false;
            }

            MInstruction* clone = ins->clone(alloc, operands);
            ins->block()->insertBefore(ins, clone);
            clone->setRecoveredOnBailout();

            // We should not update the producer of the entry resume point, as
            // it cannot refer to any instruction within the basic block excepts
            // for Phi nodes.
            MResumePoint* entry = usesDominator->entryResumePoint();

            // Replace the instruction by its clone in all the resume points /
            // recovered-on-bailout instructions which are not in blocks which
            // are dominated by the usesDominator block.
            for (MUseIterator i(ins->usesBegin()), e(ins->usesEnd()); i != e; ) {
                MUse* use = *i++;
                MNode* consumer = use->consumer();

                // If the consumer is a Phi, then we look for the index of the
                // use to find the corresponding predecessor block, which is
                // then used as the consumer block.
                MBasicBlock* consumerBlock = consumer->block();
                if (consumer->isDefinition() && consumer->toDefinition()->isPhi()) {
                    consumerBlock = consumerBlock->getPredecessor(
                        consumer->toDefinition()->toPhi()->indexOf(use));
                }

                // Keep the current instruction for all dominated uses, except
                // for the entry resume point of the block in which the
                // instruction would be moved into.
                if (usesDominator->dominates(consumerBlock) &&
                    (!consumer->isResumePoint() || consumer->toResumePoint() != entry))
                {
                    continue;
                }

                use->replaceProducer(clone);
            }

            // As we move this instruction in a different block, we should
            // verify that we do not carry over a resume point which would refer
            // to an outdated state of the control flow.
            if (ins->resumePoint())
                ins->clearResumePoint();

            // Now, that all uses which are not dominated by usesDominator are
            // using the cloned instruction, we can safely move the instruction
            // into the usesDominator block.
            MInstruction* at = usesDominator->safeInsertTop(nullptr, MBasicBlock::IgnoreRecover);
            block->moveBefore(at, ins);
        }
    }

    return true;
}
开发者ID:AlexOreshkevich,项目名称:mongo,代码行数:101,代码来源:Sink.cpp

示例3: JitSpew

// Remove the CFG edge between |pred| and |block|, and if this makes |block|
// unreachable, mark it so, and remove the rest of its incoming edges too. And
// discard any instructions made dead by the entailed release of any phi
// operands.
bool
ValueNumberer::removePredecessorAndCleanUp(MBasicBlock* block, MBasicBlock* pred)
{
    MOZ_ASSERT(!block->isMarked(), "Removing predecessor on block already marked unreachable");

    // We'll be removing a predecessor, so anything we know about phis in this
    // block will be wrong.
    for (MPhiIterator iter(block->phisBegin()), end(block->phisEnd()); iter != end; ++iter)
        values_.forget(*iter);

    // If this is a loop header, test whether it will become an unreachable
    // loop, or whether it needs special OSR-related fixups.
    bool isUnreachableLoop = false;
    MBasicBlock* origBackedgeForOSRFixup = nullptr;
    if (block->isLoopHeader()) {
        if (block->loopPredecessor() == pred) {
            if (MOZ_UNLIKELY(hasNonDominatingPredecessor(block, pred))) {
                JitSpew(JitSpew_GVN, "      "
                        "Loop with header block%u is now only reachable through an "
                        "OSR entry into the middle of the loop!!", block->id());
                origBackedgeForOSRFixup = block->backedge();
            } else {
                // Deleting the entry into the loop makes the loop unreachable.
                isUnreachableLoop = true;
                JitSpew(JitSpew_GVN, "      "
                        "Loop with header block%u is no longer reachable",
                        block->id());
            }
#ifdef DEBUG
        } else if (block->hasUniqueBackedge() && block->backedge() == pred) {
            JitSpew(JitSpew_GVN, "      Loop with header block%u is no longer a loop",
                    block->id());
#endif
        }
    }

    // Actually remove the CFG edge.
    if (!removePredecessorAndDoDCE(block, pred, block->getPredecessorIndex(pred)))
        return false;

    // We've now edited the CFG; check to see if |block| became unreachable.
    if (block->numPredecessors() == 0 || isUnreachableLoop) {
        JitSpew(JitSpew_GVN, "      Disconnecting block%u", block->id());

        // Remove |block| from its dominator parent's subtree. This is the only
        // immediately-dominated-block information we need to update, because
        // everything dominated by this block is about to be swept away.
        MBasicBlock* parent = block->immediateDominator();
        if (parent != block)
            parent->removeImmediatelyDominatedBlock(block);

        // Completely disconnect it from the CFG. We do this now rather than
        // just doing it later when we arrive there in visitUnreachableBlock
        // so that we don't leave a partially broken loop sitting around. This
        // also lets visitUnreachableBlock assert that numPredecessors() == 0,
        // which is a nice invariant.
        if (block->isLoopHeader())
            block->clearLoopHeader();
        for (size_t i = 0, e = block->numPredecessors(); i < e; ++i) {
            if (!removePredecessorAndDoDCE(block, block->getPredecessor(i), i))
                return false;
        }

        // Clear out the resume point operands, as they can hold things that
        // don't appear to dominate them live.
        if (MResumePoint* resume = block->entryResumePoint()) {
            if (!releaseResumePointOperands(resume) || !processDeadDefs())
                return false;
            if (MResumePoint* outer = block->outerResumePoint()) {
                if (!releaseResumePointOperands(outer) || !processDeadDefs())
                    return false;
            }
            MOZ_ASSERT(nextDef_ == nullptr);
            for (MInstructionIterator iter(block->begin()), end(block->end()); iter != end; ) {
                MInstruction* ins = *iter++;
                nextDef_ = *iter;
                if (MResumePoint* resume = ins->resumePoint()) {
                    if (!releaseResumePointOperands(resume) || !processDeadDefs())
                        return false;
                }
            }
            nextDef_ = nullptr;
        } else {
#ifdef DEBUG
            MOZ_ASSERT(block->outerResumePoint() == nullptr,
                       "Outer resume point in block without an entry resume point");
            for (MInstructionIterator iter(block->begin()), end(block->end());
                 iter != end;
                 ++iter)
            {
                MOZ_ASSERT(iter->resumePoint() == nullptr,
                           "Instruction with resume point in block without entry resume point");
            }
#endif
        }

//.........这里部分代码省略.........
开发者ID:JackWangCUMT,项目名称:eventql,代码行数:101,代码来源:ValueNumbering.cpp

示例4: while

bool
jit::ReorderInstructions(MIRGraph& graph)
{
    // Renumber all instructions in the graph as we go.
    size_t nextId = 0;

    // List of the headers of any loops we are in.
    Vector<MBasicBlock*, 4, SystemAllocPolicy> loopHeaders;

    for (ReversePostorderIterator block(graph.rpoBegin()); block != graph.rpoEnd(); block++) {
        // Renumber all definitions inside the basic blocks.
        for (MPhiIterator iter(block->phisBegin()); iter != block->phisEnd(); iter++)
            iter->setId(nextId++);

        for (MInstructionIterator iter(block->begin()); iter != block->end(); iter++)
            iter->setId(nextId++);

        // Don't reorder instructions within entry blocks, which have special requirements.
        if (*block == graph.entryBlock() || *block == graph.osrBlock())
            continue;

        if (block->isLoopHeader()) {
            if (!loopHeaders.append(*block))
                return false;
        }

        MBasicBlock* innerLoop = loopHeaders.empty() ? nullptr : loopHeaders.back();

        MInstruction* top = block->safeInsertTop();
        MInstructionReverseIterator rtop = ++block->rbegin(top);
        for (MInstructionIterator iter(block->begin(top)); iter != block->end(); ) {
            MInstruction* ins = *iter;

            // Filter out some instructions which are never reordered.
            if (ins->isEffectful() ||
                !ins->isMovable() ||
                ins->resumePoint() ||
                ins == block->lastIns())
            {
                iter++;
                continue;
            }

            // Move constants with a single use in the current block to the
            // start of the block. Constants won't be reordered by the logic
            // below, as they have no inputs. Moving them up as high as
            // possible can allow their use to be moved up further, though,
            // and has no cost if the constant is emitted at its use.
            if (ins->isConstant() &&
                ins->hasOneUse() &&
                ins->usesBegin()->consumer()->block() == *block &&
                !IsFloatingPointType(ins->type()))
            {
                iter++;
                MInstructionIterator targetIter = block->begin();
                while (targetIter->isConstant() || targetIter->isInterruptCheck()) {
                    if (*targetIter == ins)
                        break;
                    targetIter++;
                }
                MoveBefore(*block, *targetIter, ins);
                continue;
            }

            // Look for inputs where this instruction is the last use of that
            // input. If we move this instruction up, the input's lifetime will
            // be shortened, modulo resume point uses (which don't need to be
            // stored in a register, and can be handled by the register
            // allocator by just spilling at some point with no reload).
            Vector<MDefinition*, 4, SystemAllocPolicy> lastUsedInputs;
            for (size_t i = 0; i < ins->numOperands(); i++) {
                MDefinition* input = ins->getOperand(i);
                if (!input->isConstant() && IsLastUse(ins, input, innerLoop)) {
                    if (!lastUsedInputs.append(input))
                        return false;
                }
            }

            // Don't try to move instructions which aren't the last use of any
            // of their inputs (we really ought to move these down instead).
            if (lastUsedInputs.length() < 2) {
                iter++;
                continue;
            }

            MInstruction* target = ins;
            for (MInstructionReverseIterator riter = ++block->rbegin(ins); riter != rtop; riter++) {
                MInstruction* prev = *riter;
                if (prev->isInterruptCheck())
                    break;

                // The instruction can't be moved before any of its uses.
                bool isUse = false;
                for (size_t i = 0; i < ins->numOperands(); i++) {
                    if (ins->getOperand(i) == prev) {
                        isUse = true;
                        break;
                    }
                }
                if (isUse)
//.........这里部分代码省略.........
开发者ID:acmorrow,项目名称:mongo,代码行数:101,代码来源:InstructionReordering.cpp


注:本文中的MInstruction::resumePoint方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。