本文整理汇总了C++中MDefinition::id方法的典型用法代码示例。如果您正苦于以下问题:C++ MDefinition::id方法的具体用法?C++ MDefinition::id怎么用?C++ MDefinition::id使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类MDefinition
的用法示例。
在下文中一共展示了MDefinition::id方法的7个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: IonSpew
MDefinition *
ValueNumberer::simplify(MDefinition *def, bool useValueNumbers)
{
if (def->isEffectful())
return def;
MDefinition *ins = def->foldsTo(useValueNumbers);
if (ins == def || !ins->updateForFolding(def))
return def;
// ensure this instruction has a VN
if (!ins->valueNumberData())
ins->setValueNumberData(new ValueNumberData);
if (!ins->block()) {
// In this case, we made a new def by constant folding, for
// example, we replaced add(#3,#4) with a new const(#7) node.
// We will only fold a phi into one of its operands.
JS_ASSERT(!def->isPhi());
def->block()->insertAfter(def->toInstruction(), ins->toInstruction());
ins->setValueNumber(lookupValue(ins));
}
JS_ASSERT(ins->id() != 0);
def->replaceAllUsesWith(ins);
IonSpew(IonSpew_GVN, "Folding %d to be %d", def->id(), ins->id());
return ins;
}
示例2: IonSpew
bool
RangeAnalysis::removeBetaNobes()
{
IonSpew(IonSpew_Range, "Removing beta nobes");
for (PostorderIterator i(graph_.poBegin()); i != graph_.poEnd(); i++) {
MBasicBlock *block = *i;
for (MDefinitionIterator iter(*i); iter; ) {
MDefinition *def = *iter;
if (def->isBeta()) {
MDefinition *op = def->getOperand(0);
IonSpew(IonSpew_Range, "Removing beta node %d for %d",
def->id(), op->id());
def->replaceAllUsesWith(op);
iter = block->discardDefAt(iter);
} else {
// We only place Beta nodes at the beginning of basic
// blocks, so if we see something else, we can move on
// to the next block.
break;
}
}
}
return true;
}
示例3: IonSpew
void
ValueNumberer::breakClass(MDefinition *def)
{
if (def->valueNumber() == def->id()) {
IonSpew(IonSpew_GVN, "Breaking congruence with itself: %d", def->id());
ValueNumberData *defdata = def->valueNumberData();
JS_ASSERT(defdata->classPrev == NULL);
// If the def was the only member of the class, then there is nothing to do.
if (defdata->classNext == NULL)
return;
// If upon closer inspection, we are still equivalent to this class
// then there isn't anything for us to do.
if (!needsSplit(def))
return;
// Get a new representative member
MDefinition *newRep = defdata->classNext;
// Chop off the head of the list (the old representative)
newRep->valueNumberData()->classPrev = NULL;
def->valueNumberData()->classNext = NULL;
IonSpew(IonSpew_GVN, "Choosing a new representative: %d", newRep->id());
// make the VN of every member in the class the VN of the new representative number.
for (MDefinition *tmp = newRep; tmp != NULL; tmp = tmp->valueNumberData()->classNext) {
// if this instruction is already scheduled to be processed, don't do anything.
if (tmp->isInWorklist())
continue;
IonSpew(IonSpew_GVN, "Moving to a new congruence class: %d", tmp->id());
tmp->setValueNumber(newRep->id());
markConsumers(tmp);
markDefinition(tmp);
}
// Insert the new representative => number mapping into the table
// Logically, there should not be anything in the table currently, but
// old values are never removed, so there's a good chance something will
// already be there.
values.put(newRep, newRep->id());
} else {
// The element that is breaking from the list isn't the representative element
// just strip it from the list
ValueNumberData *defdata = def->valueNumberData();
if (defdata->classPrev)
defdata->classPrev->valueNumberData()->classNext = defdata->classNext;
if (defdata->classNext)
defdata->classNext->valueNumberData()->classPrev = defdata->classPrev;
// Make sure there is no nastinees accidentally linking elements into the old list later.
defdata->classPrev = NULL;
defdata->classNext = NULL;
}
}
示例4: IonSpew
bool
RangeAnalysis::analyze()
{
IonSpew(IonSpew_Range, "Doing range propagation");
for (ReversePostorderIterator iter(graph_.rpoBegin()); iter != graph_.rpoEnd(); iter++) {
MBasicBlock *block = *iter;
for (MDefinitionIterator iter(block); iter; iter++) {
MDefinition *def = *iter;
def->computeRange();
IonSpew(IonSpew_Range, "computing range on %d", def->id());
SpewRange(def);
}
if (block->isLoopHeader())
analyzeLoop(block);
}
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;
}
return true;
}
// If this instruction has a dependency() into an unreachable block, we'll
// need to update AliasAnalysis.
MInstruction* 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
MOZ_ASSERT(!sim->isDiscarded());
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;
// If that ended up discarding |sim|, then we're done here.
if (sim->isDiscarded())
return true;
}
// Otherwise, procede to optimize with |sim| in place of |def|.
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;
//.........这里部分代码省略.........
示例6: 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;
}
示例7: 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",
//.........这里部分代码省略.........