mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Add weak guards. Emit TNEW/TDUP with a guard bit.
This commit is contained in:
parent
8fa1db826c
commit
5ff994fa37
@ -391,8 +391,8 @@ local function dump_ir(tr, dumpsnap, dumpreg)
|
|||||||
out:write(format("%04d ", ins))
|
out:write(format("%04d ", ins))
|
||||||
end
|
end
|
||||||
out:write(format("%s%s %s %s ",
|
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))
|
irtype[t], op))
|
||||||
local m1 = band(m, 3)
|
local m1 = band(m, 3)
|
||||||
if sub(op, 1, 4) == "CALL" then
|
if sub(op, 1, 4) == "CALL" then
|
||||||
|
39
src/lj_asm.c
39
src/lj_asm.c
@ -1842,26 +1842,24 @@ static void asm_newref(ASMState *as, IRIns *ir)
|
|||||||
static void asm_uref(ASMState *as, IRIns *ir)
|
static void asm_uref(ASMState *as, IRIns *ir)
|
||||||
{
|
{
|
||||||
/* NYI: Check that UREFO is still open and not aliasing a slot. */
|
/* NYI: Check that UREFO is still open and not aliasing a slot. */
|
||||||
if (ra_used(ir)) {
|
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
if (irref_isk(ir->op1)) {
|
||||||
if (irref_isk(ir->op1)) {
|
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
||||||
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v;
|
||||||
MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v;
|
emit_rma(as, XO_MOV, dest, 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 {
|
} else {
|
||||||
Reg uv = ra_scratch(as, RSET_GPR);
|
emit_rmro(as, XO_MOV, dest, uv, offsetof(GCupval, v));
|
||||||
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, 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--) {
|
for (as->curins--; as->curins > as->stopins; as->curins--) {
|
||||||
IRIns *ir = IR(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))
|
if (irt_isguard(ir->t))
|
||||||
asm_snap_prep(as);
|
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();
|
RA_DBG_REF();
|
||||||
checkmclim(as);
|
checkmclim(as);
|
||||||
asm_ir(as, ir);
|
asm_ir(as, ir);
|
||||||
|
77
src/lj_ir.h
77
src/lj_ir.h
@ -15,7 +15,7 @@
|
|||||||
/* Miscellaneous ops. */ \
|
/* Miscellaneous ops. */ \
|
||||||
_(NOP, N , ___, ___) \
|
_(NOP, N , ___, ___) \
|
||||||
_(BASE, N , lit, lit) \
|
_(BASE, N , lit, lit) \
|
||||||
_(LOOP, G , ___, ___) \
|
_(LOOP, S , ___, ___) \
|
||||||
_(PHI, S , ref, ref) \
|
_(PHI, S , ref, ref) \
|
||||||
_(RENAME, S , ref, lit) \
|
_(RENAME, S , ref, lit) \
|
||||||
\
|
\
|
||||||
@ -30,21 +30,21 @@
|
|||||||
\
|
\
|
||||||
/* Guarded assertions. */ \
|
/* Guarded assertions. */ \
|
||||||
/* Must be properly aligned to flip opposites (^1) and (un)ordered (^4). */ \
|
/* Must be properly aligned to flip opposites (^1) and (un)ordered (^4). */ \
|
||||||
_(EQ, GC, ref, ref) \
|
_(EQ, C , ref, ref) \
|
||||||
_(NE, GC, ref, ref) \
|
_(NE, C , ref, ref) \
|
||||||
\
|
\
|
||||||
_(ABC, G , ref, ref) \
|
_(ABC, N , ref, ref) \
|
||||||
_(RETF, SG, ref, ref) \
|
_(RETF, S , ref, ref) \
|
||||||
\
|
\
|
||||||
_(LT, G , ref, ref) \
|
_(LT, N , ref, ref) \
|
||||||
_(GE, G , ref, ref) \
|
_(GE, N , ref, ref) \
|
||||||
_(LE, G , ref, ref) \
|
_(LE, N , ref, ref) \
|
||||||
_(GT, G , ref, ref) \
|
_(GT, N , ref, ref) \
|
||||||
\
|
\
|
||||||
_(ULT, G , ref, ref) \
|
_(ULT, N , ref, ref) \
|
||||||
_(UGE, G , ref, ref) \
|
_(UGE, N , ref, ref) \
|
||||||
_(ULE, G , ref, ref) \
|
_(ULE, N , ref, ref) \
|
||||||
_(UGT, G , ref, ref) \
|
_(UGT, N , ref, ref) \
|
||||||
\
|
\
|
||||||
/* Bit ops. */ \
|
/* Bit ops. */ \
|
||||||
_(BNOT, N , ref, ___) \
|
_(BNOT, N , ref, ___) \
|
||||||
@ -75,27 +75,27 @@
|
|||||||
_(MAX, C , ref, ref) \
|
_(MAX, C , ref, ref) \
|
||||||
\
|
\
|
||||||
/* Overflow-checking arithmetic ops. */ \
|
/* Overflow-checking arithmetic ops. */ \
|
||||||
_(ADDOV, GC, ref, ref) \
|
_(ADDOV, C , ref, ref) \
|
||||||
_(SUBOV, G , ref, ref) \
|
_(SUBOV, N , 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. */ \
|
||||||
\
|
\
|
||||||
/* Memory references. */ \
|
/* Memory references. */ \
|
||||||
_(AREF, R , ref, ref) \
|
_(AREF, R , ref, ref) \
|
||||||
_(HREFK, RG, ref, ref) \
|
_(HREFK, R , ref, ref) \
|
||||||
_(HREF, L , ref, ref) \
|
_(HREF, L , ref, ref) \
|
||||||
_(NEWREF, S , ref, ref) \
|
_(NEWREF, S , ref, ref) \
|
||||||
_(UREFO, LG, ref, lit) \
|
_(UREFO, LW, ref, lit) \
|
||||||
_(UREFC, LG, ref, lit) \
|
_(UREFC, LW, ref, lit) \
|
||||||
_(FREF, R , ref, lit) \
|
_(FREF, R , ref, lit) \
|
||||||
_(STRREF, N , ref, ref) \
|
_(STRREF, N , ref, ref) \
|
||||||
\
|
\
|
||||||
/* Loads and Stores. These must be in the same order. */ \
|
/* Loads and Stores. These must be in the same order. */ \
|
||||||
_(ALOAD, LG, ref, ___) \
|
_(ALOAD, L , ref, ___) \
|
||||||
_(HLOAD, LG, ref, ___) \
|
_(HLOAD, L , ref, ___) \
|
||||||
_(ULOAD, LG, ref, ___) \
|
_(ULOAD, L , ref, ___) \
|
||||||
_(FLOAD, L , ref, lit) \
|
_(FLOAD, L , ref, lit) \
|
||||||
_(SLOAD, LG, lit, lit) \
|
_(SLOAD, L , lit, lit) \
|
||||||
_(XLOAD, L , ref, lit) \
|
_(XLOAD, L , ref, lit) \
|
||||||
\
|
\
|
||||||
_(ASTORE, S , ref, ref) \
|
_(ASTORE, S , ref, ref) \
|
||||||
@ -105,8 +105,8 @@
|
|||||||
\
|
\
|
||||||
/* Allocations. */ \
|
/* Allocations. */ \
|
||||||
_(SNEW, N , ref, ref) /* CSE is ok, so not marked as A. */ \
|
_(SNEW, N , ref, ref) /* CSE is ok, so not marked as A. */ \
|
||||||
_(TNEW, A , lit, lit) \
|
_(TNEW, AW, lit, lit) \
|
||||||
_(TDUP, A , ref, ___) \
|
_(TDUP, AW, ref, ___) \
|
||||||
\
|
\
|
||||||
/* Write barriers. */ \
|
/* Write barriers. */ \
|
||||||
_(TBAR, S , ref, ___) \
|
_(TBAR, S , ref, ___) \
|
||||||
@ -117,7 +117,7 @@
|
|||||||
_(TOINT, N , ref, lit) \
|
_(TOINT, N , ref, lit) \
|
||||||
_(TOBIT, N , ref, ref) \
|
_(TOBIT, N , ref, ref) \
|
||||||
_(TOSTR, N , ref, ___) \
|
_(TOSTR, N , ref, ___) \
|
||||||
_(STRTO, G , ref, ___) \
|
_(STRTO, N , ref, ___) \
|
||||||
\
|
\
|
||||||
/* Calls. */ \
|
/* Calls. */ \
|
||||||
_(CALLN, N , ref, lit) \
|
_(CALLN, N , ref, lit) \
|
||||||
@ -274,7 +274,7 @@ typedef enum {
|
|||||||
} IRMode;
|
} IRMode;
|
||||||
#define IRM___ IRMnone
|
#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_C 0x10
|
||||||
|
|
||||||
#define IRM_N 0x00
|
#define IRM_N 0x00
|
||||||
@ -283,22 +283,17 @@ typedef enum {
|
|||||||
#define IRM_L 0x40
|
#define IRM_L 0x40
|
||||||
#define IRM_S 0x60
|
#define IRM_S 0x60
|
||||||
|
|
||||||
#define IRM_G 0x80
|
#define IRM_W 0x80
|
||||||
|
|
||||||
#define IRM_GC (IRM_G|IRM_C)
|
#define IRM_AW (IRM_A|IRM_W)
|
||||||
#define IRM_RG (IRM_R|IRM_G)
|
#define IRM_LW (IRM_L|IRM_W)
|
||||||
#define IRM_LG (IRM_L|IRM_G)
|
|
||||||
#define IRM_SG (IRM_S|IRM_G)
|
|
||||||
|
|
||||||
#define irm_op1(m) (cast(IRMode, (m)&3))
|
#define irm_op1(m) (cast(IRMode, (m)&3))
|
||||||
#define irm_op2(m) (cast(IRMode, ((m)>>2)&3))
|
#define irm_op2(m) (cast(IRMode, ((m)>>2)&3))
|
||||||
#define irm_iscomm(m) ((m) & IRM_C)
|
#define irm_iscomm(m) ((m) & IRM_C)
|
||||||
#define irm_kind(m) ((m) & IRM_S)
|
#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];
|
LJ_DATA const uint8_t lj_ir_mode[IR__MAX+1];
|
||||||
|
|
||||||
@ -335,8 +330,8 @@ typedef enum {
|
|||||||
|
|
||||||
/* Additional flags. */
|
/* Additional flags. */
|
||||||
IRT_MARK = 0x20, /* Marker for misc. purposes. */
|
IRT_MARK = 0x20, /* Marker for misc. purposes. */
|
||||||
IRT_GUARD = 0x40, /* Instruction is a guard. */
|
IRT_ISPHI = 0x40, /* Instruction is left or right PHI operand. */
|
||||||
IRT_ISPHI = 0x80, /* Instruction is left or right PHI operand. */
|
IRT_GUARD = 0x80, /* Instruction is a guard. */
|
||||||
|
|
||||||
/* Masks. */
|
/* Masks. */
|
||||||
IRT_TYPE = 0x1f,
|
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_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))
|
#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
|
#endif
|
||||||
|
@ -45,7 +45,7 @@ static void dce_propagate(jit_State *J)
|
|||||||
if (irt_ismarked(ir->t)) {
|
if (irt_ismarked(ir->t)) {
|
||||||
irt_clearmark(ir->t);
|
irt_clearmark(ir->t);
|
||||||
pchain[ir->o] = &ir->prev;
|
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->o] = ir->prev; /* Reroute original instruction chain. */
|
||||||
*pchain[IR_NOP] = (IRRef1)ins;
|
*pchain[IR_NOP] = (IRRef1)ins;
|
||||||
ir->t.irt = IRT_NIL;
|
ir->t.irt = IRT_NIL;
|
||||||
|
@ -1883,7 +1883,7 @@ static TRef rec_tnew(jit_State *J, uint32_t ah)
|
|||||||
uint32_t asize = ah & 0x7ff;
|
uint32_t asize = ah & 0x7ff;
|
||||||
uint32_t hbits = ah >> 11;
|
uint32_t hbits = ah >> 11;
|
||||||
if (asize == 0x7ff) asize = 0x801;
|
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 ------------------------------------------------- */
|
/* -- Record bytecode ops ------------------------------------------------- */
|
||||||
@ -2167,7 +2167,7 @@ void lj_record_ins(jit_State *J)
|
|||||||
rc = rec_tnew(J, rc);
|
rc = rec_tnew(J, rc);
|
||||||
break;
|
break;
|
||||||
case BC_TDUP:
|
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);
|
lj_ir_ktab(J, gco2tab(proto_kgc(J->pt, ~(ptrdiff_t)rc))), 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user