本文整理汇总了C++中MDefinition::isMovable方法的典型用法代码示例。如果您正苦于以下问题:C++ MDefinition::isMovable方法的具体用法?C++ MDefinition::isMovable怎么用?C++ MDefinition::isMovable使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类MDefinition
的用法示例。
在下文中一共展示了MDefinition::isMovable方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: IonSpew
bool
ValueNumberer::eliminateRedundancies()
{
// A definition is 'redundant' iff it is dominated by another definition
// with the same value number.
//
// So, we traverse the dominator tree in pre-order, maintaining a hashmap
// from value numbers to instructions.
//
// For each definition d with value number v, we look up v in the hashmap.
//
// If there is a definition d' in the hashmap, and the current traversal
// index is within that instruction's dominated range, then we eliminate d,
// replacing all uses of d with uses of d'.
//
// If there is no valid definition in the hashtable (the current definition
// is not in dominated scope), then we insert the current instruction,
// since it is the most dominant instruction with the given value number.
InstructionMap defs;
if (!defs.init())
return false;
IonSpew(IonSpew_GVN, "Eliminating redundant instructions");
// Stack for pre-order CFG traversal.
Vector<MBasicBlock *, 1, IonAllocPolicy> worklist;
// The index of the current block in the CFG traversal.
size_t index = 0;
// Add all self-dominating blocks to the worklist.
// This includes all roots. Order does not matter.
for (MBasicBlockIterator i(graph_.begin()); i != graph_.end(); i++) {
MBasicBlock *block = *i;
if (block->immediateDominator() == block) {
if (!worklist.append(block))
return false;
}
}
// Starting from each self-dominating block, traverse the CFG in pre-order.
while (!worklist.empty()) {
MBasicBlock *block = worklist.popCopy();
IonSpew(IonSpew_GVN, "Looking at block %d", block->id());
// Add all immediate dominators to the front of the worklist.
for (size_t i = 0; i < block->numImmediatelyDominatedBlocks(); i++) {
if (!worklist.append(block->getImmediatelyDominatedBlock(i)))
return false;
}
// For each instruction, attempt to look up a dominating definition.
for (MDefinitionIterator iter(block); iter; ) {
MDefinition *ins = simplify(*iter, true);
// Instruction was replaced, and all uses have already been fixed.
if (ins != *iter) {
iter = block->discardDefAt(iter);
continue;
}
// Instruction has side-effects and cannot be folded.
if (!ins->isMovable() || ins->isEffectful()) {
iter++;
continue;
}
MDefinition *dom = findDominatingDef(defs, ins, index);
if (!dom)
return false; // Insertion failed.
if (dom == ins || !dom->updateForReplacement(ins)) {
iter++;
continue;
}
IonSpew(IonSpew_GVN, "instruction %d is dominated by instruction %d (from block %d)",
ins->id(), dom->id(), dom->block()->id());
ins->replaceAllUsesWith(dom);
JS_ASSERT(!ins->hasUses());
JS_ASSERT(ins->block() == block);
JS_ASSERT(!ins->isEffectful());
JS_ASSERT(ins->isMovable());
iter = ins->block()->discardDefAt(iter);
}
index++;
}
JS_ASSERT(index == graph_.numBlocks());
return true;
}
示例2: sp
void
RangeAnalysis::analyzeLoop(MBasicBlock *header)
{
// Try to compute an upper bound on the number of times the loop backedge
// will be taken. Look for tests that dominate the backedge and which have
// an edge leaving the loop body.
MBasicBlock *backedge = header->backedge();
// Ignore trivial infinite loops.
if (backedge == header)
return;
markBlocksInLoopBody(header, backedge);
LoopIterationBound *iterationBound = NULL;
MBasicBlock *block = backedge;
do {
BranchDirection direction;
MTest *branch = block->immediateDominatorBranch(&direction);
if (block == block->immediateDominator())
break;
block = block->immediateDominator();
if (branch) {
direction = NegateBranchDirection(direction);
MBasicBlock *otherBlock = branch->branchSuccessor(direction);
if (!otherBlock->isMarked()) {
iterationBound =
analyzeLoopIterationCount(header, branch, direction);
if (iterationBound)
break;
}
}
} while (block != header);
if (!iterationBound) {
graph_.unmarkBlocks();
return;
}
#ifdef DEBUG
if (IonSpewEnabled(IonSpew_Range)) {
Sprinter sp(GetIonContext()->cx);
sp.init();
iterationBound->sum.print(sp);
IonSpew(IonSpew_Range, "computed symbolic bound on backedges: %s",
sp.string());
}
#endif
// Try to compute symbolic bounds for the phi nodes at the head of this
// loop, expressed in terms of the iteration bound just computed.
for (MDefinitionIterator iter(header); iter; iter++) {
MDefinition *def = *iter;
if (def->isPhi())
analyzeLoopPhi(header, iterationBound, def->toPhi());
}
// Try to hoist any bounds checks from the loop using symbolic bounds.
Vector<MBoundsCheck *, 0, IonAllocPolicy> hoistedChecks;
for (ReversePostorderIterator iter(graph_.rpoBegin()); iter != graph_.rpoEnd(); iter++) {
MBasicBlock *block = *iter;
if (!block->isMarked())
continue;
for (MDefinitionIterator iter(block); iter; iter++) {
MDefinition *def = *iter;
if (def->isBoundsCheck() && def->isMovable()) {
if (tryHoistBoundsCheck(header, def->toBoundsCheck()))
hoistedChecks.append(def->toBoundsCheck());
}
}
}
// Note: replace all uses of the original bounds check with the
// actual index. This is usually done during bounds check elimination,
// but in this case it's safe to do it here since the load/store is
// definitely not loop-invariant, so we will never move it before
// one of the bounds checks we just added.
for (size_t i = 0; i < hoistedChecks.length(); i++) {
MBoundsCheck *ins = hoistedChecks[i];
ins->replaceAllUsesWith(ins->index());
ins->block()->discard(ins);
}
graph_.unmarkBlocks();
}
示例3: IonSpew
//.........这里部分代码省略.........
}
while (count_ > 0) {
#ifdef DEBUG
if (!pessimisticPass_) {
size_t debugCount = 0;
IonSpew(IonSpew_GVN, "The following instructions require processing:");
for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {
for (MDefinitionIterator iter(*block); iter; iter++) {
if (iter->isInWorklist()) {
IonSpew(IonSpew_GVN, "\t%d", iter->id());
debugCount++;
}
}
if (block->lastIns()->isInWorklist()) {
IonSpew(IonSpew_GVN, "\t%d", block->lastIns()->id());
debugCount++;
}
}
if (!debugCount)
IonSpew(IonSpew_GVN, "\tNone");
JS_ASSERT(debugCount == count_);
}
#endif
for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {
if (mir->shouldCancel("Value Numbering (main loop)"))
return false;
for (MDefinitionIterator iter(*block); iter; ) {
if (!isMarked(*iter)) {
iter++;
continue;
}
JS_ASSERT_IF(!pessimisticPass_, count_ > 0);
unmarkDefinition(*iter);
MDefinition *ins = simplify(*iter, false);
if (ins != *iter) {
iter = block->discardDefAt(iter);
continue;
}
// Don't bother storing this instruction in the HashMap if
// (a) eliminateRedundancies will never eliminate it (because
// it's non-movable or effectful) and (b) no other instruction's
// value number depends on it.
if (!ins->hasDefUses() && (!ins->isMovable() || ins->isEffectful())) {
iter++;
continue;
}
uint32_t value = lookupValue(ins);
if (!value)
return false; // Hashtable insertion failed
if (ins->valueNumber() != value) {
IonSpew(IonSpew_GVN,
"Broke congruence for instruction %d (%p) with VN %d (now using %d)",
ins->id(), (void *) ins, ins->valueNumber(), value);
ins->setValueNumber(value);
markConsumers(ins);
}
iter++;
}
// Process control flow instruction:
MControlInstruction *jump = block->lastIns();
jump = simplifyControlInstruction(jump);
// If we are pessimistic, then this will never get set.
if (!jump->isInWorklist())
continue;
unmarkDefinition(jump);
if (jump->valueNumber() == 0) {
jump->setValueNumber(jump->id());
for (size_t i = 0; i < jump->numSuccessors(); i++)
markBlock(jump->getSuccessor(i));
}
}
// If we are doing a pessimistic pass, we only go once through the
// instruction list.
if (pessimisticPass_)
break;
}
#ifdef DEBUG
for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {
for (MDefinitionIterator iter(*block); iter; iter++) {
JS_ASSERT(!iter->isInWorklist());
JS_ASSERT_IF(iter->valueNumber() == 0,
!iter->hasDefUses() && (!iter->isMovable() || iter->isEffectful()));
}
}
#endif
return true;
}