示例#1
0
// Remove the CFG edge between |pred| and |block|, after releasing the phi
// operands on that edge and discarding any definitions consequently made dead.
bool
ValueNumberer::removePredecessorAndDoDCE(MBasicBlock* block, MBasicBlock* pred, size_t predIndex)
{
    MOZ_ASSERT(!block->isMarked(),
               "Block marked unreachable should have predecessors removed already");

    // Before removing the predecessor edge, scan the phi operands for that edge
    // for dead code before they get removed.
    MOZ_ASSERT(nextDef_ == nullptr);
    for (MPhiIterator iter(block->phisBegin()), end(block->phisEnd()); iter != end; ) {
        MPhi* phi = *iter++;
        MOZ_ASSERT(!values_.has(phi), "Visited phi in block having predecessor removed");
        MOZ_ASSERT(!phi->isGuard());

        MDefinition* op = phi->getOperand(predIndex);
        phi->removeOperand(predIndex);

        nextDef_ = iter != end ? *iter : nullptr;
        if (!handleUseReleased(op, DontSetUseRemoved) || !processDeadDefs())
            return false;

        // If |nextDef_| became dead while we had it pinned, advance the
        // iterator and discard it now.
        while (nextDef_ && !nextDef_->hasUses() && !nextDef_->isGuardRangeBailouts()) {
            phi = nextDef_->toPhi();
            iter++;
            nextDef_ = iter != end ? *iter : nullptr;
            if (!discardDefsRecursively(phi))
                return false;
        }
    }
    nextDef_ = nullptr;

    block->removePredecessorWithoutPhiOperands(pred, predIndex);
    return true;
}