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


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

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


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

示例1: JitSpew

// Visit |def|.
bool
ValueNumberer::visitDefinition(MDefinition* def)
{
    // Nop does not fit in any of the previous optimization, as its only purpose
    // is to reduce the register pressure by keeping additional resume
    // point. Still, there is no need consecutive list of MNop instructions, and
    // this will slow down every other iteration on the Graph.
    if (def->isNop()) {
        MNop* nop = def->toNop();
        MBasicBlock* block = nop->block();

        // We look backward to know if we can remove the previous Nop, we do not
        // look forward as we would not benefit from the folding made by GVN.
        MInstructionReverseIterator iter = ++block->rbegin(nop);

        // This nop is at the beginning of the basic block, just replace the
        // resume point of the basic block by the one from the resume point.
        if (iter == block->rend()) {
            JitSpew(JitSpew_GVN, "      Removing Nop%u", nop->id());
            nop->moveResumePointAsEntry();
            block->discard(nop);
            return true;
        }

        // The previous instruction is also a Nop, no need to keep it anymore.
        MInstruction* prev = *iter;
        if (prev->isNop()) {
            JitSpew(JitSpew_GVN, "      Removing Nop%u", prev->id());
            block->discard(prev);
            return true;
        }

        // The Nop is introduced to capture the result and make sure the operands
        // are not live anymore when there are no further uses. Though when
        // all operands are still needed the Nop doesn't decrease the liveness
        // and can get removed.
        MResumePoint* rp = nop->resumePoint();
        if (rp && rp->numOperands() > 0 &&
            rp->getOperand(rp->numOperands() - 1) == prev &&
            !nop->block()->lastIns()->isThrow())
        {
            size_t numOperandsLive = 0;
            for (size_t j = 0; j < prev->numOperands(); j++) {
                for (size_t i = 0; i < rp->numOperands(); i++) {
                    if (prev->getOperand(j) == rp->getOperand(i)) {
                        numOperandsLive++;
                        break;
                    }
                }
            }

            if (numOperandsLive == prev->numOperands()) {
                JitSpew(JitSpew_GVN, "      Removing Nop%u", nop->id());
                block->discard(nop);
            }
        }

        return true;
    }

    // Skip optimizations on instructions which are recovered on bailout, to
    // avoid mixing instructions which are recovered on bailouts with
    // instructions which are not.
    if (def->isRecoveredOnBailout())
        return true;

    // If this instruction has a dependency() into an unreachable block, we'll
    // need to update AliasAnalysis.
    MDefinition* dep = def->dependency();
    if (dep != nullptr && (dep->isDiscarded() || dep->block()->isDead())) {
        JitSpew(JitSpew_GVN, "      AliasAnalysis invalidated");
        if (updateAliasAnalysis_ && !dependenciesBroken_) {
            // TODO: Recomputing alias-analysis could theoretically expose more
            // GVN opportunities.
            JitSpew(JitSpew_GVN, "        Will recompute!");
            dependenciesBroken_ = true;
        }
        // Temporarily clear its dependency, to protect foldsTo, which may
        // wish to use the dependency to do store-to-load forwarding.
        def->setDependency(def->toInstruction());
    } else {
        dep = nullptr;
    }

    // Look for a simplified form of |def|.
    MDefinition* sim = simplified(def);
    if (sim != def) {
        if (sim == nullptr)
            return false;

        bool isNewInstruction = sim->block() == nullptr;

        // If |sim| doesn't belong to a block, insert it next to |def|.
        if (isNewInstruction)
            def->block()->insertAfter(def->toInstruction(), sim->toInstruction());

#ifdef JS_JITSPEW
        JitSpew(JitSpew_GVN, "      Folded %s%u to %s%u",
                def->opName(), def->id(), sim->opName(), sim->id());
//.........这里部分代码省略.........
开发者ID:subsevenx2001,项目名称:gecko-dev,代码行数:101,代码来源: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: 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::numOperands方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。