本文整理汇总了C++中MDefinition::isInWorklist方法的典型用法代码示例。如果您正苦于以下问题:C++ MDefinition::isInWorklist方法的具体用法?C++ MDefinition::isInWorklist怎么用?C++ MDefinition::isInWorklist使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类MDefinition
的用法示例。
在下文中一共展示了MDefinition::isInWorklist方法的7个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: IonSpew
bool
Loop::optimize()
{
InstructionQueue invariantInstructions;
InstructionQueue boundsChecks;
IonSpew(IonSpew_LICM, "These instructions are in the loop: ");
while (!worklist_.empty()) {
if (mir->shouldCancel("LICM (worklist)"))
return false;
MInstruction *ins = popFromWorklist();
IonSpewHeader(IonSpew_LICM);
if (IonSpewEnabled(IonSpew_LICM)) {
ins->printName(IonSpewFile);
fprintf(IonSpewFile, " <- ");
ins->printOpcode(IonSpewFile);
fprintf(IonSpewFile, ": ");
}
if (isLoopInvariant(ins)) {
// Flag this instruction as loop invariant.
ins->setLoopInvariant();
if (!invariantInstructions.append(ins))
return false;
// Loop through uses of invariant instruction and add back to work list.
for (MUseDefIterator iter(ins->toDefinition()); iter; iter++) {
MDefinition *consumer = iter.def();
if (consumer->isInWorklist())
continue;
// if the consumer of this invariant instruction is in the
// loop, and it is also worth hoisting, then process it.
if (isInLoop(consumer) && isHoistable(consumer)) {
if (!insertInWorklist(consumer->toInstruction()))
return false;
}
}
if (IonSpewEnabled(IonSpew_LICM))
fprintf(IonSpewFile, " Loop Invariant!\n");
} else if (ins->isBoundsCheck()) {
if (!boundsChecks.append(ins))
return false;
}
}
if (!hoistInstructions(invariantInstructions, boundsChecks))
return false;
return true;
}
示例2: 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;
}
}
示例3:
bool
LRecoverInfo::appendOperands(MNode* ins)
{
for (size_t i = 0, end = ins->numOperands(); i < end; i++) {
MDefinition* def = ins->getOperand(i);
// As there is no cycle in the data-flow (without MPhi), checking for
// isInWorkList implies that the definition is already in the
// instruction vector, and not processed by a caller of the current
// function.
if (def->isRecoveredOnBailout() && !def->isInWorklist()) {
if (!appendDefinition(def))
return false;
}
}
return true;
}
示例4: IonSpew
bool
RangeAnalysis::analyze()
{
int numBlocks = 0;
for (PostorderIterator i(graph_.poBegin()); i != graph_.poEnd(); i++) {
numBlocks++;
MBasicBlock *curBlock = *i;
if (!curBlock->isLoopHeader())
continue;
for (MPhiIterator pi(curBlock->phisBegin()); pi != curBlock->phisEnd(); pi++)
if (!pi->initCounts())
return false;
}
IonSpew(IonSpew_Range, "Doing range propagation");
MDefinitionVector worklist;
for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {
for (MDefinitionIterator iter(*block); iter; iter++) {
MDefinition *def = *iter;
AddToWorklist(worklist, def);
}
}
size_t iters = 0;
while (!worklist.empty()) {
MDefinition *def = PopFromWorklist(worklist);
IonSpew(IonSpew_Range, "recomputing range on %d", def->id());
SpewRange(def);
if (!def->earlyAbortCheck() && def->recomputeRange()) {
JS_ASSERT(def->range()->lower() <= def->range()->upper());
IonSpew(IonSpew_Range, "Range changed; adding consumers");
IonSpew(IonSpew_Range, "New range for %d is: (%d, %d)", def->id(), def->range()->lower(), def->range()->upper());
for (MUseDefIterator use(def); use; use++) {
if(!AddToWorklist(worklist, use.def()))
return false;
}
}
iters++;
if (iters >= numBlocks * 100)
return false;
}
// Cleanup (in case we stopped due to MAX_ITERS)
for(size_t i = 0; i < worklist.length(); i++)
worklist[i]->setNotInWorklist();
#ifdef DEBUG
for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {
for (MDefinitionIterator iter(*block); iter; iter++) {
MDefinition *def = *iter;
SpewRange(def);
JS_ASSERT(def->range()->lower() <= def->range()->upper());
JS_ASSERT(!def->isInWorklist());
}
}
#endif
return true;
}
示例5: while
bool
ion::EliminatePhis(MIRGenerator *mir, MIRGraph &graph)
{
Vector<MPhi *, 16, SystemAllocPolicy> worklist;
// Add all observable phis to a worklist. We use the "in worklist" bit to
// mean "this phi is live".
for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) {
if (mir->shouldCancel("Eliminate Phis (populate loop)"))
return false;
MPhiIterator iter = block->phisBegin();
while (iter != block->phisEnd()) {
// Flag all as unused, only observable phis would be marked as used
// when processed by the work list.
iter->setUnused();
// If the phi is redundant, remove it here.
if (MDefinition *redundant = IsPhiRedundant(*iter)) {
iter->replaceAllUsesWith(redundant);
iter = block->discardPhiAt(iter);
continue;
}
// Enqueue observable Phis.
if (IsPhiObservable(*iter)) {
iter->setInWorklist();
if (!worklist.append(*iter))
return false;
}
iter++;
}
}
// Iteratively mark all phis reachable from live phis.
while (!worklist.empty()) {
if (mir->shouldCancel("Eliminate Phis (worklist)"))
return false;
MPhi *phi = worklist.popCopy();
JS_ASSERT(phi->isUnused());
phi->setNotInWorklist();
// The removal of Phis can produce newly redundant phis.
if (MDefinition *redundant = IsPhiRedundant(phi)) {
// Add to the worklist the used phis which are impacted.
for (MUseDefIterator it(phi); it; it++) {
if (it.def()->isPhi()) {
MPhi *use = it.def()->toPhi();
if (!use->isUnused()) {
use->setUnusedUnchecked();
use->setInWorklist();
if (!worklist.append(use))
return false;
}
}
}
phi->replaceAllUsesWith(redundant);
} else {
// Otherwise flag them as used.
phi->setNotUnused();
}
// The current phi is/was used, so all its operands are used.
for (size_t i = 0; i < phi->numOperands(); i++) {
MDefinition *in = phi->getOperand(i);
if (!in->isPhi() || !in->isUnused() || in->isInWorklist())
continue;
in->setInWorklist();
if (!worklist.append(in->toPhi()))
return false;
}
}
// Sweep dead phis.
for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) {
MPhiIterator iter = block->phisBegin();
while (iter != block->phisEnd()) {
if (iter->isUnused())
iter = block->discardPhiAt(iter);
else
iter++;
}
}
return true;
}
示例6: 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.
MDefinition *newRep = findSplit(def);
if (!newRep)
return;
ValueNumberData *newdata = newRep->valueNumberData();
// Right now, |defdata| is at the front of the list, and |newdata| is
// somewhere in the middle.
//
// We want to move |defdata| and everything up to but excluding
// |newdata| to a new list, with |defdata| still as the canonical
// element.
//
// We then want to take |newdata| and everything after, and
// mark them for processing (since |newdata| is now a new canonical
// element).
//
MDefinition *lastOld = newdata->classPrev;
JS_ASSERT(lastOld); // newRep is NOT the first element of the list.
JS_ASSERT(lastOld->valueNumberData()->classNext == newRep);
//lastOld is now the last element of the old list (congruent to
//|def|)
lastOld->valueNumberData()->classNext = NULL;
#ifdef DEBUG
for (MDefinition *tmp = def; tmp != NULL; tmp = tmp->valueNumberData()->classNext) {
JS_ASSERT(tmp->valueNumber() == def->valueNumber());
JS_ASSERT(tmp->congruentTo(def));
JS_ASSERT(tmp != newRep);
}
#endif
//|newRep| is now the first element of a new list, therefore it is the
//new canonical element. Mark the remaining elements in the list
//(including |newRep|)
newdata->classPrev = 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;
}
}
示例7: while
bool
ion::EliminatePhis(MIRGenerator *mir, MIRGraph &graph,
Observability observe)
{
// Eliminates redundant or unobservable phis from the graph. A
// redundant phi is something like b = phi(a, a) or b = phi(a, b),
// both of which can be replaced with a. An unobservable phi is
// one that whose value is never used in the program.
//
// Note that we must be careful not to eliminate phis representing
// values that the interpreter will require later. When the graph
// is first constructed, we can be more aggressive, because there
// is a greater correspondence between the CFG and the bytecode.
// After optimizations such as GVN have been performed, however,
// the bytecode and CFG may not correspond as closely to one
// another. In that case, we must be more conservative. The flag
// |conservativeObservability| is used to indicate that eliminate
// phis is being run after some optimizations have been performed,
// and thus we should use more conservative rules about
// observability. The particular danger is that we can optimize
// away uses of a phi because we think they are not executable,
// but the foundation for that assumption is false TI information
// that will eventually be invalidated. Therefore, if
// |conservativeObservability| is set, we will consider any use
// from a resume point to be observable. Otherwise, we demand a
// use from an actual instruction.
Vector<MPhi *, 16, SystemAllocPolicy> worklist;
// Add all observable phis to a worklist. We use the "in worklist" bit to
// mean "this phi is live".
for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) {
if (mir->shouldCancel("Eliminate Phis (populate loop)"))
return false;
MPhiIterator iter = block->phisBegin();
while (iter != block->phisEnd()) {
// Flag all as unused, only observable phis would be marked as used
// when processed by the work list.
iter->setUnused();
// If the phi is redundant, remove it here.
if (MDefinition *redundant = IsPhiRedundant(*iter)) {
iter->replaceAllUsesWith(redundant);
iter = block->discardPhiAt(iter);
continue;
}
// Enqueue observable Phis.
if (IsPhiObservable(*iter, observe)) {
iter->setInWorklist();
if (!worklist.append(*iter))
return false;
}
iter++;
}
}
// Iteratively mark all phis reachable from live phis.
while (!worklist.empty()) {
if (mir->shouldCancel("Eliminate Phis (worklist)"))
return false;
MPhi *phi = worklist.popCopy();
JS_ASSERT(phi->isUnused());
phi->setNotInWorklist();
// The removal of Phis can produce newly redundant phis.
if (MDefinition *redundant = IsPhiRedundant(phi)) {
// Add to the worklist the used phis which are impacted.
for (MUseDefIterator it(phi); it; it++) {
if (it.def()->isPhi()) {
MPhi *use = it.def()->toPhi();
if (!use->isUnused()) {
use->setUnusedUnchecked();
use->setInWorklist();
if (!worklist.append(use))
return false;
}
}
}
phi->replaceAllUsesWith(redundant);
} else {
// Otherwise flag them as used.
phi->setNotUnused();
}
// The current phi is/was used, so all its operands are used.
for (size_t i = 0; i < phi->numOperands(); i++) {
MDefinition *in = phi->getOperand(i);
if (!in->isPhi() || !in->isUnused() || in->isInWorklist())
continue;
in->setInWorklist();
if (!worklist.append(in->toPhi()))
return false;
}
}
// Sweep dead phis.
for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) {
//.........这里部分代码省略.........