Regroup FOLD rules for constant folding.

This commit is contained in:
Mike Pall 2010-12-11 20:08:07 +01:00
parent 44101c64e8
commit 5f7e9173db

View File

@ -155,7 +155,7 @@ typedef IRRef (LJ_FASTCALL *FoldFunc)(jit_State *J);
(J->chain[IR_SNEW] || J->chain[IR_TNEW] || J->chain[IR_TDUP] || \
J->chain[IR_CNEW] || J->chain[IR_CNEWI] || J->chain[IR_TOSTR]))
/* -- Constant folding ---------------------------------------------------- */
/* -- Constant folding for FP numbers ------------------------------------- */
LJFOLD(ADD KNUM KNUM)
LJFOLD(SUB KNUM KNUM)
@ -192,6 +192,24 @@ LJFOLDF(kfold_powi)
return lj_ir_knum(J, y);
}
/* Must not use kfold_kref for numbers (could be NaN). */
LJFOLD(EQ KNUM KNUM)
LJFOLD(NE KNUM KNUM)
LJFOLD(LT KNUM KNUM)
LJFOLD(GE KNUM KNUM)
LJFOLD(LE KNUM KNUM)
LJFOLD(GT KNUM KNUM)
LJFOLD(ULT KNUM KNUM)
LJFOLD(UGE KNUM KNUM)
LJFOLD(ULE KNUM KNUM)
LJFOLD(UGT KNUM KNUM)
LJFOLDF(kfold_numcomp)
{
return CONDFOLD(lj_ir_numcmp(knumleft, knumright, (IROp)fins->o));
}
/* -- Constant folding for 32 bit integers -------------------------------- */
static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op)
{
switch (op) {
@ -239,6 +257,98 @@ LJFOLDF(kfold_bswap)
return INTFOLD((int32_t)lj_bswap((uint32_t)fleft->i));
}
LJFOLD(LT KINT KINT)
LJFOLD(GE KINT KINT)
LJFOLD(LE KINT KINT)
LJFOLD(GT KINT KINT)
LJFOLD(ULT KINT KINT)
LJFOLD(UGE KINT KINT)
LJFOLD(ULE KINT KINT)
LJFOLD(UGT KINT KINT)
LJFOLD(ABC KINT KINT)
LJFOLDF(kfold_intcomp)
{
int32_t a = fleft->i, b = fright->i;
switch ((IROp)fins->o) {
case IR_LT: return CONDFOLD(a < b);
case IR_GE: return CONDFOLD(a >= b);
case IR_LE: return CONDFOLD(a <= b);
case IR_GT: return CONDFOLD(a > b);
case IR_ULT: return CONDFOLD((uint32_t)a < (uint32_t)b);
case IR_UGE: return CONDFOLD((uint32_t)a >= (uint32_t)b);
case IR_ULE: return CONDFOLD((uint32_t)a <= (uint32_t)b);
case IR_ABC:
case IR_UGT: return CONDFOLD((uint32_t)a > (uint32_t)b);
default: lua_assert(0); return FAILFOLD;
}
}
LJFOLD(UGE any KINT)
LJFOLDF(kfold_intcomp0)
{
if (fright->i == 0)
return DROPFOLD;
return NEXTFOLD;
}
/* -- Constant folding for strings ---------------------------------------- */
LJFOLD(SNEW KPTR KINT)
LJFOLDF(kfold_snew_kptr)
{
GCstr *s = lj_str_new(J->L, (const char *)ir_kptr(fleft), (size_t)fright->i);
return lj_ir_kstr(J, s);
}
LJFOLD(SNEW any KINT)
LJFOLDF(kfold_snew_empty)
{
if (fright->i == 0)
return lj_ir_kstr(J, lj_str_new(J->L, "", 0));
return NEXTFOLD;
}
LJFOLD(STRREF KGC KINT)
LJFOLDF(kfold_strref)
{
GCstr *str = ir_kstr(fleft);
lua_assert((MSize)fright->i < str->len);
return lj_ir_kptr(J, (char *)strdata(str) + fright->i);
}
LJFOLD(STRREF SNEW any)
LJFOLDF(kfold_strref_snew)
{
PHIBARRIER(fleft);
if (irref_isk(fins->op2) && fright->i == 0) {
return fleft->op1; /* strref(snew(ptr, len), 0) ==> ptr */
} else {
/* Reassociate: strref(snew(strref(str, a), len), b) ==> strref(str, a+b) */
IRIns *ir = IR(fleft->op1);
IRRef1 str = ir->op1; /* IRIns * is not valid across emitir. */
lua_assert(ir->o == IR_STRREF);
PHIBARRIER(ir);
fins->op2 = emitir(IRTI(IR_ADD), ir->op2, fins->op2); /* Clobbers fins! */
fins->op1 = str;
fins->ot = IRT(IR_STRREF, IRT_P32);
return RETRYFOLD;
}
return NEXTFOLD;
}
LJFOLD(CALLN CARG IRCALL_lj_str_cmp)
LJFOLDF(kfold_strcmp)
{
if (irref_isk(fleft->op1) && irref_isk(fleft->op2)) {
GCstr *a = ir_kstr(IR(fleft->op1));
GCstr *b = ir_kstr(IR(fleft->op2));
return INTFOLD(lj_str_cmp(a, b));
}
return NEXTFOLD;
}
/* -- Constant folding of conversions ------------------------------------- */
LJFOLD(TONUM KINT)
LJFOLDF(kfold_tonum)
{
@ -308,109 +418,7 @@ LJFOLDF(kfold_strto)
return FAILFOLD;
}
LJFOLD(SNEW KPTR KINT)
LJFOLDF(kfold_snew_kptr)
{
GCstr *s = lj_str_new(J->L, (const char *)ir_kptr(fleft), (size_t)fright->i);
return lj_ir_kstr(J, s);
}
LJFOLD(SNEW any KINT)
LJFOLDF(kfold_snew_empty)
{
if (fright->i == 0)
return lj_ir_kstr(J, lj_str_new(J->L, "", 0));
return NEXTFOLD;
}
LJFOLD(STRREF KGC KINT)
LJFOLDF(kfold_strref)
{
GCstr *str = ir_kstr(fleft);
lua_assert((MSize)fright->i < str->len);
return lj_ir_kptr(J, (char *)strdata(str) + fright->i);
}
LJFOLD(STRREF SNEW any)
LJFOLDF(kfold_strref_snew)
{
PHIBARRIER(fleft);
if (irref_isk(fins->op2) && fright->i == 0) {
return fleft->op1; /* strref(snew(ptr, len), 0) ==> ptr */
} else {
/* Reassociate: strref(snew(strref(str, a), len), b) ==> strref(str, a+b) */
IRIns *ir = IR(fleft->op1);
IRRef1 str = ir->op1; /* IRIns * is not valid across emitir. */
lua_assert(ir->o == IR_STRREF);
PHIBARRIER(ir);
fins->op2 = emitir(IRTI(IR_ADD), ir->op2, fins->op2); /* Clobbers fins! */
fins->op1 = str;
fins->ot = IRT(IR_STRREF, IRT_P32);
return RETRYFOLD;
}
return NEXTFOLD;
}
/* Must not use kfold_kref for numbers (could be NaN). */
LJFOLD(EQ KNUM KNUM)
LJFOLD(NE KNUM KNUM)
LJFOLD(LT KNUM KNUM)
LJFOLD(GE KNUM KNUM)
LJFOLD(LE KNUM KNUM)
LJFOLD(GT KNUM KNUM)
LJFOLD(ULT KNUM KNUM)
LJFOLD(UGE KNUM KNUM)
LJFOLD(ULE KNUM KNUM)
LJFOLD(UGT KNUM KNUM)
LJFOLDF(kfold_numcomp)
{
return CONDFOLD(lj_ir_numcmp(knumleft, knumright, (IROp)fins->o));
}
LJFOLD(LT KINT KINT)
LJFOLD(GE KINT KINT)
LJFOLD(LE KINT KINT)
LJFOLD(GT KINT KINT)
LJFOLD(ULT KINT KINT)
LJFOLD(UGE KINT KINT)
LJFOLD(ULE KINT KINT)
LJFOLD(UGT KINT KINT)
LJFOLD(ABC KINT KINT)
LJFOLDF(kfold_intcomp)
{
int32_t a = fleft->i, b = fright->i;
switch ((IROp)fins->o) {
case IR_LT: return CONDFOLD(a < b);
case IR_GE: return CONDFOLD(a >= b);
case IR_LE: return CONDFOLD(a <= b);
case IR_GT: return CONDFOLD(a > b);
case IR_ULT: return CONDFOLD((uint32_t)a < (uint32_t)b);
case IR_UGE: return CONDFOLD((uint32_t)a >= (uint32_t)b);
case IR_ULE: return CONDFOLD((uint32_t)a <= (uint32_t)b);
case IR_ABC:
case IR_UGT: return CONDFOLD((uint32_t)a > (uint32_t)b);
default: lua_assert(0); return FAILFOLD;
}
}
LJFOLD(UGE any KINT)
LJFOLDF(kfold_intcomp0)
{
if (fright->i == 0)
return DROPFOLD;
return NEXTFOLD;
}
LJFOLD(CALLN CARG IRCALL_lj_str_cmp)
LJFOLDF(kfold_strcmp)
{
if (irref_isk(fleft->op1) && irref_isk(fleft->op2)) {
GCstr *a = ir_kstr(IR(fleft->op1));
GCstr *b = ir_kstr(IR(fleft->op2));
return INTFOLD(lj_str_cmp(a, b));
}
return NEXTFOLD;
}
/* -- Constant folding of equality checks --------------------------------- */
/* Don't constant-fold away FLOAD checks against KNULL. */
LJFOLD(EQ FLOAD KNULL)