Bug 781368 - Fold TypeOf strings in MConstant. r=efaust

This commit is contained in:
Sean Stangl 2012-08-08 16:32:15 -07:00
parent 8f231bb35d
commit 9748453131
2 changed files with 56 additions and 0 deletions

View File

@ -339,6 +339,24 @@ LIRGenerator::visitTest(MTest *test)
if (opd->type() == MIRType_Object) if (opd->type() == MIRType_Object)
return add(new LGoto(ifTrue)); return add(new LGoto(ifTrue));
// Constant Double operand.
if (opd->type() == MIRType_Double && opd->isConstant()) {
double dbl = opd->toConstant()->value().toDouble();
return add(new LGoto(dbl ? ifTrue : ifFalse));
}
// Constant Int32 operand.
if (opd->type() == MIRType_Int32 && opd->isConstant()) {
int32 num = opd->toConstant()->value().toInt32();
return add(new LGoto(num ? ifTrue : ifFalse));
}
// Constant Boolean operand.
if (opd->type() == MIRType_Boolean && opd->isConstant()) {
bool result = opd->toConstant()->value().toBoolean();
return add(new LGoto(result ? ifTrue : ifFalse));
}
// Check if the operand for this test is a compare operation. If it is, we want // Check if the operand for this test is a compare operation. If it is, we want
// to emit an LCompare*AndBranch rather than an LTest*AndBranch, to fuse the // to emit an LCompare*AndBranch rather than an LTest*AndBranch, to fuse the
// compare and jump instructions. // compare and jump instructions.

View File

@ -11,6 +11,7 @@
#include "MIRGraph.h" #include "MIRGraph.h"
#include "EdgeCaseAnalysis.h" #include "EdgeCaseAnalysis.h"
#include "jsnum.h" #include "jsnum.h"
#include "jsstr.h"
#include "jstypedarrayinlines.h" // For ClampIntForUint8Array #include "jstypedarrayinlines.h" // For ClampIntForUint8Array
using namespace js; using namespace js;
@ -1347,6 +1348,43 @@ MCompare::evaluateConstantOperands(bool *result)
Value lhs = left->toConstant()->value(); Value lhs = left->toConstant()->value();
Value rhs = right->toConstant()->value(); Value rhs = right->toConstant()->value();
// Fold away some String equality comparisons.
if (lhs.isString() && rhs.isString()) {
int32_t comp = 0; // Default to equal.
if (left != right) {
if (!CompareStrings(GetIonContext()->cx, lhs.toString(), rhs.toString(), &comp))
return false;
}
switch (jsop_) {
case JSOP_LT:
*result = (comp < 0);
break;
case JSOP_LE:
*result = (comp <= 0);
break;
case JSOP_GT:
*result = (comp > 0);
break;
case JSOP_GE:
*result = (comp >= 0);
break;
case JSOP_STRICTEQ: // Fall through.
case JSOP_EQ:
*result = (comp == 0);
break;
case JSOP_STRICTNE: // Fall through.
case JSOP_NE:
*result = (comp != 0);
break;
default:
JS_NOT_REACHED("Unexpected op.");
return false;
}
return true;
}
if (!lhs.isNumber() || !rhs.isNumber()) if (!lhs.isNumber() || !rhs.isNumber())
return false; return false;