本文整理汇总了C++中MInstructionIterator::isFolded方法的典型用法代码示例。如果您正苦于以下问题:C++ MInstructionIterator::isFolded方法的具体用法?C++ MInstructionIterator::isFolded怎么用?C++ MInstructionIterator::isFolded使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类MInstructionIterator
的用法示例。
在下文中一共展示了MInstructionIterator::isFolded方法的1个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Max
// Operands to a resume point which are dead at the point of the resume can be
// replaced with undefined values. This analysis supports limited detection of
// dead operands, pruning those which are defined in the resume point's basic
// block and have no uses outside the block or at points later than the resume
// point.
//
// This is intended to ensure that extra resume points within a basic block
// will not artificially extend the lifetimes of any SSA values. This could
// otherwise occur if the new resume point captured a value which is created
// between the old and new resume point and is dead at the new resume point.
bool
ion::EliminateDeadResumePointOperands(MIRGenerator *mir, MIRGraph &graph)
{
for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) {
if (mir->shouldCancel("Eliminate Dead Resume Point Operands (main loop)"))
return false;
// The logic below can get confused on infinite loops.
if (block->isLoopHeader() && block->backedge() == *block)
continue;
for (MInstructionIterator ins = block->begin(); ins != block->end(); ins++) {
// No benefit to replacing constant operands with other constants.
if (ins->isConstant())
continue;
// Scanning uses does not give us sufficient information to tell
// where instructions that are involved in box/unbox operations or
// parameter passing might be live. Rewriting uses of these terms
// in resume points may affect the interpreter's behavior. Rather
// than doing a more sophisticated analysis, just ignore these.
if (ins->isUnbox() || ins->isParameter())
continue;
// If the instruction's behavior has been constant folded into a
// separate instruction, we can't determine precisely where the
// instruction becomes dead and can't eliminate its uses.
if (ins->isFolded())
continue;
// Check if this instruction's result is only used within the
// current block, and keep track of its last use in a definition
// (not resume point). This requires the instructions in the block
// to be numbered, ensured by running this immediately after alias
// analysis.
uint32_t maxDefinition = 0;
for (MUseDefIterator uses(*ins); uses; uses++) {
if (uses.def()->block() != *block ||
uses.def()->isBox() ||
uses.def()->isPassArg() ||
uses.def()->isPhi())
{
maxDefinition = UINT32_MAX;
break;
}
maxDefinition = Max(maxDefinition, uses.def()->id());
}
if (maxDefinition == UINT32_MAX)
continue;
// Walk the uses a second time, removing any in resume points after
// the last use in a definition.
for (MUseIterator uses(ins->usesBegin()); uses != ins->usesEnd(); ) {
if (uses->node()->isDefinition()) {
uses++;
continue;
}
MResumePoint *mrp = uses->node()->toResumePoint();
if (mrp->block() != *block ||
!mrp->instruction() ||
mrp->instruction() == *ins ||
mrp->instruction()->id() <= maxDefinition)
{
uses++;
continue;
}
// Store an undefined value in place of all dead resume point
// operands. Making any such substitution can in general alter
// the interpreter's behavior, even though the code is dead, as
// the interpreter will still execute opcodes whose effects
// cannot be observed. If the undefined value were to flow to,
// say, a dead property access the interpreter could throw an
// exception; we avoid this problem by removing dead operands
// before removing dead code.
MConstant *constant = MConstant::New(UndefinedValue());
block->insertBefore(*(block->begin()), constant);
uses = mrp->replaceOperand(uses, constant);
}
}
}
return true;
}