DUALNUM: Make overflow guards weak. Add IR_USE and IR_MULOV.

This commit is contained in:
Mike Pall 2011-03-07 20:21:38 +01:00
parent a30f58b54b
commit 54978e481b
4 changed files with 40 additions and 4 deletions

View File

@ -3992,6 +3992,8 @@ static void asm_ir(ASMState *as, IRIns *ir)
/* Miscellaneous ops. */ /* Miscellaneous ops. */
case IR_LOOP: asm_loop(as); break; case IR_LOOP: asm_loop(as); break;
case IR_NOP: case IR_XBAR: lua_assert(!ra_used(ir)); break; case IR_NOP: case IR_XBAR: lua_assert(!ra_used(ir)); break;
case IR_USE:
ra_alloc1(as, ir->op1, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); break;
case IR_PHI: asm_phi(as, ir); break; case IR_PHI: asm_phi(as, ir); break;
case IR_HIOP: asm_hiop(as, ir); break; case IR_HIOP: asm_hiop(as, ir); break;
@ -4077,6 +4079,7 @@ static void asm_ir(ASMState *as, IRIns *ir)
/* Overflow-checking arithmetic ops. Note: don't use LEA here! */ /* Overflow-checking arithmetic ops. Note: don't use LEA here! */
case IR_ADDOV: asm_intarith(as, ir, XOg_ADD); break; case IR_ADDOV: asm_intarith(as, ir, XOg_ADD); break;
case IR_SUBOV: asm_intarith(as, ir, XOg_SUB); break; case IR_SUBOV: asm_intarith(as, ir, XOg_SUB); break;
case IR_MULOV: asm_intarith(as, ir, XOg_X_IMUL); break;
/* Memory references. */ /* Memory references. */
case IR_AREF: asm_aref(as, ir); break; case IR_AREF: asm_aref(as, ir); break;

View File

@ -35,6 +35,7 @@
_(BASE, N , lit, lit) \ _(BASE, N , lit, lit) \
_(HIOP, S , ref, ref) \ _(HIOP, S , ref, ref) \
_(LOOP, S , ___, ___) \ _(LOOP, S , ___, ___) \
_(USE, S , ref, ___) \
_(PHI, S , ref, ref) \ _(PHI, S , ref, ref) \
_(RENAME, S , ref, lit) \ _(RENAME, S , ref, lit) \
\ \
@ -78,8 +79,9 @@
_(FPMATH, N , ref, lit) \ _(FPMATH, N , ref, lit) \
\ \
/* Overflow-checking arithmetic ops. */ \ /* Overflow-checking arithmetic ops. */ \
_(ADDOV, C , ref, ref) \ _(ADDOV, CW, ref, ref) \
_(SUBOV, N , ref, ref) \ _(SUBOV, NW, ref, ref) \
_(MULOV, CW, ref, ref) \
\ \
/* Memory ops. A = array, H = hash, U = upvalue, F = field, S = stack. */ \ /* Memory ops. A = array, H = hash, U = upvalue, F = field, S = stack. */ \
\ \
@ -339,6 +341,7 @@ typedef enum {
#define IRM_W 0x80 #define IRM_W 0x80
#define IRM_NW (IRM_N|IRM_W) #define IRM_NW (IRM_N|IRM_W)
#define IRM_CW (IRM_C|IRM_W)
#define IRM_AW (IRM_A|IRM_W) #define IRM_AW (IRM_A|IRM_W)
#define IRM_LW (IRM_L|IRM_W) #define IRM_LW (IRM_L|IRM_W)

View File

@ -247,6 +247,19 @@ LJFOLDF(kfold_intarith)
return INTFOLD(kfold_intop(fleft->i, fright->i, (IROp)fins->o)); return INTFOLD(kfold_intop(fleft->i, fright->i, (IROp)fins->o));
} }
LJFOLD(ADDOV KINT KINT)
LJFOLD(SUBOV KINT KINT)
LJFOLD(MULOV KINT KINT)
LJFOLDF(kfold_intovarith)
{
lua_Number n = lj_vm_foldarith((lua_Number)fleft->i, (lua_Number)fright->i,
fins->o - IR_ADDOV);
int32_t k = lj_num2int(n);
if (n != (lua_Number)k)
return FAILFOLD;
return INTFOLD(k);
}
LJFOLD(BNOT KINT) LJFOLD(BNOT KINT)
LJFOLDF(kfold_bnot) LJFOLDF(kfold_bnot)
{ {
@ -992,6 +1005,21 @@ LJFOLDF(simplify_intadd_k)
return NEXTFOLD; return NEXTFOLD;
} }
LJFOLD(MULOV any KINT)
LJFOLDF(simplify_intmul_k)
{
if (fright->i == 0) /* i * 0 ==> 0 */
return RIGHTFOLD;
if (fright->i == 1) /* i * 1 ==> i */
return LEFTFOLD;
if (fright->i == 2) { /* i * 2 ==> i + i */
fins->o = IR_ADDOV;
fins->op2 = fins->op1;
return RETRYFOLD;
}
return NEXTFOLD;
}
LJFOLD(SUB any KINT) LJFOLD(SUB any KINT)
LJFOLDF(simplify_intsub_k) LJFOLDF(simplify_intsub_k)
{ {
@ -1484,6 +1512,7 @@ LJFOLDF(abc_invar)
LJFOLD(ADD any any) LJFOLD(ADD any any)
LJFOLD(MUL any any) LJFOLD(MUL any any)
LJFOLD(ADDOV any any) LJFOLD(ADDOV any any)
LJFOLD(MULOV any any)
LJFOLDF(comm_swap) LJFOLDF(comm_swap)
{ {
if (fins->op1 < fins->op2) { /* Move lower ref to the right. */ if (fins->op1 < fins->op2) { /* Move lower ref to the right. */

View File

@ -1860,8 +1860,9 @@ static void rec_setup_forl(jit_State *J, const BCIns *fori)
emitir(IRTGI(IR_GE), step, lj_ir_kint(J, (int32_t)0x80000000-k)); emitir(IRTGI(IR_GE), step, lj_ir_kint(J, (int32_t)0x80000000-k));
} }
} else { } else {
/* Stop+step variable: need full overflow check (with dead result). */ /* Stop+step variable: need full overflow check. */
emitir(IRTGI(IR_ADDOV), step, stop); TRef tr = emitir(IRTGI(IR_ADDOV), step, stop);
emitir(IRTI(IR_USE), tr, 0); /* ADDOV is weak. Avoid dead result. */
} }
} }
} else if (t == IRT_INT && !tref_isk(stop)) { } else if (t == IRT_INT && !tref_isk(stop)) {