本文整理汇总了C++中MDefinition::isDiscarded方法的典型用法代码示例。如果您正苦于以下问题:C++ MDefinition::isDiscarded方法的具体用法?C++ MDefinition::isDiscarded怎么用?C++ MDefinition::isDiscarded使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类MDefinition
的用法示例。
在下文中一共展示了MDefinition::isDiscarded方法的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: JitSpew
// If an equivalent and dominating value already exists in the set, return it.
// Otherwise insert |def| into the set and return it.
MDefinition*
ValueNumberer::leader(MDefinition* def)
{
// If the value isn't suitable for eliminating, don't bother hashing it. The
// convention is that congruentTo returns false for node kinds that wish to
// opt out of redundance elimination.
// TODO: It'd be nice to clean up that convention (bug 1031406).
if (!def->isEffectful() && def->congruentTo(def)) {
// Look for a match.
VisibleValues::AddPtr p = values_.findLeaderForAdd(def);
if (p) {
MDefinition* rep = *p;
if (!rep->isDiscarded() && rep->block()->dominates(def->block())) {
// We found a dominating congruent value.
return rep;
}
// The congruent value doesn't dominate. It never will again in this
// dominator tree, so overwrite it.
values_.overwrite(p, def);
} else {
// No match. Add a new entry.
if (!values_.add(p, def))
return nullptr;
}
#ifdef DEBUG
JitSpew(JitSpew_GVN, " Recording %s%u", def->opName(), def->id());
#endif
}
return def;
}
示例2:
// Assuming |resume| is unreachable, release its operands.
// It might be nice to integrate this code with prepareForDiscard, however GVN
// needs it to call handleUseReleased so that it can observe when a definition
// becomes unused, so it isn't trivial to do.
bool
ValueNumberer::releaseResumePointOperands(MResumePoint *resume)
{
for (size_t i = 0, e = resume->numOperands(); i < e; ++i) {
if (!resume->hasOperand(i))
continue;
MDefinition *op = resume->getOperand(i);
// TODO: We shouldn't leave discarded operands sitting around
// (bug 1055690).
if (op->isDiscarded())
continue;
resume->releaseOperand(i);
// We set the UseRemoved flag when removing resume point operands,
// because even though we may think we're certain that a particular
// branch might not be taken, the type information might be incomplete.
if (!handleUseReleased(op, SetUseRemoved))
return false;
}
return true;
}
示例3: remainingIterationsInequality
void
LoopUnroller::go(LoopIterationBound* bound)
{
// For now we always unroll loops the same number of times.
static const size_t UnrollCount = 10;
JitSpew(JitSpew_Unrolling, "Attempting to unroll loop");
header = bound->header;
// UCE might have determined this isn't actually a loop.
if (!header->isLoopHeader())
return;
backedge = header->backedge();
oldPreheader = header->loopPredecessor();
MOZ_ASSERT(oldPreheader->numSuccessors() == 1);
// Only unroll loops with two blocks: an initial one ending with the
// bound's test, and the body ending with the backedge.
MTest* test = bound->test;
if (header->lastIns() != test)
return;
if (test->ifTrue() == backedge) {
if (test->ifFalse()->id() <= backedge->id())
return;
} else if (test->ifFalse() == backedge) {
if (test->ifTrue()->id() <= backedge->id())
return;
} else {
return;
}
if (backedge->numPredecessors() != 1 || backedge->numSuccessors() != 1)
return;
MOZ_ASSERT(backedge->phisEmpty());
MBasicBlock* bodyBlocks[] = { header, backedge };
// All instructions in the header and body must be clonable.
for (size_t i = 0; i < ArrayLength(bodyBlocks); i++) {
MBasicBlock* block = bodyBlocks[i];
for (MInstructionIterator iter(block->begin()); iter != block->end(); iter++) {
MInstruction* ins = *iter;
if (ins->canClone())
continue;
if (ins->isTest() || ins->isGoto() || ins->isInterruptCheck())
continue;
#ifdef DEBUG
JitSpew(JitSpew_Unrolling, "Aborting: can't clone instruction %s", ins->opName());
#endif
return;
}
}
// Compute the linear inequality we will use for exiting the unrolled loop:
//
// iterationBound - iterationCount - UnrollCount >= 0
//
LinearSum remainingIterationsInequality(bound->boundSum);
if (!remainingIterationsInequality.add(bound->currentSum, -1))
return;
if (!remainingIterationsInequality.add(-int32_t(UnrollCount)))
return;
// Terms in the inequality need to be either loop invariant or phis from
// the original header.
for (size_t i = 0; i < remainingIterationsInequality.numTerms(); i++) {
MDefinition* def = remainingIterationsInequality.term(i).term;
if (def->isDiscarded())
return;
if (def->block()->id() < header->id())
continue;
if (def->block() == header && def->isPhi())
continue;
return;
}
// OK, we've checked everything, now unroll the loop.
JitSpew(JitSpew_Unrolling, "Unrolling loop");
// The old preheader will go before the unrolled loop, and the old loop
// will need a new empty preheader.
CompileInfo& info = oldPreheader->info();
if (header->trackedPc()) {
unrolledHeader =
MBasicBlock::New(graph, nullptr, info,
oldPreheader, header->trackedSite(), MBasicBlock::LOOP_HEADER);
unrolledBackedge =
MBasicBlock::New(graph, nullptr, info,
unrolledHeader, backedge->trackedSite(), MBasicBlock::NORMAL);
newPreheader =
MBasicBlock::New(graph, nullptr, info,
unrolledHeader, oldPreheader->trackedSite(), MBasicBlock::NORMAL);
} else {
unrolledHeader = MBasicBlock::NewAsmJS(graph, info, oldPreheader, MBasicBlock::LOOP_HEADER);
unrolledBackedge = MBasicBlock::NewAsmJS(graph, info, unrolledHeader, MBasicBlock::NORMAL);
newPreheader = MBasicBlock::NewAsmJS(graph, info, unrolledHeader, MBasicBlock::NORMAL);
}
//.........这里部分代码省略.........
示例4: JitSpew
// Visit |def|.
bool
ValueNumberer::visitDefinition(MDefinition *def)
{
// 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;
// If |sim| doesn't belong to a block, insert it next to |def|.
if (sim->block() == nullptr)
def->block()->insertAfter(def->toInstruction(), sim->toInstruction());
#ifdef DEBUG
JitSpew(JitSpew_GVN, " Folded %s%u to %s%u",
def->opName(), def->id(), sim->opName(), sim->id());
#endif
ReplaceAllUsesWith(def, sim);
// The node's foldsTo said |def| can be replaced by |rep|. If |def| is a
// guard, then either |rep| is also a guard, or a guard isn't actually
// needed, so we can clear |def|'s guard flag and let it be discarded.
def->setNotGuardUnchecked();
if (DeadIfUnused(def)) {
if (!discardDefsRecursively(def))
return false;
}
def = sim;
}
// Now that foldsTo is done, re-enable the original dependency. Even though
// it may be pointing into a discarded block, it's still valid for the
// purposes of detecting congruent loads.
if (dep != nullptr)
def->setDependency(dep);
// Look for a dominating def which makes |def| redundant.
MDefinition *rep = leader(def);
if (rep != def) {
if (rep == nullptr)
return false;
if (rep->updateForReplacement(def)) {
#ifdef DEBUG
JitSpew(JitSpew_GVN,
" Replacing %s%u with %s%u",
def->opName(), def->id(), rep->opName(), rep->id());
#endif
ReplaceAllUsesWith(def, rep);
// The node's congruentTo said |def| is congruent to |rep|, and it's
// dominated by |rep|. If |def| is a guard, it's covered by |rep|,
// so we can clear |def|'s guard flag and let it be discarded.
def->setNotGuardUnchecked();
if (DeadIfUnused(def)) {
// discardDef should not add anything to the deadDefs, as the
// redundant operation should have the same input operands.
mozilla::DebugOnly<bool> r = discardDef(def);
MOZ_ASSERT(r, "discardDef shouldn't have tried to add anything to the worklist, "
"so it shouldn't have failed");
MOZ_ASSERT(deadDefs_.empty(),
"discardDef shouldn't have added anything to the worklist");
}
def = rep;
}
}
return true;
}
示例5: 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() &&
!prev->isAssertRecoveredOnBailout())
{
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",
//.........这里部分代码省略.........