本文整理汇总了C++中MInstruction类的典型用法代码示例。如果您正苦于以下问题:C++ MInstruction类的具体用法?C++ MInstruction怎么用?C++ MInstruction使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了MInstruction类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: MOZ_ASSERT
bool
FilterTypeSetPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
{
MOZ_ASSERT(ins->numOperands() == 1);
MIRType inputType = ins->getOperand(0)->type();
MIRType outputType = ins->type();
// Input and output type are already in accordance.
if (inputType == outputType)
return true;
// Output is a value, box the input.
if (outputType == MIRType_Value) {
MOZ_ASSERT(inputType != MIRType_Value);
ins->replaceOperand(0, BoxAt(alloc, ins, ins->getOperand(0)));
return true;
}
// The outputType should be a subset of the inputType else we are in code
// that has never executed yet. Bail to see the new type (if that hasn't
// happened yet).
if (inputType != MIRType_Value) {
MBail *bail = MBail::New(alloc);
ins->block()->insertBefore(ins, bail);
bail->setDependency(ins->dependency());
ins->setDependency(bail);
ins->replaceOperand(0, BoxAt(alloc, ins, ins->getOperand(0)));
}
// We can't unbox a value to null/undefined/lazyargs. So keep output
// also a value.
// Note: Using setResultType shouldn't be done in TypePolicies,
// Here it is fine, since the type barrier has no uses.
if (IsNullOrUndefined(outputType) || outputType == MIRType_MagicOptimizedArguments) {
MOZ_ASSERT(!ins->hasDefUses());
ins->setResultType(MIRType_Value);
return true;
}
// Unbox / propagate the right type.
MUnbox::Mode mode = MUnbox::Infallible;
MInstruction *replace = MUnbox::New(alloc, ins->getOperand(0), ins->type(), mode);
ins->block()->insertBefore(ins, replace);
ins->replaceOperand(0, replace);
if (!replace->typePolicy()->adjustInputs(alloc, replace))
return false;
// Carry over the dependency the MFilterTypeSet had.
replace->setDependency(ins->dependency());
return true;
}
示例2: MOZ_ASSERT
bool
TypeBarrierPolicy::adjustInputs(TempAllocator &alloc, MInstruction *def)
{
MTypeBarrier *ins = def->toTypeBarrier();
MIRType inputType = ins->getOperand(0)->type();
MIRType outputType = ins->type();
// Input and output type are already in accordance.
if (inputType == outputType)
return true;
// Output is a value, currently box the input.
if (outputType == MIRType_Value) {
// XXX: Possible optimization: decrease resultTypeSet to only include
// the inputType. This will remove the need for boxing.
MOZ_ASSERT(inputType != MIRType_Value);
ins->replaceOperand(0, boxAt(alloc, ins, ins->getOperand(0)));
return true;
}
// Box input if needed.
if (inputType != MIRType_Value) {
MOZ_ASSERT(ins->alwaysBails());
ins->replaceOperand(0, boxAt(alloc, ins, ins->getOperand(0)));
}
// We can't unbox a value to null/undefined/lazyargs. So keep output
// also a value.
// Note: Using setResultType shouldn't be done in TypePolicies,
// Here it is fine, since the type barrier has no uses.
if (IsNullOrUndefined(outputType) || outputType == MIRType_MagicOptimizedArguments) {
MOZ_ASSERT(!ins->hasDefUses());
ins->setResultType(MIRType_Value);
return true;
}
// Unbox / propagate the right type.
MUnbox::Mode mode = MUnbox::TypeBarrier;
MInstruction *replace = MUnbox::New(alloc, ins->getOperand(0), ins->type(), mode);
ins->block()->insertBefore(ins, replace);
ins->replaceOperand(0, replace);
if (!replace->typePolicy()->adjustInputs(alloc, replace))
return false;
// The TypeBarrier is equivalent to removing branches with unexpected
// types. The unexpected types would have changed Range Analysis
// predictions. As such, we need to prevent destructive optimizations.
ins->block()->flagOperandsOfPrunedBranches(replace);
return true;
}
示例3: MagicValue
MConstant*
MBasicBlock::optimizedOutConstant(TempAllocator& alloc)
{
// If the first instruction is a MConstant(MagicValue(JS_OPTIMIZED_OUT))
// then reuse it.
MInstruction* ins = *begin();
if (ins->type() == MIRType_MagicOptimizedOut)
return ins->toConstant();
MConstant* constant = MConstant::New(alloc, MagicValue(JS_OPTIMIZED_OUT));
insertBefore(ins, constant);
return constant;
}
示例4: MOZ_ASSERT
bool
MBasicBlock::linkOsrValues(MStart* start)
{
MOZ_ASSERT(start->startType() == MStart::StartType_Osr);
MResumePoint* res = start->resumePoint();
for (uint32_t i = 0; i < stackDepth(); i++) {
MDefinition* def = slots_[i];
MInstruction* cloneRp = nullptr;
if (i == info().scopeChainSlot()) {
if (def->isOsrScopeChain())
cloneRp = def->toOsrScopeChain();
} else if (i == info().returnValueSlot()) {
if (def->isOsrReturnValue())
cloneRp = def->toOsrReturnValue();
} else if (info().hasArguments() && i == info().argsObjSlot()) {
MOZ_ASSERT(def->isConstant() || def->isOsrArgumentsObject());
MOZ_ASSERT_IF(def->isConstant(), def->toConstant()->value() == UndefinedValue());
if (def->isOsrArgumentsObject())
cloneRp = def->toOsrArgumentsObject();
} else {
MOZ_ASSERT(def->isOsrValue() || def->isGetArgumentsObjectArg() || def->isConstant() ||
def->isParameter());
// A constant Undefined can show up here for an argument slot when
// the function has an arguments object, but the argument in
// question is stored on the scope chain.
MOZ_ASSERT_IF(def->isConstant(), def->toConstant()->value() == UndefinedValue());
if (def->isOsrValue())
cloneRp = def->toOsrValue();
else if (def->isGetArgumentsObjectArg())
cloneRp = def->toGetArgumentsObjectArg();
else if (def->isParameter())
cloneRp = def->toParameter();
}
if (cloneRp) {
MResumePoint* clone = MResumePoint::Copy(graph().alloc(), res);
if (!clone)
return false;
cloneRp->setResumePoint(clone);
}
}
return true;
}
示例5:
bool
Loop::hoistInstructions(InstructionQueue &toHoist)
{
// Iterate in post-order (uses before definitions)
for (int32_t i = toHoist.length() - 1; i >= 0; i--) {
MInstruction *ins = toHoist[i];
// Don't hoist a cheap constant if it doesn't enable us to hoist one of
// its uses. We want those instructions as close as possible to their
// use, to facilitate folding and minimize register pressure.
if (requiresHoistedUse(ins)) {
bool loopInvariantUse = false;
for (MUseDefIterator use(ins); use; use++) {
if (use.def()->isLoopInvariant()) {
loopInvariantUse = true;
break;
}
}
if (!loopInvariantUse)
ins->setNotLoopInvariant();
}
}
// Move all instructions to the preLoop_ block just before the control instruction.
for (size_t i = 0; i < toHoist.length(); i++) {
MInstruction *ins = toHoist[i];
// Loads may have an implicit dependency on either stores (effectful instructions) or
// control instructions so we should never move these.
JS_ASSERT(!ins->isControlInstruction());
JS_ASSERT(!ins->isEffectful());
JS_ASSERT(ins->isMovable());
if (!ins->isLoopInvariant())
continue;
if (checkHotness(ins->block())) {
ins->block()->moveBefore(preLoop_->lastIns(), ins);
ins->setNotLoopInvariant();
}
}
return true;
}
示例6:
bool
AllDoublePolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
{
for (size_t i = 0, e = ins->numOperands(); i < e; i++) {
MDefinition *in = ins->getOperand(i);
if (in->type() == MIRType_Double)
continue;
MInstruction *replace = MToDouble::New(alloc, in);
ins->block()->insertBefore(ins, replace);
ins->replaceOperand(i, replace);
if (!replace->typePolicy()->adjustInputs(alloc, replace))
return false;
}
return true;
}
示例7: AnalyzeAdd
// Fold AddIs with one variable and two or more constants into one AddI.
static void AnalyzeAdd(TempAllocator& alloc, MAdd* add) {
if (add->specialization() != MIRType::Int32 || add->isRecoveredOnBailout()) {
return;
}
if (!add->hasUses()) {
return;
}
JitSpew(JitSpew_FLAC, "analyze add: %s%u", add->opName(), add->id());
SimpleLinearSum sum = ExtractLinearSum(add);
if (sum.constant == 0 || !sum.term) {
return;
}
// Determine which operand is the constant.
int idx = add->getOperand(0)->isConstant() ? 0 : 1;
if (add->getOperand(idx)->isConstant()) {
// Do not replace an add where the outcome is the same add instruction.
MOZ_ASSERT(add->getOperand(idx)->toConstant()->type() == MIRType::Int32);
if (sum.term == add->getOperand(1 - idx) ||
sum.constant == add->getOperand(idx)->toConstant()->toInt32()) {
return;
}
}
MInstruction* rhs = MConstant::New(alloc, Int32Value(sum.constant));
add->block()->insertBefore(add, rhs);
MAdd* addNew =
MAdd::New(alloc, sum.term, rhs, MIRType::Int32, add->truncateKind());
add->replaceAllLiveUsesWith(addNew);
add->block()->insertBefore(add, addNew);
JitSpew(JitSpew_FLAC, "replaced with: %s%u", addNew->opName(), addNew->id());
JitSpew(JitSpew_FLAC, "and constant: %s%u (%d)", rhs->opName(), rhs->id(),
sum.constant);
// Mark the stale nodes as RecoveredOnBailout since the Sink pass has
// been run before this pass. DCE will then remove the unused nodes.
markNodesAsRecoveredOnBailout(add);
}
示例8: IonSpew
// Iterate backward on all instruction and attempt to truncate operations for
// each instruction which respect the following list of predicates: Has been
// analyzed by range analysis, the range has no rounding errors, all uses cases
// are truncating the result.
//
// If the truncation of the operation is successful, then the instruction is
// queue for later updating the graph to restore the type correctness by
// converting the operands that need to be truncated.
//
// We iterate backward because it is likely that a truncated operation truncates
// some of its operands.
bool
RangeAnalysis::truncate()
{
IonSpew(IonSpew_Range, "Do range-base truncation (backward loop)");
Vector<MInstruction *, 16, SystemAllocPolicy> worklist;
for (PostorderIterator block(graph_.poBegin()); block != graph_.poEnd(); block++) {
for (MInstructionReverseIterator iter(block->rbegin()); iter != block->rend(); iter++) {
// Set truncated flag if range analysis ensure that it has no
// rounding errors and no freactional part.
const Range *r = iter->range();
if (!r || r->hasRoundingErrors())
continue;
// Ensure all observable uses are truncated.
if (!AllUsesTruncate(*iter))
continue;
// Truncate this instruction if possible.
if (!iter->truncate())
continue;
// Delay updates of inputs/outputs to avoid creating node which
// would be removed by the truncation of the next operations.
iter->setInWorklist();
if (!worklist.append(*iter))
return false;
}
}
// Update inputs/outputs of truncated instructions.
IonSpew(IonSpew_Range, "Do graph type fixup (dequeue)");
while (!worklist.empty()) {
MInstruction *ins = worklist.popCopy();
ins->setNotInWorklist();
RemoveTruncatesOnOutput(ins);
AdjustTruncatedInputs(ins);
}
return true;
}
示例9:
bool
CallPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
{
MCall *call = ins->toCall();
MDefinition *func = call->getFunction();
if (func->type() != MIRType_Object) {
MInstruction *unbox = MUnbox::New(alloc, func, MIRType_Object, MUnbox::Fallible);
call->block()->insertBefore(call, unbox);
call->replaceFunction(unbox);
if (!unbox->typePolicy()->adjustInputs(alloc, unbox))
return false;
}
for (uint32_t i = 0; i < call->numStackArgs(); i++)
EnsureOperandNotFloat32(alloc, call, MCall::IndexOfStackArg(i));
return true;
}
示例10: LoopContainsPossibleCall
// Test whether any instruction in the loop possiblyCalls().
static bool
LoopContainsPossibleCall(MIRGraph &graph, MBasicBlock *header, MBasicBlock *backedge)
{
for (auto i(graph.rpoBegin(header)); ; ++i) {
MOZ_ASSERT(i != graph.rpoEnd(), "Reached end of graph searching for blocks in loop");
MBasicBlock *block = *i;
if (!block->isMarked())
continue;
for (auto insIter(block->begin()), insEnd(block->end()); insIter != insEnd; ++insIter) {
MInstruction *ins = *insIter;
if (ins->possiblyCalls()) {
JitSpew(JitSpew_LICM, " Possile call found at %s%u", ins->opName(), ins->id());
return true;
}
}
if (block == backedge)
break;
}
return false;
}
示例11: iterateLoopBlocks
Loop::LoopReturn
Loop::iterateLoopBlocks(MBasicBlock *current)
{
// Visited.
current->mark();
// Hoisting requires more finesse if the loop contains a block that
// self-dominates: there exists control flow that may enter the loop
// without passing through the loop preheader.
//
// Rather than perform a complicated analysis of the dominance graph,
// just return a soft error to ignore this loop.
if (current->immediateDominator() == current)
return LoopReturn_Skip;
// If we haven't reached the loop header yet, recursively explore predecessors
// if we haven't seen them already.
if (current != header_) {
for (size_t i = 0; i < current->numPredecessors(); i++) {
if (current->getPredecessor(i)->isMarked())
continue;
LoopReturn lr = iterateLoopBlocks(current->getPredecessor(i));
if (lr != LoopReturn_Success)
return lr;
}
}
// Add all instructions in this block (but the control instruction) to the worklist
for (MInstructionIterator i = current->begin(); i != current->end(); i++) {
MInstruction *ins = *i;
if (ins->isMovable() && !ins->isEffectful()) {
if (!insertInWorklist(ins))
return LoopReturn_Error;
}
}
return LoopReturn_Success;
}
示例12: MoveDeferredOperands
// In preparation for hoisting an instruction, hoist any of its operands which
// were too cheap to hoist on their own.
static void
MoveDeferredOperands(MInstruction *ins, MInstruction *hoistPoint, bool hasCalls)
{
// If any of our operands were waiting for a user to be hoisted, make a note
// to hoist them.
for (size_t i = 0, e = ins->numOperands(); i != e; ++i) {
MDefinition *op = ins->getOperand(i);
if (!IsInLoop(op))
continue;
MOZ_ASSERT(RequiresHoistedUse(op, hasCalls),
"Deferred loop-invariant operand is not cheap");
MInstruction *opIns = op->toInstruction();
// Recursively move the operands. Note that the recursion is bounded
// because we require RequiresHoistedUse to be set at each level.
MoveDeferredOperands(opIns, hoistPoint, hasCalls);
JitSpew(JitSpew_LICM, " Hoisting %s%u (now that a user will be hoisted)",
opIns->opName(), opIns->id());
opIns->block()->moveBefore(hoistPoint, opIns);
}
}
示例13: MOZ_ASSERT
bool
SimdShufflePolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
{
MSimdGeneralShuffle* s = ins->toSimdGeneralShuffle();
for (unsigned i = 0; i < s->numVectors(); i++)
MOZ_ASSERT(ins->getOperand(i)->type() == ins->typePolicySpecialization());
// Next inputs are the lanes, which need to be int32
for (unsigned i = 0; i < s->numLanes(); i++) {
MDefinition* in = ins->getOperand(s->numVectors() + i);
if (in->type() == MIRType_Int32)
continue;
MInstruction* replace = MToInt32::New(alloc, in, MacroAssembler::IntConversion_NumbersOnly);
ins->block()->insertBefore(ins, replace);
ins->replaceOperand(s->numVectors() + i, replace);
if (!replace->typePolicy()->adjustInputs(alloc, replace))
return false;
}
return true;
}
示例14: MOZ_ASSERT
bool
SimdScalarPolicy<Op>::staticAdjustInputs(TempAllocator &alloc, MInstruction *ins)
{
MOZ_ASSERT(IsSimdType(ins->type()));
MIRType scalarType = SimdTypeToScalarType(ins->type());
MDefinition *in = ins->getOperand(Op);
if (in->type() == scalarType)
return true;
MInstruction *replace;
if (scalarType == MIRType_Int32) {
replace = MTruncateToInt32::New(alloc, in);
} else {
MOZ_ASSERT(scalarType == MIRType_Float32);
replace = MToFloat32::New(alloc, in);
}
ins->block()->insertBefore(ins, replace);
ins->replaceOperand(Op, replace);
return replace->typePolicy()->adjustInputs(alloc, replace);
}
示例15: inputs
void
LoopUnroller::makeReplacementInstruction(MInstruction *ins)
{
MDefinitionVector inputs(alloc);
for (size_t i = 0; i < ins->numOperands(); i++) {
MDefinition *old = ins->getOperand(i);
MDefinition *replacement = getReplacementDefinition(old);
if (!inputs.append(replacement))
CrashAtUnhandlableOOM("LoopUnroller::makeReplacementDefinition");
}
MInstruction *clone = ins->clone(alloc, inputs);
unrolledBackedge->add(clone);
if (!unrolledDefinitions.putNew(ins, clone))
CrashAtUnhandlableOOM("LoopUnroller::makeReplacementDefinition");
if (MResumePoint *old = ins->resumePoint()) {
MResumePoint *rp = makeReplacementResumePoint(unrolledBackedge, old);
clone->setResumePoint(rp);
}
}