From 5ff994fa3767e47ebc3ed66959d63caba990d920 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Sat, 8 May 2010 18:59:59 +0200 Subject: [PATCH] Add weak guards. Emit TNEW/TDUP with a guard bit. --- lib/dump.lua | 4 +-- src/lj_asm.c | 39 +++++++++++------------- src/lj_ir.h | 77 +++++++++++++++++++++++++----------------------- src/lj_opt_dce.c | 2 +- src/lj_record.c | 4 +-- 5 files changed, 63 insertions(+), 63 deletions(-) diff --git a/lib/dump.lua b/lib/dump.lua index 39de30d0..f87f5e1d 100644 --- a/lib/dump.lua +++ b/lib/dump.lua @@ -391,8 +391,8 @@ local function dump_ir(tr, dumpsnap, dumpreg) out:write(format("%04d ", ins)) end out:write(format("%s%s %s %s ", - band(ot, 64) == 0 and " " or ">", - band(ot, 128) == 0 and " " or "+", + band(ot, 128) == 0 and " " or ">", + band(ot, 64) == 0 and " " or "+", irtype[t], op)) local m1 = band(m, 3) if sub(op, 1, 4) == "CALL" then diff --git a/src/lj_asm.c b/src/lj_asm.c index 985f0cef..c51cc89d 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -1842,26 +1842,24 @@ static void asm_newref(ASMState *as, IRIns *ir) static void asm_uref(ASMState *as, IRIns *ir) { /* NYI: Check that UREFO is still open and not aliasing a slot. */ - if (ra_used(ir)) { - Reg dest = ra_dest(as, ir, RSET_GPR); - if (irref_isk(ir->op1)) { - GCfunc *fn = ir_kfunc(IR(ir->op1)); - MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v; - emit_rma(as, XO_MOV, dest, v); + Reg dest = ra_dest(as, ir, RSET_GPR); + if (irref_isk(ir->op1)) { + GCfunc *fn = ir_kfunc(IR(ir->op1)); + MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v; + emit_rma(as, XO_MOV, dest, v); + } else { + Reg uv = ra_scratch(as, RSET_GPR); + Reg func = ra_alloc1(as, ir->op1, RSET_GPR); + if (ir->o == IR_UREFC) { + emit_rmro(as, XO_LEA, dest, uv, offsetof(GCupval, tv)); + asm_guardcc(as, CC_NE); + emit_i8(as, 1); + emit_rmro(as, XO_ARITHib, XOg_CMP, uv, offsetof(GCupval, closed)); } else { - Reg uv = ra_scratch(as, RSET_GPR); - Reg func = ra_alloc1(as, ir->op1, RSET_GPR); - if (ir->o == IR_UREFC) { - emit_rmro(as, XO_LEA, dest, uv, offsetof(GCupval, tv)); - asm_guardcc(as, CC_NE); - emit_i8(as, 1); - emit_rmro(as, XO_ARITHib, XOg_CMP, uv, offsetof(GCupval, closed)); - } else { - emit_rmro(as, XO_MOV, dest, uv, offsetof(GCupval, v)); - } - emit_rmro(as, XO_MOV, uv, func, - (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)(ir->op2 >> 8)); + emit_rmro(as, XO_MOV, dest, uv, offsetof(GCupval, v)); } + emit_rmro(as, XO_MOV, uv, func, + (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)(ir->op2 >> 8)); } } @@ -3423,11 +3421,10 @@ static void asm_trace(ASMState *as) { for (as->curins--; as->curins > as->stopins; as->curins--) { IRIns *ir = IR(as->curins); + if (!ra_used(ir) && !ir_sideeff(ir) && (as->flags & JIT_F_OPT_DCE)) + continue; /* Dead-code elimination can be soooo easy. */ if (irt_isguard(ir->t)) asm_snap_prep(as); - else if (!ra_used(ir) && !irm_sideeff(lj_ir_mode[ir->o]) && - (as->flags & JIT_F_OPT_DCE)) - continue; /* Dead-code elimination can be soooo easy. */ RA_DBG_REF(); checkmclim(as); asm_ir(as, ir); diff --git a/src/lj_ir.h b/src/lj_ir.h index 4c72d88f..22127806 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h @@ -15,7 +15,7 @@ /* Miscellaneous ops. */ \ _(NOP, N , ___, ___) \ _(BASE, N , lit, lit) \ - _(LOOP, G , ___, ___) \ + _(LOOP, S , ___, ___) \ _(PHI, S , ref, ref) \ _(RENAME, S , ref, lit) \ \ @@ -30,21 +30,21 @@ \ /* Guarded assertions. */ \ /* Must be properly aligned to flip opposites (^1) and (un)ordered (^4). */ \ - _(EQ, GC, ref, ref) \ - _(NE, GC, ref, ref) \ + _(EQ, C , ref, ref) \ + _(NE, C , ref, ref) \ \ - _(ABC, G , ref, ref) \ - _(RETF, SG, ref, ref) \ + _(ABC, N , ref, ref) \ + _(RETF, S , ref, ref) \ \ - _(LT, G , ref, ref) \ - _(GE, G , ref, ref) \ - _(LE, G , ref, ref) \ - _(GT, G , ref, ref) \ + _(LT, N , ref, ref) \ + _(GE, N , ref, ref) \ + _(LE, N , ref, ref) \ + _(GT, N , ref, ref) \ \ - _(ULT, G , ref, ref) \ - _(UGE, G , ref, ref) \ - _(ULE, G , ref, ref) \ - _(UGT, G , ref, ref) \ + _(ULT, N , ref, ref) \ + _(UGE, N , ref, ref) \ + _(ULE, N , ref, ref) \ + _(UGT, N , ref, ref) \ \ /* Bit ops. */ \ _(BNOT, N , ref, ___) \ @@ -75,27 +75,27 @@ _(MAX, C , ref, ref) \ \ /* Overflow-checking arithmetic ops. */ \ - _(ADDOV, GC, ref, ref) \ - _(SUBOV, G , ref, ref) \ + _(ADDOV, C , ref, ref) \ + _(SUBOV, N , ref, ref) \ \ /* Memory ops. A = array, H = hash, U = upvalue, F = field, S = stack. */ \ \ /* Memory references. */ \ _(AREF, R , ref, ref) \ - _(HREFK, RG, ref, ref) \ + _(HREFK, R , ref, ref) \ _(HREF, L , ref, ref) \ _(NEWREF, S , ref, ref) \ - _(UREFO, LG, ref, lit) \ - _(UREFC, LG, ref, lit) \ + _(UREFO, LW, ref, lit) \ + _(UREFC, LW, ref, lit) \ _(FREF, R , ref, lit) \ _(STRREF, N , ref, ref) \ \ /* Loads and Stores. These must be in the same order. */ \ - _(ALOAD, LG, ref, ___) \ - _(HLOAD, LG, ref, ___) \ - _(ULOAD, LG, ref, ___) \ + _(ALOAD, L , ref, ___) \ + _(HLOAD, L , ref, ___) \ + _(ULOAD, L , ref, ___) \ _(FLOAD, L , ref, lit) \ - _(SLOAD, LG, lit, lit) \ + _(SLOAD, L , lit, lit) \ _(XLOAD, L , ref, lit) \ \ _(ASTORE, S , ref, ref) \ @@ -105,8 +105,8 @@ \ /* Allocations. */ \ _(SNEW, N , ref, ref) /* CSE is ok, so not marked as A. */ \ - _(TNEW, A , lit, lit) \ - _(TDUP, A , ref, ___) \ + _(TNEW, AW, lit, lit) \ + _(TDUP, AW, ref, ___) \ \ /* Write barriers. */ \ _(TBAR, S , ref, ___) \ @@ -117,7 +117,7 @@ _(TOINT, N , ref, lit) \ _(TOBIT, N , ref, ref) \ _(TOSTR, N , ref, ___) \ - _(STRTO, G , ref, ___) \ + _(STRTO, N , ref, ___) \ \ /* Calls. */ \ _(CALLN, N , ref, lit) \ @@ -274,7 +274,7 @@ typedef enum { } IRMode; #define IRM___ IRMnone -/* Mode bits: Commutative, {Normal/Ref, Alloc, Load, Store}, Guard. */ +/* Mode bits: Commutative, {Normal/Ref, Alloc, Load, Store}, Non-weak guard. */ #define IRM_C 0x10 #define IRM_N 0x00 @@ -283,22 +283,17 @@ typedef enum { #define IRM_L 0x40 #define IRM_S 0x60 -#define IRM_G 0x80 +#define IRM_W 0x80 -#define IRM_GC (IRM_G|IRM_C) -#define IRM_RG (IRM_R|IRM_G) -#define IRM_LG (IRM_L|IRM_G) -#define IRM_SG (IRM_S|IRM_G) +#define IRM_AW (IRM_A|IRM_W) +#define IRM_LW (IRM_L|IRM_W) #define irm_op1(m) (cast(IRMode, (m)&3)) #define irm_op2(m) (cast(IRMode, ((m)>>2)&3)) #define irm_iscomm(m) ((m) & IRM_C) #define irm_kind(m) ((m) & IRM_S) -#define irm_isguard(m) ((m) & IRM_G) -/* Stores or any other op with a guard has a side-effect. */ -#define irm_sideeff(m) ((m) >= IRM_S) -#define IRMODE(name, m, m1, m2) ((IRM##m1)|((IRM##m2)<<2)|(IRM_##m)), +#define IRMODE(name, m, m1, m2) (((IRM##m1)|((IRM##m2)<<2)|(IRM_##m))^IRM_W), LJ_DATA const uint8_t lj_ir_mode[IR__MAX+1]; @@ -335,8 +330,8 @@ typedef enum { /* Additional flags. */ IRT_MARK = 0x20, /* Marker for misc. purposes. */ - IRT_GUARD = 0x40, /* Instruction is a guard. */ - IRT_ISPHI = 0x80, /* Instruction is left or right PHI operand. */ + IRT_ISPHI = 0x40, /* Instruction is left or right PHI operand. */ + IRT_GUARD = 0x80, /* Instruction is a guard. */ /* Masks. */ IRT_TYPE = 0x1f, @@ -531,4 +526,12 @@ typedef union IRIns { #define ir_knum(ir) check_exp((ir)->o == IR_KNUM, mref((ir)->ptr, cTValue)) #define ir_kptr(ir) check_exp((ir)->o == IR_KPTR, mref((ir)->ptr, void)) +LJ_STATIC_ASSERT((int)IRT_GUARD == (int)IRM_W); + +/* A store or any other op with a non-weak guard has a side-effect. */ +static LJ_AINLINE int ir_sideeff(IRIns *ir) +{ + return (((ir->t.irt | ~IRT_GUARD) & lj_ir_mode[ir->o]) >= IRM_S); +} + #endif diff --git a/src/lj_opt_dce.c b/src/lj_opt_dce.c index 90e81526..083239f6 100644 --- a/src/lj_opt_dce.c +++ b/src/lj_opt_dce.c @@ -45,7 +45,7 @@ static void dce_propagate(jit_State *J) if (irt_ismarked(ir->t)) { irt_clearmark(ir->t); pchain[ir->o] = &ir->prev; - } else if (!(irt_isguard(ir->t) || irm_sideeff(lj_ir_mode[ir->o]))) { + } else if (!ir_sideeff(ir)) { *pchain[ir->o] = ir->prev; /* Reroute original instruction chain. */ *pchain[IR_NOP] = (IRRef1)ins; ir->t.irt = IRT_NIL; diff --git a/src/lj_record.c b/src/lj_record.c index 440db6c6..55daaae6 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -1883,7 +1883,7 @@ static TRef rec_tnew(jit_State *J, uint32_t ah) uint32_t asize = ah & 0x7ff; uint32_t hbits = ah >> 11; if (asize == 0x7ff) asize = 0x801; - return emitir(IRT(IR_TNEW, IRT_TAB), asize, hbits); + return emitir(IRTG(IR_TNEW, IRT_TAB), asize, hbits); } /* -- Record bytecode ops ------------------------------------------------- */ @@ -2167,7 +2167,7 @@ void lj_record_ins(jit_State *J) rc = rec_tnew(J, rc); break; case BC_TDUP: - rc = emitir(IRT(IR_TDUP, IRT_TAB), + rc = emitir(IRTG(IR_TDUP, IRT_TAB), lj_ir_ktab(J, gco2tab(proto_kgc(J->pt, ~(ptrdiff_t)rc))), 0); break;