Don't guard on constant decisions, which will always have the same path (bug 452884, r=gal).

This commit is contained in:
David Anderson 2008-09-04 14:44:59 -07:00
parent b15e1fe4d3
commit 09123ebd63
2 changed files with 49 additions and 9 deletions

View File

@ -367,6 +367,11 @@ static bool isconst(LIns* i, int32_t c)
return i->isconst() && i->constval() == c;
}
static bool isAnyConst(LIns* i)
{
return i->isconst() || i->isconstq();
}
static bool overflowSafe(LIns* i)
{
LIns* c;
@ -2790,9 +2795,15 @@ TraceRecorder::ifop()
jsdouble d = asNumber(v);
jsdpun u;
u.d = 0;
guard(d == 0 || JSDOUBLE_IS_NaN(d),
lir->ins2(LIR_feq, get(&v), lir->insImmq(u.u64)),
BRANCH_EXIT);
LIns* v_ins = get(&v);
// Only insert the guard if the condition is not constant, since in
// that case at runtime we would always take the same path as the
// interpreter is taking right now and hence there is no need for
// a guard.
if (!v_ins->isconst() && !v_ins->isconstq())
guard(d == 0 || JSDOUBLE_IS_NaN(d),
lir->ins2(LIR_feq, v_ins, lir->insImmq(u.u64)),
BRANCH_EXIT);
} else if (JSVAL_IS_STRING(v)) {
guard(JSSTRING_LENGTH(JSVAL_TO_STRING(v)) == 0,
lir->ins_eq0(lir->ins2(LIR_piand,
@ -2924,9 +2935,16 @@ TraceRecorder::cmp(LOpcode op, int flags)
LIns* x;
bool negate = !!(flags & CMP_NEGATE);
bool cond;
LIns* l_ins = get(&l);
LIns* r_ins = get(&r);
/* Don't guard if the same path is always taken. */
if (isAnyConst(r_ins) && isAnyConst(l_ins))
return true;
if (JSVAL_IS_STRING(l) && JSVAL_IS_STRING(r)) {
JS_ASSERT(!negate);
LIns* args[] = { get(&r), get(&l) };
LIns* args[] = { r_ins, l_ins };
x = lir->ins1(LIR_i2f, lir->insCall(F_CompareStrings, args));
x = lir->ins2i(op, x, 0);
jsint result = js_CompareStrings(JSVAL_TO_STRING(l), JSVAL_TO_STRING(r));
@ -2952,8 +2970,6 @@ TraceRecorder::cmp(LOpcode op, int flags)
JSAutoTempValueRooter tvr(cx, 2, tmp);
// TODO: coerce non-numbers to numbers if it's not string-on-string above
LIns* l_ins = get(&l);
LIns* r_ins = get(&r);
jsdouble lnum;
jsdouble rnum;
LIns* args[] = { l_ins, cx_ins };
@ -2973,7 +2989,7 @@ TraceRecorder::cmp(LOpcode op, int flags)
}
lnum = js_ValueToNumber(cx, &tmp[0]);
args[0] = get(&r);
args[0] = r_ins;
args[1] = cx_ins;
if (JSVAL_IS_STRING(r)) {
r_ins = lir->insCall(F_StringToNumber, args);
@ -3065,8 +3081,16 @@ TraceRecorder::equal(int flags)
jsval& r = stackval(-1);
jsval& l = stackval(-2);
bool negate = !!(flags & CMP_NEGATE);
LIns* r_ins = get(&r);
LIns* l_ins = get(&l);
/* Don't guard if the same path is always taken. */
if (isAnyConst(r_ins) && isAnyConst(l_ins))
return true;
if (JSVAL_IS_STRING(l) && JSVAL_IS_STRING(r)) {
LIns* args[] = { get(&r), get(&l) };
LIns* args[] = { r_ins, l_ins };
bool cond = js_EqualStrings(JSVAL_TO_STRING(l), JSVAL_TO_STRING(r)) ^ negate;
LIns* x = lir->ins_eq0(lir->insCall(F_EqualStrings, args));
if (!negate)
@ -3092,7 +3116,7 @@ TraceRecorder::equal(int flags)
}
if (JSVAL_IS_OBJECT(l) && JSVAL_IS_OBJECT(r)) {
bool cond = (l == r) ^ negate;
LIns* x = lir->ins2(LIR_eq, get(&l), get(&r));
LIns* x = lir->ins2(LIR_eq, l_ins, r_ins);
if (negate)
x = lir->ins_eq0(x);

View File

@ -1185,6 +1185,22 @@ function testNegZero2() {
}
testNegZero2();
function testConstSwitch() {
var x;
for (var j=0;j<5;++j) { switch(1.1) { case NaN: case 2: } x = 2; }
return x;
}
testConstSwitch.expected = 2;
test(testConstSwitch);
function testConstIf() {
var x;
for (var j=0;j<5;++j) { if (1.1 || 5) { } x = 2;}
return x;
}
testConstIf.expected = 2;
test(testConstIf);
/* Keep these at the end so that we can see the summary after the trace-debug spew. */
print("\npassed:", passes.length && passes.join(","));
print("\nFAILED:", fails.length && fails.join(","));