Bug 1107328 - IonMonkey: Also check for boxed constants when checking for constants, r=jandem

This commit is contained in:
Hannes Verschore 2014-12-22 13:16:48 +01:00
parent b90d771c94
commit 2642d1cb91
11 changed files with 194 additions and 149 deletions

View File

@ -21,10 +21,10 @@ AnalyzeLsh(TempAllocator &alloc, MLsh *lsh)
MOZ_ASSERT(index->type() == MIRType_Int32);
MDefinition *shift = lsh->rhs();
if (!shift->isConstant())
if (!shift->isConstantValue())
return;
Value shiftValue = shift->toConstant()->value();
Value shiftValue = shift->constantValue();
if (!shiftValue.isInt32() || !IsShiftInScaleRange(shiftValue.toInt32()))
return;
@ -47,8 +47,8 @@ AnalyzeLsh(TempAllocator &alloc, MLsh *lsh)
MDefinition *other = add->getOperand(1 - add->indexOf(*use));
if (other->isConstant()) {
displacement += other->toConstant()->value().toInt32();
if (other->isConstantValue()) {
displacement += other->constantValue().toInt32();
} else {
if (base)
break;
@ -72,11 +72,11 @@ AnalyzeLsh(TempAllocator &alloc, MLsh *lsh)
MBitAnd *bitAnd = use->consumer()->toDefinition()->toBitAnd();
MDefinition *other = bitAnd->getOperand(1 - bitAnd->indexOf(*use));
if (!other->isConstant() || !other->toConstant()->value().isInt32())
if (!other->isConstantValue() || !other->constantValue().isInt32())
return;
uint32_t bitsClearedByShift = elemSize - 1;
uint32_t bitsClearedByMask = ~uint32_t(other->toConstant()->value().toInt32());
uint32_t bitsClearedByMask = ~uint32_t(other->constantValue().toInt32());
if ((bitsClearedByShift & bitsClearedByMask) != bitsClearedByMask)
return;

View File

@ -260,7 +260,7 @@ MaybeFoldConditionBlock(MIRGraph &graph, MBasicBlock *initialBlock)
MBasicBlock *trueTarget = trueBranch;
if (BlockComputesConstant(trueBranch, trueResult)) {
trueTarget = trueResult->toConstant()->valueToBoolean()
trueTarget = trueResult->constantToBoolean()
? finalTest->ifTrue()
: finalTest->ifFalse();
testBlock->removePredecessor(trueBranch);
@ -272,7 +272,7 @@ MaybeFoldConditionBlock(MIRGraph &graph, MBasicBlock *initialBlock)
MBasicBlock *falseTarget = falseBranch;
if (BlockComputesConstant(falseBranch, falseResult)) {
falseTarget = falseResult->toConstant()->valueToBoolean()
falseTarget = falseResult->constantToBoolean()
? finalTest->ifTrue()
: finalTest->ifFalse();
testBlock->removePredecessor(falseBranch);
@ -2270,8 +2270,8 @@ jit::ExtractLinearSum(MDefinition *ins)
if (ins->type() != MIRType_Int32)
return SimpleLinearSum(ins, 0);
if (ins->isConstant()) {
const Value &v = ins->toConstant()->value();
if (ins->isConstantValue()) {
const Value &v = ins->constantValue();
MOZ_ASSERT(v.isInt32());
return SimpleLinearSum(nullptr, v.toInt32());
} else if (ins->isAdd() || ins->isSub()) {
@ -2672,8 +2672,8 @@ LinearSum::add(MDefinition *term, int32_t scale)
if (scale == 0)
return true;
if (term->isConstant()) {
int32_t constant = term->toConstant()->value().toInt32();
if (term->isConstantValue()) {
int32_t constant = term->constantValue().toInt32();
if (!SafeMul(constant, scale, &constant))
return false;
return add(constant);
@ -2751,7 +2751,7 @@ jit::ConvertLinearSum(TempAllocator &alloc, MBasicBlock *block, const LinearSum
for (size_t i = 0; i < sum.numTerms(); i++) {
LinearTerm term = sum.term(i);
MOZ_ASSERT(!term.term->isConstant());
MOZ_ASSERT(!term.term->isConstantValue());
if (term.scale == 1) {
if (def) {
def = MAdd::New(alloc, def, term.term);

View File

@ -2261,9 +2261,8 @@ IonBuilder::processDoWhileCondEnd(CFGState &state)
return ControlStatus_Error;
// Test for do {} while(false) and don't create a loop in that case.
if (vins->isConstant()) {
MConstant *cte = vins->toConstant();
if (cte->value().isBoolean() && !cte->value().toBoolean()) {
if (vins->isConstantValue() && !vins->constantValue().isMagic()) {
if (!vins->constantToBoolean()) {
current->end(MGoto::New(alloc(), successor));
current = nullptr;
@ -4568,7 +4567,7 @@ IonBuilder::makeInliningDecision(JSObject *targetArg, CallInfo &callInfo)
bool hasOpportunities = false;
for (size_t i = 0, e = callInfo.argv().length(); !hasOpportunities && i < e; i++) {
MDefinition *arg = callInfo.argv()[i];
hasOpportunities = arg->isLambda() || arg->isConstant();
hasOpportunities = arg->isLambda() || arg->isConstantValue();
}
if (!hasOpportunities)
@ -5930,10 +5929,10 @@ IonBuilder::jsop_eval(uint32_t argc)
// name on the scope chain and the eval is performing a call on that
// value. Use a dynamic scope chain lookup rather than a full eval.
if (string->isConcat() &&
string->getOperand(1)->isConstant() &&
string->getOperand(1)->toConstant()->value().isString())
string->getOperand(1)->isConstantValue() &&
string->getOperand(1)->constantValue().isString())
{
JSAtom *atom = &string->getOperand(1)->toConstant()->value().toString()->asAtom();
JSAtom *atom = &string->getOperand(1)->constantValue().toString()->asAtom();
if (StringEqualsAscii(atom, "()")) {
MDefinition *name = string->getOperand(0);
@ -7846,10 +7845,10 @@ IonBuilder::getElemTryArgumentsInlined(bool *emitted, MDefinition *obj, MDefinit
MOZ_ASSERT(!info().argsObjAliasesFormals());
// When the id is constant, we can just return the corresponding inlined argument
if (index->isConstant() && index->toConstant()->value().isInt32()) {
if (index->isConstantValue() && index->constantValue().isInt32()) {
MOZ_ASSERT(inliningDepth_ > 0);
int32_t id = index->toConstant()->value().toInt32();
int32_t id = index->constantValue().toInt32();
index->setImplicitlyUsedUnchecked();
if (id < (int32_t)inlineCallInfo_->argc() && id >= 0)
@ -8065,8 +8064,8 @@ IonBuilder::addTypedArrayLengthAndData(MDefinition *obj,
MOZ_ASSERT((index != nullptr) == (elements != nullptr));
JSObject *tarr = nullptr;
if (obj->isConstant() && obj->toConstant()->value().isObject())
tarr = &obj->toConstant()->value().toObject();
if (obj->isConstantValue() && obj->constantValue().isObject())
tarr = &obj->constantValue().toObject();
else if (obj->resultTypeSet())
tarr = obj->resultTypeSet()->getSingleton();
@ -8123,8 +8122,8 @@ IonBuilder::convertShiftToMaskForStaticTypedArray(MDefinition *id,
// If the index is an already shifted constant, undo the shift to get the
// absolute offset being accessed.
if (id->isConstant() && id->toConstant()->value().isInt32()) {
int32_t index = id->toConstant()->value().toInt32();
if (id->isConstantValue() && id->constantValue().isInt32()) {
int32_t index = id->constantValue().toInt32();
MConstant *offset = MConstant::New(alloc(), Int32Value(index << TypedArrayShift(viewType)));
current->add(offset);
return offset;
@ -8132,9 +8131,9 @@ IonBuilder::convertShiftToMaskForStaticTypedArray(MDefinition *id,
if (!id->isRsh() || id->isEffectful())
return nullptr;
if (!id->getOperand(1)->isConstant())
if (!id->getOperand(1)->isConstantValue())
return nullptr;
const Value &value = id->getOperand(1)->toConstant()->value();
const Value &value = id->getOperand(1)->constantValue();
if (!value.isInt32() || uint32_t(value.toInt32()) != TypedArrayShift(viewType))
return nullptr;

View File

@ -623,7 +623,7 @@ ReorderComparison(JSOp op, MDefinition **lhsp, MDefinition **rhsp)
MDefinition *lhs = *lhsp;
MDefinition *rhs = *rhsp;
if (lhs->isConstant()) {
if (lhs->isConstantValue()) {
*rhsp = lhs;
*lhsp = rhs;
return ReverseCompareOp(op);
@ -643,8 +643,8 @@ LIRGenerator::visitTest(MTest *test)
MOZ_ASSERT(opd->type() != MIRType_String);
// Testing a constant.
if (opd->isConstant()) {
bool result = opd->toConstant()->valueToBoolean();
if (opd->isConstantValue() && !opd->constantValue().isMagic()) {
bool result = opd->constantToBoolean();
add(new(alloc()) LGoto(result ? ifTrue : ifFalse));
return;
}
@ -1491,7 +1491,7 @@ LIRGenerator::visitMul(MMul *ins)
// If our RHS is a constant -1 and we don't have to worry about
// overflow, we can optimize to an LNegI.
if (!ins->fallible() && rhs->isConstant() && rhs->toConstant()->value() == Int32Value(-1))
if (!ins->fallible() && rhs->isConstantValue() && rhs->constantValue() == Int32Value(-1))
defineReuseInput(new(alloc()) LNegI(useRegisterAtStart(lhs)), ins, 0);
else
lowerMulI(ins, lhs, rhs);
@ -1500,7 +1500,7 @@ LIRGenerator::visitMul(MMul *ins)
ReorderCommutative(&lhs, &rhs, ins);
// If our RHS is a constant -1.0, we can optimize to an LNegD.
if (rhs->isConstant() && rhs->toConstant()->value() == DoubleValue(-1.0))
if (rhs->isConstantValue() && rhs->constantValue() == DoubleValue(-1.0))
defineReuseInput(new(alloc()) LNegD(useRegisterAtStart(lhs)), ins, 0);
else
lowerForFPU(new(alloc()) LMathD(JSOP_MUL), ins, lhs, rhs);
@ -1509,7 +1509,7 @@ LIRGenerator::visitMul(MMul *ins)
ReorderCommutative(&lhs, &rhs, ins);
// We apply the same optimizations as for doubles
if (rhs->isConstant() && rhs->toConstant()->value() == Float32Value(-1.0f))
if (rhs->isConstantValue() && rhs->constantValue() == Float32Value(-1.0f))
defineReuseInput(new(alloc()) LNegF(useRegisterAtStart(lhs)), ins, 0);
else
lowerForFPU(new(alloc()) LMathF(JSOP_MUL), ins, lhs, rhs);

View File

@ -378,7 +378,7 @@ IonBuilder::inlineArray(CallInfo &callInfo)
return InliningStatus_NotInlined;
MDefinition *arg = callInfo.getArg(0);
if (!arg->isConstant()) {
if (!arg->isConstantValue()) {
callInfo.setImplicitlyUsedUnchecked();
ArrayObject *templateArray = &templateObject->as<ArrayObject>();
MNewArrayDynamicLength *ins =
@ -391,7 +391,7 @@ IonBuilder::inlineArray(CallInfo &callInfo)
}
// Negative lengths generate a RangeError, unhandled by the inline path.
initLength = arg->toConstant()->value().toInt32();
initLength = arg->constantValue().toInt32();
if (initLength >= NativeObject::NELEMENTS_LIMIT)
return InliningStatus_NotInlined;
@ -1038,10 +1038,10 @@ IonBuilder::inlineMathPow(CallInfo &callInfo)
MDefinition *output = nullptr;
// Optimize some constant powers.
if (callInfo.getArg(1)->isConstant() &&
callInfo.getArg(1)->toConstant()->value().isNumber())
if (callInfo.getArg(1)->isConstantValue() &&
callInfo.getArg(1)->constantValue().isNumber())
{
double pow = callInfo.getArg(1)->toConstant()->value().toNumber();
double pow = callInfo.getArg(1)->constantValue().toNumber();
// Math.pow(x, 0.5) is a sqrt with edge-case detection.
if (pow == 0.5) {
@ -1216,8 +1216,8 @@ IonBuilder::inlineMathMinMax(CallInfo &callInfo, bool max)
case MIRType_Float32:
// Don't force a double MMinMax for arguments that would be a NOP
// when doing an integer MMinMax.
if (arg->isConstant()) {
double cte = arg->toConstant()->value().toDouble();
if (arg->isConstantValue()) {
double cte = arg->constantValue().toDouble();
// min(int32, cte >= INT32_MAX) = int32
if (cte >= INT32_MAX && !max)
break;
@ -1368,14 +1368,14 @@ IonBuilder::inlineStrCharCodeAt(CallInfo &callInfo)
IonBuilder::InliningStatus
IonBuilder::inlineConstantCharCodeAt(CallInfo &callInfo)
{
if (!callInfo.thisArg()->isConstant())
if (!callInfo.thisArg()->isConstantValue())
return InliningStatus_NotInlined;
if (!callInfo.getArg(0)->isConstant())
if (!callInfo.getArg(0)->isConstantValue())
return InliningStatus_NotInlined;
const js::Value *strval = callInfo.thisArg()->toConstant()->vp();
const js::Value *idxval = callInfo.getArg(0)->toConstant()->vp();
const js::Value *strval = callInfo.thisArg()->constantVp();
const js::Value *idxval = callInfo.getArg(0)->constantVp();
if (!strval->isString() || !idxval->isInt32())
return InliningStatus_NotInlined;
@ -2033,9 +2033,9 @@ IonBuilder::inlineUnsafeSetReservedSlot(CallInfo &callInfo)
// Don't inline if we don't have a constant slot.
MDefinition *arg = callInfo.getArg(1);
if (!arg->isConstant())
if (!arg->isConstantValue())
return InliningStatus_NotInlined;
uint32_t slot = arg->toConstant()->value().toPrivateUint32();
uint32_t slot = arg->constantValue().toPrivateUint32();
callInfo.setImplicitlyUsedUnchecked();
@ -2061,9 +2061,9 @@ IonBuilder::inlineUnsafeGetReservedSlot(CallInfo &callInfo)
// Don't inline if we don't have a constant slot.
MDefinition *arg = callInfo.getArg(1);
if (!arg->isConstant())
if (!arg->isConstantValue())
return InliningStatus_NotInlined;
uint32_t slot = arg->toConstant()->value().toPrivateUint32();
uint32_t slot = arg->constantValue().toPrivateUint32();
callInfo.setImplicitlyUsedUnchecked();
@ -2259,9 +2259,9 @@ IonBuilder::inlineAssertFloat32(CallInfo &callInfo)
MDefinition *secondArg = callInfo.getArg(1);
MOZ_ASSERT(secondArg->type() == MIRType_Boolean);
MOZ_ASSERT(secondArg->isConstant());
MOZ_ASSERT(secondArg->isConstantValue());
bool mustBeFloat32 = secondArg->toConstant()->value().toBoolean();
bool mustBeFloat32 = secondArg->constantValue().toBoolean();
current->add(MAssertFloat32::New(alloc(), callInfo.getArg(0), mustBeFloat32));
MConstant *undefined = MConstant::New(alloc(), UndefinedValue());

View File

@ -71,17 +71,45 @@ MDefinition::PrintOpcodeName(FILE *fp, MDefinition::Opcode op)
fprintf(fp, "%c", tolower(name[i]));
}
const Value &
MDefinition::constantValue()
{
MOZ_ASSERT(isConstantValue());
if (isBox())
return getOperand(0)->constantValue();
return toConstant()->value();
}
const Value *
MDefinition::constantVp()
{
MOZ_ASSERT(isConstantValue());
if (isBox())
return getOperand(0)->constantVp();
return toConstant()->vp();
}
bool
MDefinition::constantToBoolean()
{
MOZ_ASSERT(isConstantValue());
if (isBox())
return getOperand(0)->constantToBoolean();
return toConstant()->valueToBoolean();
}
static MConstant *
EvaluateConstantOperands(TempAllocator &alloc, MBinaryInstruction *ins, bool *ptypeChange = nullptr)
{
MDefinition *left = ins->getOperand(0);
MDefinition *right = ins->getOperand(1);
if (!left->isConstant() || !right->isConstant())
if (!left->isConstantValue() || !right->isConstantValue())
return nullptr;
Value lhs = left->toConstant()->value();
Value rhs = right->toConstant()->value();
Value lhs = left->constantValue();
Value rhs = right->constantValue();
Value ret = UndefinedValue();
switch (ins->op()) {
@ -146,10 +174,10 @@ EvaluateExactReciprocal(TempAllocator &alloc, MDiv *ins)
MDefinition *left = ins->getOperand(0);
MDefinition *right = ins->getOperand(1);
if (!right->isConstant())
if (!right->isConstantValue())
return nullptr;
Value rhs = right->toConstant()->value();
Value rhs = right->constantValue();
int32_t num;
if (!mozilla::NumberIsInt32(rhs.toNumber(), &num))
@ -355,8 +383,8 @@ MTest::foldsTo(TempAllocator &alloc)
return MTest::New(alloc, op->toNot()->input(), ifFalse(), ifTrue());
}
if (op->isConstant())
return MGoto::New(alloc, op->toConstant()->valueToBoolean() ? ifTrue() : ifFalse());
if (op->isConstantValue() && !op->constantValue().isMagic())
return MGoto::New(alloc, op->constantToBoolean() ? ifTrue() : ifFalse());
switch (op->type()) {
case MIRType_Undefined:
@ -768,7 +796,7 @@ MSimdValueX4::foldsTo(TempAllocator &alloc)
for (size_t i = 0; i < 4; ++i) {
MDefinition *op = getOperand(i);
MOZ_ASSERT(op->type() == scalarType);
if (!op->isConstant())
if (!op->isConstantValue())
allConstants = false;
if (i > 0 && op != getOperand(i - 1))
allSame = false;
@ -783,14 +811,14 @@ MSimdValueX4::foldsTo(TempAllocator &alloc)
case MIRType_Int32x4: {
int32_t a[4];
for (size_t i = 0; i < 4; ++i)
a[i] = getOperand(i)->toConstant()->value().toInt32();
a[i] = getOperand(i)->constantValue().toInt32();
cst = SimdConstant::CreateX4(a);
break;
}
case MIRType_Float32x4: {
float a[4];
for (size_t i = 0; i < 4; ++i)
a[i] = getOperand(i)->toConstant()->value().toNumber();
a[i] = getOperand(i)->constantValue().toNumber();
cst = SimdConstant::CreateX4(a);
break;
}
@ -809,7 +837,7 @@ MSimdSplatX4::foldsTo(TempAllocator &alloc)
{
DebugOnly<MIRType> scalarType = SimdTypeToScalarType(type());
MDefinition *op = getOperand(0);
if (!op->isConstant())
if (!op->isConstantValue())
return this;
MOZ_ASSERT(op->type() == scalarType);
@ -817,7 +845,7 @@ MSimdSplatX4::foldsTo(TempAllocator &alloc)
switch (type()) {
case MIRType_Int32x4: {
int32_t a[4];
int32_t v = getOperand(0)->toConstant()->value().toInt32();
int32_t v = getOperand(0)->constantValue().toInt32();
for (size_t i = 0; i < 4; ++i)
a[i] = v;
cst = SimdConstant::CreateX4(a);
@ -825,7 +853,7 @@ MSimdSplatX4::foldsTo(TempAllocator &alloc)
}
case MIRType_Float32x4: {
float a[4];
float v = getOperand(0)->toConstant()->value().toNumber();
float v = getOperand(0)->constantValue().toNumber();
for (size_t i = 0; i < 4; ++i)
a[i] = v;
cst = SimdConstant::CreateX4(a);
@ -1096,8 +1124,8 @@ MApplyArgs::New(TempAllocator &alloc, JSFunction *target, MDefinition *fun, MDef
MDefinition*
MStringLength::foldsTo(TempAllocator &alloc)
{
if ((type() == MIRType_Int32) && (string()->isConstant())) {
Value value = string()->toConstant()->value();
if ((type() == MIRType_Int32) && (string()->isConstantValue())) {
Value value = string()->constantValue();
JSAtom *atom = &value.toString()->asAtom();
return MConstant::New(alloc, Int32Value(atom->length()));
}
@ -1884,12 +1912,10 @@ MMinMax::foldsTo(TempAllocator &alloc)
if (!lhs()->isConstant() && !rhs()->isConstant())
return this;
MDefinition *operand = lhs()->isConstant() ? rhs() : lhs();
MConstant *constant = lhs()->isConstant() ? lhs()->toConstant() : rhs()->toConstant();
MDefinition *operand = lhs()->isConstantValue() ? rhs() : lhs();
const js::Value &val = lhs()->isConstantValue() ? lhs()->constantValue() : rhs()->constantValue();
if (operand->isToDouble() && operand->getOperand(0)->type() == MIRType_Int32) {
const js::Value &val = constant->value();
// min(int32, cte >= INT32_MAX) = int32
if (val.isDouble() && val.toDouble() >= INT32_MAX && !isMax()) {
MLimitedTruncate *limit =
@ -1959,25 +1985,25 @@ MDiv::analyzeEdgeCasesForward()
return;
// Try removing divide by zero check
if (rhs()->isConstant() && !rhs()->toConstant()->value().isInt32(0))
if (rhs()->isConstantValue() && !rhs()->constantValue().isInt32(0))
canBeDivideByZero_ = false;
// If lhs is a constant int != INT32_MIN, then
// negative overflow check can be skipped.
if (lhs()->isConstant() && !lhs()->toConstant()->value().isInt32(INT32_MIN))
if (lhs()->isConstantValue() && !lhs()->constantValue().isInt32(INT32_MIN))
canBeNegativeOverflow_ = false;
// If rhs is a constant int != -1, likewise.
if (rhs()->isConstant() && !rhs()->toConstant()->value().isInt32(-1))
if (rhs()->isConstantValue() && !rhs()->constantValue().isInt32(-1))
canBeNegativeOverflow_ = false;
// If lhs is != 0, then negative zero check can be skipped.
if (lhs()->isConstant() && !lhs()->toConstant()->value().isInt32(0))
if (lhs()->isConstantValue() && !lhs()->constantValue().isInt32(0))
setCanBeNegativeZero(false);
// If rhs is >= 0, likewise.
if (rhs()->isConstant()) {
const js::Value &val = rhs()->toConstant()->value();
if (rhs()->isConstantValue()) {
const js::Value &val = rhs()->constantValue();
if (val.isInt32() && val.toInt32() >= 0)
setCanBeNegativeZero(false);
}
@ -2015,11 +2041,11 @@ MMod::analyzeEdgeCasesForward()
if (specialization_ != MIRType_Int32)
return;
if (rhs()->isConstant() && !rhs()->toConstant()->value().isInt32(0))
if (rhs()->isConstantValue() && !rhs()->constantValue().isInt32(0))
canBeDivideByZero_ = false;
if (rhs()->isConstant()) {
int32_t n = rhs()->toConstant()->value().toInt32();
if (rhs()->isConstantValue()) {
int32_t n = rhs()->constantValue().toInt32();
if (n > 0 && !IsPowerOfTwo(n))
canBePowerOfTwoDivisor_ = false;
}
@ -2093,15 +2119,15 @@ MMul::analyzeEdgeCasesForward()
return;
// If lhs is > 0, no need for negative zero check.
if (lhs()->isConstant()) {
const js::Value &val = lhs()->toConstant()->value();
if (lhs()->isConstantValue()) {
const js::Value &val = lhs()->constantValue();
if (val.isInt32() && val.toInt32() > 0)
setCanBeNegativeZero(false);
}
// If rhs is > 0, likewise.
if (rhs()->isConstant()) {
const js::Value &val = rhs()->toConstant()->value();
if (rhs()->isConstantValue()) {
const js::Value &val = rhs()->constantValue();
if (val.isInt32() && val.toInt32() > 0)
setCanBeNegativeZero(false);
}
@ -2370,15 +2396,15 @@ MustBeUInt32(MDefinition *def, MDefinition **pwrapped)
*pwrapped = def->toUrsh()->getOperand(0);
MDefinition *rhs = def->toUrsh()->getOperand(1);
return !def->toUrsh()->bailoutsDisabled()
&& rhs->isConstant()
&& rhs->toConstant()->value().isInt32()
&& rhs->toConstant()->value().toInt32() == 0;
&& rhs->isConstantValue()
&& rhs->constantValue().isInt32()
&& rhs->constantValue().toInt32() == 0;
}
if (def->isConstant()) {
if (def->isConstantValue()) {
*pwrapped = def;
return def->toConstant()->value().isInt32()
&& def->toConstant()->value().toInt32() >= 0;
return def->constantValue().isInt32()
&& def->constantValue().toInt32() >= 0;
}
return false;
@ -2553,7 +2579,7 @@ MBitNot::foldsTo(TempAllocator &alloc)
MDefinition *input = getOperand(0);
if (input->isConstant()) {
js::Value v = Int32Value(~(input->toConstant()->value().toInt32()));
js::Value v = Int32Value(~(input->constantValue().toInt32()));
return MConstant::New(alloc, v);
}
@ -2878,11 +2904,14 @@ MDefinition *
MTruncateToInt32::foldsTo(TempAllocator &alloc)
{
MDefinition *input = getOperand(0);
if (input->isBox())
input = input->getOperand(0);
if (input->type() == MIRType_Int32)
return input;
if (input->type() == MIRType_Double && input->isConstant()) {
const Value &v = input->toConstant()->value();
const Value &v = input->constantValue();
int32_t ret = ToInt32(v.toDouble());
return MConstant::New(alloc, Int32Value(ret));
}
@ -2893,12 +2922,15 @@ MTruncateToInt32::foldsTo(TempAllocator &alloc)
MDefinition *
MToDouble::foldsTo(TempAllocator &alloc)
{
MDefinition *in = input();
if (in->type() == MIRType_Double)
return in;
MDefinition *input = getOperand(0);
if (input->isBox())
input = input->getOperand(0);
if (in->isConstant()) {
const Value &v = in->toConstant()->value();
if (input->type() == MIRType_Double)
return input;
if (input->isConstant()) {
const Value &v = input->toConstant()->value();
if (v.isNumber()) {
double out = v.toNumber();
return MConstant::New(alloc, DoubleValue(out));
@ -2911,15 +2943,19 @@ MToDouble::foldsTo(TempAllocator &alloc)
MDefinition *
MToFloat32::foldsTo(TempAllocator &alloc)
{
if (input()->type() == MIRType_Float32)
return input();
MDefinition *input = getOperand(0);
if (input->isBox())
input = input->getOperand(0);
if (input->type() == MIRType_Float32)
return input;
// If x is a Float32, Float32(Double(x)) == x
if (input()->isToDouble() && input()->toToDouble()->input()->type() == MIRType_Float32)
return input()->toToDouble()->input();
if (input->isToDouble() && input->toToDouble()->input()->type() == MIRType_Float32)
return input->toToDouble()->input();
if (input()->isConstant()) {
const Value &v = input()->toConstant()->value();
if (input->isConstant()) {
const Value &v = input->toConstant()->value();
if (v.isNumber()) {
float out = v.toNumber();
MConstant *c = MConstant::New(alloc, DoubleValue(out));
@ -2934,6 +2970,9 @@ MDefinition *
MToString::foldsTo(TempAllocator &alloc)
{
MDefinition *in = input();
if (in->isBox())
in = in->getOperand(0);
if (in->type() == MIRType_String)
return in;
return this;
@ -2942,8 +2981,8 @@ MToString::foldsTo(TempAllocator &alloc)
MDefinition *
MClampToUint8::foldsTo(TempAllocator &alloc)
{
if (input()->isConstant()) {
const Value &v = input()->toConstant()->value();
if (input()->isConstantValue()) {
const Value &v = input()->constantValue();
if (v.isDouble()) {
int32_t clamped = ClampDoubleToUint8(v.toDouble());
return MConstant::New(alloc, Int32Value(clamped));
@ -3358,8 +3397,8 @@ MDefinition *
MNot::foldsTo(TempAllocator &alloc)
{
// Fold if the input is constant
if (input()->isConstant()) {
bool result = input()->toConstant()->valueToBoolean();
if (input()->isConstantValue() && !input()->constantValue().isMagic()) {
bool result = input()->constantToBoolean();
if (type() == MIRType_Int32)
return MConstant::New(alloc, Int32Value(!result));
@ -3925,8 +3964,8 @@ MGetPropertyCache::updateForReplacement(MDefinition *ins) {
MDefinition *
MAsmJSUnsignedToDouble::foldsTo(TempAllocator &alloc)
{
if (input()->isConstant()) {
const Value &v = input()->toConstant()->value();
if (input()->isConstantValue()) {
const Value &v = input()->constantValue();
if (v.isInt32())
return MConstant::New(alloc, DoubleValue(uint32_t(v.toInt32())));
}
@ -3937,8 +3976,8 @@ MAsmJSUnsignedToDouble::foldsTo(TempAllocator &alloc)
MDefinition *
MAsmJSUnsignedToFloat32::foldsTo(TempAllocator &alloc)
{
if (input()->isConstant()) {
const Value &v = input()->toConstant()->value();
if (input()->isConstantValue()) {
const Value &v = input()->constantValue();
if (v.isInt32()) {
double dval = double(uint32_t(v.toInt32()));
if (IsFloat32Representable(dval))
@ -3987,8 +4026,8 @@ MSqrt::trySpecializeFloat32(TempAllocator &alloc) {
MDefinition *
MClz::foldsTo(TempAllocator &alloc)
{
if (num()->isConstant()) {
int32_t n = num()->toConstant()->value().toInt32();
if (num()->isConstantValue()) {
int32_t n = num()->constantValue().toInt32();
if (n == 0)
return MConstant::New(alloc, Int32Value(32));
return MConstant::New(alloc, Int32Value(mozilla::CountLeadingZeroes32(n)));
@ -4000,9 +4039,9 @@ MClz::foldsTo(TempAllocator &alloc)
MDefinition *
MBoundsCheck::foldsTo(TempAllocator &alloc)
{
if (index()->isConstant() && length()->isConstant()) {
uint32_t len = length()->toConstant()->value().toInt32();
uint32_t idx = index()->toConstant()->value().toInt32();
if (index()->isConstantValue() && length()->isConstantValue()) {
uint32_t len = length()->constantValue().toInt32();
uint32_t idx = index()->constantValue().toInt32();
if (idx + uint32_t(minimum()) < len && idx + uint32_t(maximum()) < len)
return index();
}

View File

@ -752,6 +752,13 @@ class MDefinition : public MNode
MIR_OPCODE_LIST(OPCODE_CASTS)
# undef OPCODE_CASTS
bool isConstantValue() {
return isConstant() || (isBox() && getOperand(0)->isConstant());
}
const Value &constantValue();
const Value *constantVp();
bool constantToBoolean();
inline MInstruction *toInstruction();
inline const MInstruction *toInstruction() const;
bool isInstruction() const {

View File

@ -174,12 +174,12 @@ RangeAnalysis::addBetaNodes()
conservativeUpper = GenericNaN();
}
if (left->isConstant() && left->toConstant()->value().isNumber()) {
bound = left->toConstant()->value().toNumber();
if (left->isConstantValue() && left->constantValue().isNumber()) {
bound = left->constantValue().toNumber();
val = right;
jsop = ReverseCompareOp(jsop);
} else if (right->isConstant() && right->toConstant()->value().isNumber()) {
bound = right->toConstant()->value().toNumber();
} else if (right->isConstantValue() && right->constantValue().isNumber()) {
bound = right->constantValue().toNumber();
val = left;
} else if (left->type() == MIRType_Int32 && right->type() == MIRType_Int32) {
MDefinition *smaller = nullptr;
@ -1310,14 +1310,14 @@ MLsh::computeRange(TempAllocator &alloc)
left.wrapAroundToInt32();
MDefinition *rhs = getOperand(1);
if (!rhs->isConstant()) {
right.wrapAroundToShiftCount();
setRange(Range::lsh(alloc, &left, &right));
if (rhs->isConstantValue() && rhs->constantValue().isInt32()) {
int32_t c = rhs->constantValue().toInt32();
setRange(Range::lsh(alloc, &left, c));
return;
}
int32_t c = rhs->toConstant()->value().toInt32();
setRange(Range::lsh(alloc, &left, c));
right.wrapAroundToShiftCount();
setRange(Range::lsh(alloc, &left, &right));
}
void
@ -1328,14 +1328,14 @@ MRsh::computeRange(TempAllocator &alloc)
left.wrapAroundToInt32();
MDefinition *rhs = getOperand(1);
if (!rhs->isConstant()) {
right.wrapAroundToShiftCount();
setRange(Range::rsh(alloc, &left, &right));
if (rhs->isConstantValue() && rhs->constantValue().isInt32()) {
int32_t c = rhs->constantValue().toInt32();
setRange(Range::rsh(alloc, &left, c));
return;
}
int32_t c = rhs->toConstant()->value().toInt32();
setRange(Range::rsh(alloc, &left, c));
right.wrapAroundToShiftCount();
setRange(Range::rsh(alloc, &left, &right));
}
void
@ -1353,11 +1353,11 @@ MUrsh::computeRange(TempAllocator &alloc)
right.wrapAroundToShiftCount();
MDefinition *rhs = getOperand(1);
if (!rhs->isConstant()) {
setRange(Range::ursh(alloc, &left, &right));
} else {
int32_t c = rhs->toConstant()->value().toInt32();
if (rhs->isConstantValue() && rhs->constantValue().isInt32()) {
int32_t c = rhs->constantValue().toInt32();
setRange(Range::ursh(alloc, &left, c));
} else {
setRange(Range::ursh(alloc, &left, &right));
}
MOZ_ASSERT(range()->lower() >= 0);
@ -2734,7 +2734,7 @@ CloneForDeadBranches(TempAllocator &alloc, MInstruction *candidate)
candidate->block()->insertBefore(candidate, clone);
if (!candidate->isConstant()) {
if (!candidate->isConstantValue()) {
MOZ_ASSERT(clone->canRecoverOnBailout());
clone->setRecoveredOnBailout();
}

View File

@ -533,10 +533,10 @@ IndexOf(MDefinition *ins, int32_t *res)
indexDef = indexDef->toBoundsCheck()->index();
if (indexDef->isToInt32())
indexDef = indexDef->toToInt32()->getOperand(0);
if (!indexDef->isConstant())
if (!indexDef->isConstantValue())
return false;
Value index = indexDef->toConstant()->value();
Value index = indexDef->constantValue();
if (!index.isInt32())
return false;
*res = index.toInt32();
@ -966,7 +966,7 @@ ArrayMemoryView::visitSetInitializedLength(MSetInitializedLength *ins)
// To obtain the length, we need to add 1 to it, and thus we need to create
// a new constant that we register in the ArrayState.
state_ = BlockState::Copy(alloc_, state_);
int32_t initLengthValue = ins->index()->toConstant()->value().toInt32() + 1;
int32_t initLengthValue = ins->index()->constantValue().toInt32() + 1;
MConstant *initLength = MConstant::New(alloc_, Int32Value(initLengthValue));
ins->block()->insertBefore(ins, initLength);
ins->block()->insertBefore(ins, state_);

View File

@ -492,10 +492,10 @@ LIRGeneratorARM::visitAsmJSLoadHeap(MAsmJSLoadHeap *ins)
LAllocation ptrAlloc;
// For the ARM it is best to keep the 'ptr' in a register if a bounds check is needed.
if (ptr->isConstant() && !ins->needsBoundsCheck()) {
if (ptr->isConstantValue() && !ins->needsBoundsCheck()) {
// A bounds check is only skipped for a positive index.
MOZ_ASSERT(ptr->toConstant()->value().toInt32() >= 0);
ptrAlloc = LAllocation(ptr->toConstant()->vp());
MOZ_ASSERT(ptr->constantValue().toInt32() >= 0);
ptrAlloc = LAllocation(ptr->constantVp());
} else {
ptrAlloc = useRegisterAtStart(ptr);
}
@ -510,9 +510,9 @@ LIRGeneratorARM::visitAsmJSStoreHeap(MAsmJSStoreHeap *ins)
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());
if (ptr->isConstantValue() && !ins->needsBoundsCheck()) {
MOZ_ASSERT(ptr->constantValue().toInt32() >= 0);
ptrAlloc = LAllocation(ptr->constantVp());
} else {
ptrAlloc = useRegisterAtStart(ptr);
}

View File

@ -470,11 +470,11 @@ LIRGeneratorMIPS::visitAsmJSLoadHeap(MAsmJSLoadHeap *ins)
// For MIPS it is best to keep the 'ptr' in a register if a bounds check
// is needed.
if (ptr->isConstant() && !ins->needsBoundsCheck()) {
int32_t ptrValue = ptr->toConstant()->value().toInt32();
if (ptr->isConstantValue() && !ins->needsBoundsCheck()) {
int32_t ptrValue = ptr->constantValue().toInt32();
// A bounds check is only skipped for a positive index.
MOZ_ASSERT(ptrValue >= 0);
ptrAlloc = LAllocation(ptr->toConstant()->vp());
ptrAlloc = LAllocation(ptr->constantVp());
} else
ptrAlloc = useRegisterAtStart(ptr);
@ -488,9 +488,9 @@ LIRGeneratorMIPS::visitAsmJSStoreHeap(MAsmJSStoreHeap *ins)
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());
if (ptr->isConstantValue() && !ins->needsBoundsCheck()) {
MOZ_ASSERT(ptr->constantValue().toInt32() >= 0);
ptrAlloc = LAllocation(ptr->constantVp());
} else
ptrAlloc = useRegisterAtStart(ptr);