本文整理汇总了C++中MDefinition::isConstant方法的典型用法代码示例。如果您正苦于以下问题:C++ MDefinition::isConstant方法的具体用法?C++ MDefinition::isConstant怎么用?C++ MDefinition::isConstant使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类MDefinition
的用法示例。
在下文中一共展示了MDefinition::isConstant方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: if
void
MBasicBlock::linkOsrValues(MStart *start)
{
JS_ASSERT(start->startType() == MStart::StartType_Osr);
MResumePoint *res = start->resumePoint();
for (uint32_t i = 0; i < stackDepth(); i++) {
MDefinition *def = slots_[i];
if (i == info().scopeChainSlot()) {
if (def->isOsrScopeChain())
def->toOsrScopeChain()->setResumePoint(res);
} else if (info().hasArguments() && i == info().argsObjSlot()) {
JS_ASSERT(def->isConstant() || def->isOsrArgumentsObject());
JS_ASSERT_IF(def->isConstant(), def->toConstant()->value() == UndefinedValue());
if (def->isOsrArgumentsObject())
def->toOsrArgumentsObject()->setResumePoint(res);
} else {
JS_ASSERT(def->isOsrValue() || def->isGetArgumentsObjectArg() || def->isConstant());
// A constant Undefined can show up here for an argument slot when the function uses
// a heavyweight argsobj, but the argument in question is stored on the scope chain.
JS_ASSERT_IF(def->isConstant(), def->toConstant()->value() == UndefinedValue());
if (def->isOsrValue())
def->toOsrValue()->setResumePoint(res);
else if (def->isGetArgumentsObjectArg())
def->toGetArgumentsObjectArg()->setResumePoint(res);
}
}
}
示例2: it
LSnapshot *
LIRGeneratorShared::buildSnapshot(LInstruction *ins, MResumePoint *rp, BailoutKind kind)
{
LRecoverInfo *recoverInfo = getRecoverInfo(rp);
if (!recoverInfo)
return nullptr;
LSnapshot *snapshot = LSnapshot::New(gen, recoverInfo, kind);
if (!snapshot)
return nullptr;
size_t index = 0;
LRecoverInfo::OperandIter it(recoverInfo->begin());
LRecoverInfo::OperandIter end(recoverInfo->end());
for (; it != end; ++it) {
// Check that optimized out operands are in eliminable slots.
MOZ_ASSERT(it.canOptimizeOutIfUnused());
MDefinition *ins = *it;
if (ins->isRecoveredOnBailout())
continue;
LAllocation *type = snapshot->typeOfSlot(index);
LAllocation *payload = snapshot->payloadOfSlot(index);
++index;
if (ins->isBox())
ins = ins->toBox()->getOperand(0);
// Guards should never be eliminated.
MOZ_ASSERT_IF(ins->isUnused(), !ins->isGuard());
// Snapshot operands other than constants should never be
// emitted-at-uses. Try-catch support depends on there being no
// code between an instruction and the LOsiPoint that follows it.
MOZ_ASSERT_IF(!ins->isConstant(), !ins->isEmittedAtUses());
// The register allocation will fill these fields in with actual
// register/stack assignments. During code generation, we can restore
// interpreter state with the given information. Note that for
// constants, including known types, we record a dummy placeholder,
// since we can recover the same information, much cleaner, from MIR.
if (ins->isConstant() || ins->isUnused()) {
*type = LConstantIndex::Bogus();
*payload = LConstantIndex::Bogus();
} else if (ins->type() != MIRType_Value) {
*type = LConstantIndex::Bogus();
*payload = use(ins, LUse(LUse::KEEPALIVE));
} else {
*type = useType(ins, LUse::KEEPALIVE);
*payload = usePayload(ins, LUse::KEEPALIVE);
}
}
return snapshot;
}
示例3: JitSpew
// Transform:
//
// [AddI]
// addl $9, %esi
// [LoadUnboxedScalar]
// movsd 0x0(%rbx,%rsi,8), %xmm4
//
// into:
//
// [LoadUnboxedScalar]
// movsd 0x48(%rbx,%rsi,8), %xmm4
//
// This is possible when the AddI is only used by the LoadUnboxedScalar opcode.
static void
AnalyzeLoadUnboxedScalar(TempAllocator& alloc, MLoadUnboxedScalar* load)
{
if (load->isRecoveredOnBailout())
return;
if (!load->getOperand(1)->isAdd())
return;
JitSpew(JitSpew_EAA, "analyze: %s%u", load->opName(), load->id());
MAdd* add = load->getOperand(1)->toAdd();
if (add->specialization() != MIRType::Int32 || !add->hasUses() ||
add->truncateKind() != MDefinition::TruncateKind::Truncate)
{
return;
}
MDefinition* lhs = add->lhs();
MDefinition* rhs = add->rhs();
MDefinition* constant = nullptr;
MDefinition* node = nullptr;
if (lhs->isConstant()) {
constant = lhs;
node = rhs;
} else if (rhs->isConstant()) {
constant = rhs;
node = lhs;
} else
return;
MOZ_ASSERT(constant->type() == MIRType::Int32);
size_t storageSize = Scalar::byteSize(load->storageType());
int32_t c1 = load->offsetAdjustment();
int32_t c2 = 0;
if (!SafeMul(constant->maybeConstantValue()->toInt32(), storageSize, &c2))
return;
int32_t offset = 0;
if (!SafeAdd(c1, c2, &offset))
return;
JitSpew(JitSpew_EAA, "set offset: %d + %d = %d on: %s%u", c1, c2, offset,
load->opName(), load->id());
load->setOffsetAdjustment(offset);
load->replaceOperand(1, node);
if (!add->hasLiveDefUses() && DeadIfUnused(add) && add->canRecoverOnBailout()) {
JitSpew(JitSpew_EAA, "mark as recovered on bailout: %s%u",
add->opName(), add->id());
add->setRecoveredOnBailoutUnchecked();
}
}
示例4: iter
LSnapshot *
LIRGeneratorShared::buildSnapshot(LInstruction *ins, MResumePoint *rp, BailoutKind kind)
{
LSnapshot *snapshot = LSnapshot::New(gen, rp, kind);
if (!snapshot)
return NULL;
FlattenedMResumePointIter iter(rp);
if (!iter.init())
return NULL;
size_t i = 0;
for (MResumePoint **it = iter.begin(), **end = iter.end(); it != end; ++it) {
MResumePoint *mir = *it;
for (size_t j = 0, e = mir->numOperands(); j < e; ++i, ++j) {
MDefinition *ins = mir->getOperand(j);
LAllocation *type = snapshot->typeOfSlot(i);
LAllocation *payload = snapshot->payloadOfSlot(i);
if (ins->isPassArg())
ins = ins->toPassArg()->getArgument();
JS_ASSERT(!ins->isPassArg());
if (ins->isBox())
ins = ins->toBox()->getOperand(0);
// Guards should never be eliminated.
JS_ASSERT_IF(ins->isUnused(), !ins->isGuard());
// Snapshot operands other than constants should never be
// emitted-at-uses. Try-catch support depends on there being no
// code between an instruction and the LOsiPoint that follows it.
JS_ASSERT_IF(!ins->isConstant(), !ins->isEmittedAtUses());
// The register allocation will fill these fields in with actual
// register/stack assignments. During code generation, we can restore
// interpreter state with the given information. Note that for
// constants, including known types, we record a dummy placeholder,
// since we can recover the same information, much cleaner, from MIR.
if (ins->isConstant() || ins->isUnused()) {
*type = LConstantIndex::Bogus();
*payload = LConstantIndex::Bogus();
} else if (ins->type() != MIRType_Value) {
*type = LConstantIndex::Bogus();
*payload = use(ins, LUse::KEEPALIVE);
} else {
*type = useType(ins, LUse::KEEPALIVE);
*payload = usePayload(ins, LUse::KEEPALIVE);
}
}
}
return snapshot;
}
示例5:
static void
AnalyzeAsmHeapAddress(MDefinition* ptr, MIRGraph& graph)
{
// Fold (a+i)&m to (a&m)+i, provided that this doesn't change the result,
// since the users of the BitAnd include heap accesses. This will expose
// the redundancy for GVN when expressions like this:
// a&m
// (a+1)&m,
// (a+2)&m,
// are transformed into this:
// a&m
// (a&m)+1
// (a&m)+2
// and it will allow the constants to be folded by the
// EffectiveAddressAnalysis pass.
//
// Putting the add on the outside might seem like it exposes other users of
// the expression to the possibility of i32 overflow, if we aren't in wasm
// and they aren't naturally truncating. However, since we use MAdd::New
// with MIRType::Int32, we make sure that the value is truncated, just as it
// would be by the MBitAnd.
MOZ_ASSERT(IsCompilingWasm());
if (!ptr->isBitAnd())
return;
MDefinition* lhs = ptr->toBitAnd()->getOperand(0);
MDefinition* rhs = ptr->toBitAnd()->getOperand(1);
if (lhs->isConstant())
mozilla::Swap(lhs, rhs);
if (!lhs->isAdd() || !rhs->isConstant())
return;
MDefinition* op0 = lhs->toAdd()->getOperand(0);
MDefinition* op1 = lhs->toAdd()->getOperand(1);
if (op0->isConstant())
mozilla::Swap(op0, op1);
if (!op1->isConstant())
return;
uint32_t i = op1->toConstant()->toInt32();
uint32_t m = rhs->toConstant()->toInt32();
if (!IsAlignmentMask(m) || (i & m) != i)
return;
// The pattern was matched! Produce the replacement expression.
MInstruction* and_ = MBitAnd::New(graph.alloc(), op0, rhs, MIRType::Int32);
ptr->block()->insertBefore(ptr->toBitAnd(), and_);
MInstruction* add = MAdd::New(graph.alloc(), and_, op1, MIRType::Int32);
ptr->block()->insertBefore(ptr->toBitAnd(), add);
ptr->replaceAllUsesWith(add);
ptr->block()->discard(ptr->toBitAnd());
}
示例6: emitAtUses
bool
LIRGeneratorX64::visitBox(MBox *box)
{
MDefinition *opd = box->getOperand(0);
// If the operand is a constant, emit near its uses.
if (opd->isConstant() && box->canEmitAtUses())
return emitAtUses(box);
if (opd->isConstant())
return define(new LValue(opd->toConstant()->value()), box, LDefinition(LDefinition::BOX));
LBox *ins = new LBox(opd->type(), useRegister(opd));
return define(ins, box, LDefinition(LDefinition::BOX));
}
示例7: if
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;
}
示例8: defineBox
bool
LIRGeneratorARM::visitBox(MBox *box)
{
MDefinition *inner = box->getOperand(0);
// If the box wrapped a double, it needs a new register.
if (inner->type() == MIRType_Double)
return defineBox(new LBoxDouble(useRegisterAtStart(inner), tempCopy(inner, 0)), box);
if (box->canEmitAtUses())
return emitAtUses(box);
if (inner->isConstant())
return defineBox(new LValue(inner->toConstant()->value()), box);
LBox *lir = new LBox(use(inner), inner->type());
// Otherwise, we should not define a new register for the payload portion
// of the output, so bypass defineBox().
uint32_t vreg = getVirtualRegister();
if (vreg >= MAX_VIRTUAL_REGISTERS)
return false;
// Note that because we're using PASSTHROUGH, we do not change the type of
// the definition. We also do not define the first output as "TYPE",
// because it has no corresponding payload at (vreg + 1). Also note that
// although we copy the input's original type for the payload half of the
// definition, this is only for clarity. PASSTHROUGH definitions are
// ignored.
lir->setDef(0, LDefinition(vreg, LDefinition::GENERAL));
lir->setDef(1, LDefinition(inner->virtualRegister(), LDefinition::TypeFrom(inner->type()),
LDefinition::PASSTHROUGH));
box->setVirtualRegister(vreg);
return add(lir);
}
示例9: while
// Determine whether the possible value of start (a phi node within the loop)
// can become smaller than an initial value at loop entry.
bool
Loop::nonDecreasing(MDefinition *initial, MDefinition *start)
{
MDefinitionVector worklist;
MDefinitionVector seen;
if (!worklist.append(start))
return false;
while (!worklist.empty()) {
MDefinition *def = worklist.popCopy();
bool duplicate = false;
for (size_t i = 0; i < seen.length() && !duplicate; i++) {
if (seen[i] == def)
duplicate = true;
}
if (duplicate)
continue;
if (!seen.append(def))
return false;
if (def->type() != MIRType_Int32)
return false;
if (!isInLoop(def)) {
if (def != initial)
return false;
continue;
}
if (def->isPhi()) {
MPhi *phi = def->toPhi();
for (size_t i = 0; i < phi->numOperands(); i++) {
if (!worklist.append(phi->getOperand(i)))
return false;
}
continue;
}
if (def->isAdd()) {
if (def->toAdd()->specialization() != MIRType_Int32)
return false;
MDefinition *lhs = def->toAdd()->getOperand(0);
MDefinition *rhs = def->toAdd()->getOperand(1);
if (!rhs->isConstant())
return false;
Value v = rhs->toConstant()->value();
if (!v.isInt32() || v.toInt32() < 0)
return false;
if (!worklist.append(lhs))
return false;
continue;
}
return false;
}
return true;
}
示例10: visitBox
void LIRGenerator::visitBox(MBox* box) {
MDefinition* opd = box->getOperand(0);
// If the operand is a constant, emit near its uses.
if (opd->isConstant() && box->canEmitAtUses()) {
emitAtUses(box);
return;
}
if (opd->isConstant()) {
define(new (alloc()) LValue(opd->toConstant()->toJSValue()), box,
LDefinition(LDefinition::BOX));
} else {
LBox* ins = new (alloc()) LBox(useRegister(opd), opd->type());
define(ins, box, LDefinition(LDefinition::BOX));
}
}
示例11: other
void
MRsh::computeRange()
{
MDefinition *right = getOperand(1);
if (!right->isConstant())
return;
int32_t c = right->toConstant()->value().toInt32();
Range other(getOperand(0));
setRange(Range::shr(&other, c));
}
示例12: getOperand
void
MLsh::computeRange()
{
MDefinition *right = getOperand(1);
if (!right->isConstant())
return;
int32 c = right->toConstant()->value().toInt32();
const Range *other = getOperand(0)->range();
setRange(Range::shl(other, c));
}
示例13: LAllocation
void
LIRGeneratorX86::visitAsmJSStoreHeap(MAsmJSStoreHeap *ins)
{
MDefinition *ptr = ins->ptr();
LAsmJSStoreHeap *lir;
MOZ_ASSERT(ptr->type() == MIRType_Int32);
if (ptr->isConstant() && !ins->needsBoundsCheck()) {
MOZ_ASSERT(ptr->toConstant()->value().toInt32() >= 0);
LAllocation ptrAlloc = LAllocation(ptr->toConstant()->vp());
switch (ins->accessType()) {
case Scalar::Int8: case Scalar::Uint8:
// See comment below.
lir = new(alloc()) LAsmJSStoreHeap(ptrAlloc, useFixed(ins->value(), eax));
break;
case Scalar::Int16: case Scalar::Uint16:
case Scalar::Int32: case Scalar::Uint32:
case Scalar::Float32: case Scalar::Float64:
case Scalar::Float32x4: case Scalar::Int32x4:
// See comment below.
lir = new(alloc()) LAsmJSStoreHeap(ptrAlloc, useRegisterAtStart(ins->value()));
break;
case Scalar::Uint8Clamped:
case Scalar::MaxTypedArrayViewType:
MOZ_CRASH("unexpected array type");
}
add(lir, ins);
return;
}
switch (ins->accessType()) {
case Scalar::Int8: case Scalar::Uint8:
// See comment for LIRGeneratorX86::useByteOpRegister.
lir = new(alloc()) LAsmJSStoreHeap(useRegister(ins->ptr()), useFixed(ins->value(), eax));
break;
case Scalar::Int16: case Scalar::Uint16:
case Scalar::Int32: case Scalar::Uint32:
case Scalar::Float32: case Scalar::Float64:
case Scalar::Float32x4: case Scalar::Int32x4:
// For now, don't allow constant values. The immediate operand
// affects instruction layout which affects patching.
lir = new(alloc()) LAsmJSStoreHeap(useRegisterAtStart(ptr), useRegisterAtStart(ins->value()));
break;
case Scalar::Uint8Clamped:
case Scalar::MaxTypedArrayViewType:
MOZ_CRASH("unexpected array type");
}
add(lir, ins);
}
示例14: New
MDefinition *
MTruncateToInt32::foldsTo(bool useValueNumbers)
{
MDefinition *input = getOperand(0);
if (input->type() == MIRType_Int32)
return input;
if (input->type() == MIRType_Double && input->isConstant()) {
const Value &v = input->toConstant()->value();
uint32 ret = ToInt32(v.toDouble());
return MConstant::New(Int32Value(ret));
}
return this;
}
示例15: LAllocation
void
LIRGeneratorPPC::visitAsmJSStoreHeap(MAsmJSStoreHeap *ins)
{
MDefinition *ptr = ins->ptr();
MOZ_ASSERT(ptr->type() == MIRType_Int32);
LAllocation ptrAlloc;
if (ptr->isConstant() && !ins->needsBoundsCheck()) {
MOZ_ASSERT(ptr->toConstant()->value().toInt32() >= 0);
ptrAlloc = LAllocation(ptr->toConstant()->vp());
} else
ptrAlloc = useRegisterAtStart(ptr);
add(new(alloc()) LAsmJSStoreHeap(ptrAlloc, useRegisterAtStart(ins->value())), ins);
}