From 54978e481befa5988df1dc3edc76c9467d5c47b4 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Mon, 7 Mar 2011 20:21:38 +0100 Subject: [PATCH] DUALNUM: Make overflow guards weak. Add IR_USE and IR_MULOV. --- src/lj_asm.c | 3 +++ src/lj_ir.h | 7 +++++-- src/lj_opt_fold.c | 29 +++++++++++++++++++++++++++++ src/lj_record.c | 5 +++-- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/lj_asm.c b/src/lj_asm.c index f808dd4a..889ab668 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -3992,6 +3992,8 @@ static void asm_ir(ASMState *as, IRIns *ir) /* Miscellaneous ops. */ case IR_LOOP: asm_loop(as); 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_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! */ case IR_ADDOV: asm_intarith(as, ir, XOg_ADD); break; case IR_SUBOV: asm_intarith(as, ir, XOg_SUB); break; + case IR_MULOV: asm_intarith(as, ir, XOg_X_IMUL); break; /* Memory references. */ case IR_AREF: asm_aref(as, ir); break; diff --git a/src/lj_ir.h b/src/lj_ir.h index 4813f250..060cf562 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h @@ -35,6 +35,7 @@ _(BASE, N , lit, lit) \ _(HIOP, S , ref, ref) \ _(LOOP, S , ___, ___) \ + _(USE, S , ref, ___) \ _(PHI, S , ref, ref) \ _(RENAME, S , ref, lit) \ \ @@ -78,8 +79,9 @@ _(FPMATH, N , ref, lit) \ \ /* Overflow-checking arithmetic ops. */ \ - _(ADDOV, C , ref, ref) \ - _(SUBOV, N , ref, ref) \ + _(ADDOV, CW, ref, ref) \ + _(SUBOV, NW, ref, ref) \ + _(MULOV, CW, ref, ref) \ \ /* Memory ops. A = array, H = hash, U = upvalue, F = field, S = stack. */ \ \ @@ -339,6 +341,7 @@ typedef enum { #define IRM_W 0x80 #define IRM_NW (IRM_N|IRM_W) +#define IRM_CW (IRM_C|IRM_W) #define IRM_AW (IRM_A|IRM_W) #define IRM_LW (IRM_L|IRM_W) diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index e7a1ca54..495b784d 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -247,6 +247,19 @@ LJFOLDF(kfold_intarith) 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) LJFOLDF(kfold_bnot) { @@ -992,6 +1005,21 @@ LJFOLDF(simplify_intadd_k) 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) LJFOLDF(simplify_intsub_k) { @@ -1484,6 +1512,7 @@ LJFOLDF(abc_invar) LJFOLD(ADD any any) LJFOLD(MUL any any) LJFOLD(ADDOV any any) +LJFOLD(MULOV any any) LJFOLDF(comm_swap) { if (fins->op1 < fins->op2) { /* Move lower ref to the right. */ diff --git a/src/lj_record.c b/src/lj_record.c index e20d142a..2bfd2608 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -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)); } } else { - /* Stop+step variable: need full overflow check (with dead result). */ - emitir(IRTGI(IR_ADDOV), step, stop); + /* Stop+step variable: need full overflow check. */ + 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)) {