]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Add weak guards. Emit TNEW/TDUP with a guard bit.
authorMike Pall <mike>
Sat, 8 May 2010 16:59:59 +0000 (18:59 +0200)
committerMike Pall <mike>
Sat, 8 May 2010 16:59:59 +0000 (18:59 +0200)
lib/dump.lua
src/lj_asm.c
src/lj_ir.h
src/lj_opt_dce.c
src/lj_record.c

index 39de30d067f4181109aac5519d02953915199c67..f87f5e1dadbed4dfe479889ce4a7a1f4f7aa15bf 100644 (file)
@@ -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
index 985f0cefef46fa164b6b7739ba6fc92628d991cb..c51cc89d4395e204e286c63c6c46e512102bdada 100644 (file)
@@ -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);
index 4c72d88f6f595c3eceb244428c149572ec5a5830..22127806eadc821a97c951b09fd91b6e2c8b1648 100644 (file)
@@ -15,7 +15,7 @@
   /* Miscellaneous ops. */ \
   _(NOP,       N , ___, ___) \
   _(BASE,      N , lit, lit) \
-  _(LOOP,      G , ___, ___) \
+  _(LOOP,      S , ___, ___) \
   _(PHI,       S , ref, ref) \
   _(RENAME,    S , ref, lit) \
   \
   \
   /* Guarded assertions. */ \
   /* Must be properly aligned to flip opposites (^1) and (un)ordered (^4). */ \
-  _(EQ,                GC, ref, ref) \
-  _(NE,                GC, ref, ref) \
+  _(EQ,                , ref, ref) \
+  _(NE,                , 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, ___) \
   _(MAX,       C , ref, ref) \
   \
   /* Overflow-checking arithmetic ops. */ \
-  _(ADDOV,     GC, ref, ref) \
-  _(SUBOV,     G , ref, ref) \
+  _(ADDOV,     , 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) \
   \
   /* 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, ___) \
   _(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
index 90e81526372430d4defbed243360e3365bd9be08..083239f6c6f919e2c13a55493c1036599f8cb1cf 100644 (file)
@@ -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;
index 440db6c68166a0cd2783ba087b0441765a34d837..55daaae6315551af9fd9d0291747e97c009b9c89 100644 (file)
@@ -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;