mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1107328 - IonMonkey: Also check for boxed constants when checking for constants, r=jandem
This commit is contained in:
parent
b90d771c94
commit
2642d1cb91
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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_);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user