Bug 774974 - Implement constant folding for StringLength and Compare instructions. r=pierron

This commit is contained in:
Péricles Alves 2012-07-18 08:46:27 -07:00 committed by Nicolas B. Pierron
parent 4e9abfc0e4
commit 4e902123cb
2 changed files with 64 additions and 0 deletions

View File

@ -408,6 +408,19 @@ MApplyArgs::New(JSFunction *target, MDefinition *fun, MDefinition *argc, MDefini
return new MApplyArgs(target, fun, argc, self);
}
MDefinition*
MStringLength::foldsTo(bool useValueNumbers)
{
if ((type() == MIRType_Int32) && (string()->isConstant())) {
Value value = string()->toConstant()->value();
size_t length = JS_GetStringLength(value.toString());
return MConstant::New(Int32Value(length));
}
return this;
}
MTest *
MTest::New(MDefinition *ins, MBasicBlock *ifTrue, MBasicBlock *ifFalse)
{
@ -1330,12 +1343,60 @@ MCompare::tryFold(bool *result)
return false;
}
bool
MCompare::evaluateConstantOperands(bool *result)
{
if (type() != MIRType_Boolean)
return false;
MDefinition *left = getOperand(0);
MDefinition *right = getOperand(1);
if (!left->isConstant() || !right->isConstant())
return false;
Value lhs = left->toConstant()->value();
Value rhs = right->toConstant()->value();
if (!lhs.isNumber() || !rhs.isNumber())
return false;
switch (jsop_) {
case JSOP_LT:
*result = (lhs.toNumber() < rhs.toNumber());
break;
case JSOP_LE:
*result = (lhs.toNumber() <= rhs.toNumber());
break;
case JSOP_GT:
*result = (lhs.toNumber() > rhs.toNumber());
break;
case JSOP_GE:
*result = (lhs.toNumber() >= rhs.toNumber());
break;
case JSOP_EQ:
*result = (lhs.toNumber() == rhs.toNumber());
break;
case JSOP_NE:
*result = (lhs.toNumber() != rhs.toNumber());
break;
default:
return false;
}
return true;
}
MDefinition *
MCompare::foldsTo(bool useValueNumbers)
{
bool result;
if (tryFold(&result))
return MConstant::New(BooleanValue(result));
else if (evaluateConstantOperands(&result))
return MConstant::New(BooleanValue(result));
return this;
}

View File

@ -1438,6 +1438,7 @@ class MCompare
static MCompare *New(MDefinition *left, MDefinition *right, JSOp op);
bool tryFold(bool *result);
bool evaluateConstantOperands(bool *result);
MDefinition *foldsTo(bool useValueNumbers);
void infer(JSContext *cx, const TypeOracle::BinaryTypes &b);
@ -4530,6 +4531,8 @@ class MStringLength
return new MStringLength(string);
}
MDefinition *foldsTo(bool useValueNumbers);
TypePolicy *typePolicy() {
return this;
}