diff options
| -rw-r--r-- | lib/dump.lua | 4 | ||||
| -rw-r--r-- | src/lj_asm.c | 39 | ||||
| -rw-r--r-- | src/lj_ir.h | 77 | ||||
| -rw-r--r-- | src/lj_opt_dce.c | 2 | ||||
| -rw-r--r-- | 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) | |||
| 391 | out:write(format("%04d ", ins)) | 391 | out:write(format("%04d ", ins)) |
| 392 | end | 392 | end |
| 393 | out:write(format("%s%s %s %s ", | 393 | out:write(format("%s%s %s %s ", |
| 394 | band(ot, 64) == 0 and " " or ">", | 394 | band(ot, 128) == 0 and " " or ">", |
| 395 | band(ot, 128) == 0 and " " or "+", | 395 | band(ot, 64) == 0 and " " or "+", |
| 396 | irtype[t], op)) | 396 | irtype[t], op)) |
| 397 | local m1 = band(m, 3) | 397 | local m1 = band(m, 3) |
| 398 | if sub(op, 1, 4) == "CALL" then | 398 | 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) | |||
| 1842 | static void asm_uref(ASMState *as, IRIns *ir) | 1842 | static void asm_uref(ASMState *as, IRIns *ir) |
| 1843 | { | 1843 | { |
| 1844 | /* NYI: Check that UREFO is still open and not aliasing a slot. */ | 1844 | /* NYI: Check that UREFO is still open and not aliasing a slot. */ |
| 1845 | if (ra_used(ir)) { | 1845 | Reg dest = ra_dest(as, ir, RSET_GPR); |
| 1846 | Reg dest = ra_dest(as, ir, RSET_GPR); | 1846 | if (irref_isk(ir->op1)) { |
| 1847 | if (irref_isk(ir->op1)) { | 1847 | GCfunc *fn = ir_kfunc(IR(ir->op1)); |
| 1848 | GCfunc *fn = ir_kfunc(IR(ir->op1)); | 1848 | MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v; |
| 1849 | MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v; | 1849 | emit_rma(as, XO_MOV, dest, v); |
| 1850 | emit_rma(as, XO_MOV, dest, v); | 1850 | } else { |
| 1851 | Reg uv = ra_scratch(as, RSET_GPR); | ||
| 1852 | Reg func = ra_alloc1(as, ir->op1, RSET_GPR); | ||
| 1853 | if (ir->o == IR_UREFC) { | ||
| 1854 | emit_rmro(as, XO_LEA, dest, uv, offsetof(GCupval, tv)); | ||
| 1855 | asm_guardcc(as, CC_NE); | ||
| 1856 | emit_i8(as, 1); | ||
| 1857 | emit_rmro(as, XO_ARITHib, XOg_CMP, uv, offsetof(GCupval, closed)); | ||
| 1851 | } else { | 1858 | } else { |
| 1852 | Reg uv = ra_scratch(as, RSET_GPR); | 1859 | emit_rmro(as, XO_MOV, dest, uv, offsetof(GCupval, v)); |
| 1853 | Reg func = ra_alloc1(as, ir->op1, RSET_GPR); | ||
| 1854 | if (ir->o == IR_UREFC) { | ||
| 1855 | emit_rmro(as, XO_LEA, dest, uv, offsetof(GCupval, tv)); | ||
| 1856 | asm_guardcc(as, CC_NE); | ||
| 1857 | emit_i8(as, 1); | ||
| 1858 | emit_rmro(as, XO_ARITHib, XOg_CMP, uv, offsetof(GCupval, closed)); | ||
| 1859 | } else { | ||
| 1860 | emit_rmro(as, XO_MOV, dest, uv, offsetof(GCupval, v)); | ||
| 1861 | } | ||
| 1862 | emit_rmro(as, XO_MOV, uv, func, | ||
| 1863 | (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)(ir->op2 >> 8)); | ||
| 1864 | } | 1860 | } |
| 1861 | emit_rmro(as, XO_MOV, uv, func, | ||
| 1862 | (int32_t)offsetof(GCfuncL, uvptr) + 4*(int32_t)(ir->op2 >> 8)); | ||
| 1865 | } | 1863 | } |
| 1866 | } | 1864 | } |
| 1867 | 1865 | ||
| @@ -3423,11 +3421,10 @@ static void asm_trace(ASMState *as) | |||
| 3423 | { | 3421 | { |
| 3424 | for (as->curins--; as->curins > as->stopins; as->curins--) { | 3422 | for (as->curins--; as->curins > as->stopins; as->curins--) { |
| 3425 | IRIns *ir = IR(as->curins); | 3423 | IRIns *ir = IR(as->curins); |
| 3424 | if (!ra_used(ir) && !ir_sideeff(ir) && (as->flags & JIT_F_OPT_DCE)) | ||
| 3425 | continue; /* Dead-code elimination can be soooo easy. */ | ||
| 3426 | if (irt_isguard(ir->t)) | 3426 | if (irt_isguard(ir->t)) |
| 3427 | asm_snap_prep(as); | 3427 | asm_snap_prep(as); |
| 3428 | else if (!ra_used(ir) && !irm_sideeff(lj_ir_mode[ir->o]) && | ||
| 3429 | (as->flags & JIT_F_OPT_DCE)) | ||
| 3430 | continue; /* Dead-code elimination can be soooo easy. */ | ||
| 3431 | RA_DBG_REF(); | 3428 | RA_DBG_REF(); |
| 3432 | checkmclim(as); | 3429 | checkmclim(as); |
| 3433 | asm_ir(as, ir); | 3430 | 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 @@ | |||
| 15 | /* Miscellaneous ops. */ \ | 15 | /* Miscellaneous ops. */ \ |
| 16 | _(NOP, N , ___, ___) \ | 16 | _(NOP, N , ___, ___) \ |
| 17 | _(BASE, N , lit, lit) \ | 17 | _(BASE, N , lit, lit) \ |
| 18 | _(LOOP, G , ___, ___) \ | 18 | _(LOOP, S , ___, ___) \ |
| 19 | _(PHI, S , ref, ref) \ | 19 | _(PHI, S , ref, ref) \ |
| 20 | _(RENAME, S , ref, lit) \ | 20 | _(RENAME, S , ref, lit) \ |
| 21 | \ | 21 | \ |
| @@ -30,21 +30,21 @@ | |||
| 30 | \ | 30 | \ |
| 31 | /* Guarded assertions. */ \ | 31 | /* Guarded assertions. */ \ |
| 32 | /* Must be properly aligned to flip opposites (^1) and (un)ordered (^4). */ \ | 32 | /* Must be properly aligned to flip opposites (^1) and (un)ordered (^4). */ \ |
| 33 | _(EQ, GC, ref, ref) \ | 33 | _(EQ, C , ref, ref) \ |
| 34 | _(NE, GC, ref, ref) \ | 34 | _(NE, C , ref, ref) \ |
| 35 | \ | 35 | \ |
| 36 | _(ABC, G , ref, ref) \ | 36 | _(ABC, N , ref, ref) \ |
| 37 | _(RETF, SG, ref, ref) \ | 37 | _(RETF, S , ref, ref) \ |
| 38 | \ | 38 | \ |
| 39 | _(LT, G , ref, ref) \ | 39 | _(LT, N , ref, ref) \ |
| 40 | _(GE, G , ref, ref) \ | 40 | _(GE, N , ref, ref) \ |
| 41 | _(LE, G , ref, ref) \ | 41 | _(LE, N , ref, ref) \ |
| 42 | _(GT, G , ref, ref) \ | 42 | _(GT, N , ref, ref) \ |
| 43 | \ | 43 | \ |
| 44 | _(ULT, G , ref, ref) \ | 44 | _(ULT, N , ref, ref) \ |
| 45 | _(UGE, G , ref, ref) \ | 45 | _(UGE, N , ref, ref) \ |
| 46 | _(ULE, G , ref, ref) \ | 46 | _(ULE, N , ref, ref) \ |
| 47 | _(UGT, G , ref, ref) \ | 47 | _(UGT, N , ref, ref) \ |
| 48 | \ | 48 | \ |
| 49 | /* Bit ops. */ \ | 49 | /* Bit ops. */ \ |
| 50 | _(BNOT, N , ref, ___) \ | 50 | _(BNOT, N , ref, ___) \ |
| @@ -75,27 +75,27 @@ | |||
| 75 | _(MAX, C , ref, ref) \ | 75 | _(MAX, C , ref, ref) \ |
| 76 | \ | 76 | \ |
| 77 | /* Overflow-checking arithmetic ops. */ \ | 77 | /* Overflow-checking arithmetic ops. */ \ |
| 78 | _(ADDOV, GC, ref, ref) \ | 78 | _(ADDOV, C , ref, ref) \ |
| 79 | _(SUBOV, G , ref, ref) \ | 79 | _(SUBOV, N , ref, ref) \ |
| 80 | \ | 80 | \ |
| 81 | /* Memory ops. A = array, H = hash, U = upvalue, F = field, S = stack. */ \ | 81 | /* Memory ops. A = array, H = hash, U = upvalue, F = field, S = stack. */ \ |
| 82 | \ | 82 | \ |
| 83 | /* Memory references. */ \ | 83 | /* Memory references. */ \ |
| 84 | _(AREF, R , ref, ref) \ | 84 | _(AREF, R , ref, ref) \ |
| 85 | _(HREFK, RG, ref, ref) \ | 85 | _(HREFK, R , ref, ref) \ |
| 86 | _(HREF, L , ref, ref) \ | 86 | _(HREF, L , ref, ref) \ |
| 87 | _(NEWREF, S , ref, ref) \ | 87 | _(NEWREF, S , ref, ref) \ |
| 88 | _(UREFO, LG, ref, lit) \ | 88 | _(UREFO, LW, ref, lit) \ |
| 89 | _(UREFC, LG, ref, lit) \ | 89 | _(UREFC, LW, ref, lit) \ |
| 90 | _(FREF, R , ref, lit) \ | 90 | _(FREF, R , ref, lit) \ |
| 91 | _(STRREF, N , ref, ref) \ | 91 | _(STRREF, N , ref, ref) \ |
| 92 | \ | 92 | \ |
| 93 | /* Loads and Stores. These must be in the same order. */ \ | 93 | /* Loads and Stores. These must be in the same order. */ \ |
| 94 | _(ALOAD, LG, ref, ___) \ | 94 | _(ALOAD, L , ref, ___) \ |
| 95 | _(HLOAD, LG, ref, ___) \ | 95 | _(HLOAD, L , ref, ___) \ |
| 96 | _(ULOAD, LG, ref, ___) \ | 96 | _(ULOAD, L , ref, ___) \ |
| 97 | _(FLOAD, L , ref, lit) \ | 97 | _(FLOAD, L , ref, lit) \ |
| 98 | _(SLOAD, LG, lit, lit) \ | 98 | _(SLOAD, L , lit, lit) \ |
| 99 | _(XLOAD, L , ref, lit) \ | 99 | _(XLOAD, L , ref, lit) \ |
| 100 | \ | 100 | \ |
| 101 | _(ASTORE, S , ref, ref) \ | 101 | _(ASTORE, S , ref, ref) \ |
| @@ -105,8 +105,8 @@ | |||
| 105 | \ | 105 | \ |
| 106 | /* Allocations. */ \ | 106 | /* Allocations. */ \ |
| 107 | _(SNEW, N , ref, ref) /* CSE is ok, so not marked as A. */ \ | 107 | _(SNEW, N , ref, ref) /* CSE is ok, so not marked as A. */ \ |
| 108 | _(TNEW, A , lit, lit) \ | 108 | _(TNEW, AW, lit, lit) \ |
| 109 | _(TDUP, A , ref, ___) \ | 109 | _(TDUP, AW, ref, ___) \ |
| 110 | \ | 110 | \ |
| 111 | /* Write barriers. */ \ | 111 | /* Write barriers. */ \ |
| 112 | _(TBAR, S , ref, ___) \ | 112 | _(TBAR, S , ref, ___) \ |
| @@ -117,7 +117,7 @@ | |||
| 117 | _(TOINT, N , ref, lit) \ | 117 | _(TOINT, N , ref, lit) \ |
| 118 | _(TOBIT, N , ref, ref) \ | 118 | _(TOBIT, N , ref, ref) \ |
| 119 | _(TOSTR, N , ref, ___) \ | 119 | _(TOSTR, N , ref, ___) \ |
| 120 | _(STRTO, G , ref, ___) \ | 120 | _(STRTO, N , ref, ___) \ |
| 121 | \ | 121 | \ |
| 122 | /* Calls. */ \ | 122 | /* Calls. */ \ |
| 123 | _(CALLN, N , ref, lit) \ | 123 | _(CALLN, N , ref, lit) \ |
| @@ -274,7 +274,7 @@ typedef enum { | |||
| 274 | } IRMode; | 274 | } IRMode; |
| 275 | #define IRM___ IRMnone | 275 | #define IRM___ IRMnone |
| 276 | 276 | ||
| 277 | /* Mode bits: Commutative, {Normal/Ref, Alloc, Load, Store}, Guard. */ | 277 | /* Mode bits: Commutative, {Normal/Ref, Alloc, Load, Store}, Non-weak guard. */ |
| 278 | #define IRM_C 0x10 | 278 | #define IRM_C 0x10 |
| 279 | 279 | ||
| 280 | #define IRM_N 0x00 | 280 | #define IRM_N 0x00 |
| @@ -283,22 +283,17 @@ typedef enum { | |||
| 283 | #define IRM_L 0x40 | 283 | #define IRM_L 0x40 |
| 284 | #define IRM_S 0x60 | 284 | #define IRM_S 0x60 |
| 285 | 285 | ||
| 286 | #define IRM_G 0x80 | 286 | #define IRM_W 0x80 |
| 287 | 287 | ||
| 288 | #define IRM_GC (IRM_G|IRM_C) | 288 | #define IRM_AW (IRM_A|IRM_W) |
| 289 | #define IRM_RG (IRM_R|IRM_G) | 289 | #define IRM_LW (IRM_L|IRM_W) |
| 290 | #define IRM_LG (IRM_L|IRM_G) | ||
| 291 | #define IRM_SG (IRM_S|IRM_G) | ||
| 292 | 290 | ||
| 293 | #define irm_op1(m) (cast(IRMode, (m)&3)) | 291 | #define irm_op1(m) (cast(IRMode, (m)&3)) |
| 294 | #define irm_op2(m) (cast(IRMode, ((m)>>2)&3)) | 292 | #define irm_op2(m) (cast(IRMode, ((m)>>2)&3)) |
| 295 | #define irm_iscomm(m) ((m) & IRM_C) | 293 | #define irm_iscomm(m) ((m) & IRM_C) |
| 296 | #define irm_kind(m) ((m) & IRM_S) | 294 | #define irm_kind(m) ((m) & IRM_S) |
| 297 | #define irm_isguard(m) ((m) & IRM_G) | ||
| 298 | /* Stores or any other op with a guard has a side-effect. */ | ||
| 299 | #define irm_sideeff(m) ((m) >= IRM_S) | ||
| 300 | 295 | ||
| 301 | #define IRMODE(name, m, m1, m2) ((IRM##m1)|((IRM##m2)<<2)|(IRM_##m)), | 296 | #define IRMODE(name, m, m1, m2) (((IRM##m1)|((IRM##m2)<<2)|(IRM_##m))^IRM_W), |
| 302 | 297 | ||
| 303 | LJ_DATA const uint8_t lj_ir_mode[IR__MAX+1]; | 298 | LJ_DATA const uint8_t lj_ir_mode[IR__MAX+1]; |
| 304 | 299 | ||
| @@ -335,8 +330,8 @@ typedef enum { | |||
| 335 | 330 | ||
| 336 | /* Additional flags. */ | 331 | /* Additional flags. */ |
| 337 | IRT_MARK = 0x20, /* Marker for misc. purposes. */ | 332 | IRT_MARK = 0x20, /* Marker for misc. purposes. */ |
| 338 | IRT_GUARD = 0x40, /* Instruction is a guard. */ | 333 | IRT_ISPHI = 0x40, /* Instruction is left or right PHI operand. */ |
| 339 | IRT_ISPHI = 0x80, /* Instruction is left or right PHI operand. */ | 334 | IRT_GUARD = 0x80, /* Instruction is a guard. */ |
| 340 | 335 | ||
| 341 | /* Masks. */ | 336 | /* Masks. */ |
| 342 | IRT_TYPE = 0x1f, | 337 | IRT_TYPE = 0x1f, |
| @@ -531,4 +526,12 @@ typedef union IRIns { | |||
| 531 | #define ir_knum(ir) check_exp((ir)->o == IR_KNUM, mref((ir)->ptr, cTValue)) | 526 | #define ir_knum(ir) check_exp((ir)->o == IR_KNUM, mref((ir)->ptr, cTValue)) |
| 532 | #define ir_kptr(ir) check_exp((ir)->o == IR_KPTR, mref((ir)->ptr, void)) | 527 | #define ir_kptr(ir) check_exp((ir)->o == IR_KPTR, mref((ir)->ptr, void)) |
| 533 | 528 | ||
| 529 | LJ_STATIC_ASSERT((int)IRT_GUARD == (int)IRM_W); | ||
| 530 | |||
| 531 | /* A store or any other op with a non-weak guard has a side-effect. */ | ||
| 532 | static LJ_AINLINE int ir_sideeff(IRIns *ir) | ||
| 533 | { | ||
| 534 | return (((ir->t.irt | ~IRT_GUARD) & lj_ir_mode[ir->o]) >= IRM_S); | ||
| 535 | } | ||
| 536 | |||
| 534 | #endif | 537 | #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) | |||
| 45 | if (irt_ismarked(ir->t)) { | 45 | if (irt_ismarked(ir->t)) { |
| 46 | irt_clearmark(ir->t); | 46 | irt_clearmark(ir->t); |
| 47 | pchain[ir->o] = &ir->prev; | 47 | pchain[ir->o] = &ir->prev; |
| 48 | } else if (!(irt_isguard(ir->t) || irm_sideeff(lj_ir_mode[ir->o]))) { | 48 | } else if (!ir_sideeff(ir)) { |
| 49 | *pchain[ir->o] = ir->prev; /* Reroute original instruction chain. */ | 49 | *pchain[ir->o] = ir->prev; /* Reroute original instruction chain. */ |
| 50 | *pchain[IR_NOP] = (IRRef1)ins; | 50 | *pchain[IR_NOP] = (IRRef1)ins; |
| 51 | ir->t.irt = IRT_NIL; | 51 | 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) | |||
| 1883 | uint32_t asize = ah & 0x7ff; | 1883 | uint32_t asize = ah & 0x7ff; |
| 1884 | uint32_t hbits = ah >> 11; | 1884 | uint32_t hbits = ah >> 11; |
| 1885 | if (asize == 0x7ff) asize = 0x801; | 1885 | if (asize == 0x7ff) asize = 0x801; |
| 1886 | return emitir(IRT(IR_TNEW, IRT_TAB), asize, hbits); | 1886 | return emitir(IRTG(IR_TNEW, IRT_TAB), asize, hbits); |
| 1887 | } | 1887 | } |
| 1888 | 1888 | ||
| 1889 | /* -- Record bytecode ops ------------------------------------------------- */ | 1889 | /* -- Record bytecode ops ------------------------------------------------- */ |
| @@ -2167,7 +2167,7 @@ void lj_record_ins(jit_State *J) | |||
| 2167 | rc = rec_tnew(J, rc); | 2167 | rc = rec_tnew(J, rc); |
| 2168 | break; | 2168 | break; |
| 2169 | case BC_TDUP: | 2169 | case BC_TDUP: |
| 2170 | rc = emitir(IRT(IR_TDUP, IRT_TAB), | 2170 | rc = emitir(IRTG(IR_TDUP, IRT_TAB), |
| 2171 | lj_ir_ktab(J, gco2tab(proto_kgc(J->pt, ~(ptrdiff_t)rc))), 0); | 2171 | lj_ir_ktab(J, gco2tab(proto_kgc(J->pt, ~(ptrdiff_t)rc))), 0); |
| 2172 | break; | 2172 | break; |
| 2173 | 2173 | ||
