]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Decouple guard vs. INT check vs. TYPECHECK semantics for SLOAD.
authorMike Pall <mike>
Tue, 19 Jan 2010 15:58:26 +0000 (16:58 +0100)
committerMike Pall <mike>
Tue, 19 Jan 2010 15:58:26 +0000 (16:58 +0100)
lib/dump.lua
src/lj_asm.c
src/lj_ir.h
src/lj_record.c

index 00f59977339580d692b494c350a2a1cc107f424f..fb40a8f85772ac9669d92b7c08b24a02a8edb9fe 100644 (file)
@@ -209,7 +209,8 @@ local colorize, irtype
 
 -- Lookup table to convert some literals into names.
 local litname = {
-  ["SLOAD "] = { [0] = "", "I", "R", "RI", "P", "PI", "PR", "PRI", },
+  ["SLOAD "] = { [0] = "", "I", "R", "RI", "P", "PI", "PR", "PRI",
+                "T", "IT", "RT", "RIT", "PT", "PIT", "PRT", "PRIT", },
   ["XLOAD "] = { [0] = "", "R", "U", "RU", },
   ["TOINT "] = { [0] = "check", "index", "", },
   ["FLOAD "] = vmdef.irfield,
index 6d42cf35479955c024d525505fc3bf193294f973..eeb6aeb4834bb17f4d4cc3c10ec6443e64cac552 100644 (file)
@@ -1852,6 +1852,8 @@ static void asm_sload(ASMState *as, IRIns *ir)
   IRType1 t = ir->t;
   Reg base;
   lua_assert(!(ir->op2 & IRSLOAD_PARENT));  /* Handled by asm_head_side(). */
+  lua_assert(!irt_isguard(ir->t) ==
+            !((ir->op2 & IRSLOAD_TYPECHECK) || irt_isint(t)));
   if (irt_isint(t)) {
     Reg left = ra_scratch(as, RSET_FPR);
     asm_tointg(as, ir, left);  /* Frees dest reg. Do this before base alloc. */
@@ -1865,11 +1867,11 @@ static void asm_sload(ASMState *as, IRIns *ir)
     base = ra_alloc1(as, REF_BASE, RSET_GPR);
     emit_movrmro(as, dest, base, ofs);
   } else {
-    if (!irt_isguard(ir->t))
+    if (!(ir->op2 & IRSLOAD_TYPECHECK))
       return;  /* No type check: avoid base alloc. */
     base = ra_alloc1(as, REF_BASE, RSET_GPR);
   }
-  if (irt_isguard(ir->t)) {
+  if ((ir->op2 & IRSLOAD_TYPECHECK)) {
     /* Need type check, even if the load result is unused. */
     asm_guardcc(as, irt_isnum(t) ? CC_A : CC_NE);
     emit_i8(as, ~irt_type(t));
index f73dcc407037e4988bce7f96a0c87f98ab46a22b..efc8205e60facb05057aeb597068ed21c770f915 100644 (file)
@@ -192,6 +192,7 @@ IRFLDEF(FLENUM)
 #define IRSLOAD_INHERIT                1       /* Inherited by exits/side traces. */
 #define IRSLOAD_READONLY       2       /* Read-only, omit slot store. */
 #define IRSLOAD_PARENT         4       /* Coalesce with parent trace. */
+#define IRSLOAD_TYPECHECK      8       /* Needs type check. */
 
 /* XLOAD mode, stored in op2. */
 #define IRXLOAD_READONLY       1       /* Load from read-only data. */
index 950f4d820e8699da203a59216e9ffc9942f3f21d..5085d735ab152f94a9754cc6cf3b745ff779c837 100644 (file)
@@ -125,7 +125,7 @@ static void rec_check_slots(jit_State *J)
 /* Specialize a slot to a specific type. Note: slot can be negative! */
 static TRef sloadt(jit_State *J, int32_t slot, IRType t, int mode)
 {
-  /* No guard, since none of the callers need a type-checking SLOAD. */
+  /* Caller may set IRT_GUARD in t. */
   TRef ref = emitir_raw(IRT(IR_SLOAD, t), (int32_t)J->baseslot+slot, mode);
   J->base[slot] = ref;
   return ref;
@@ -135,7 +135,8 @@ static TRef sloadt(jit_State *J, int32_t slot, IRType t, int mode)
 static TRef sload(jit_State *J, int32_t slot)
 {
   IRType t = itype2irt(&J->L->base[slot]);
-  TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot, 0);
+  TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot,
+                       IRSLOAD_TYPECHECK);
   if (irtype_ispri(t)) ref = TREF_PRI(t);  /* Canonicalize primitive refs. */
   J->base[slot] = ref;
   return ref;
@@ -251,8 +252,9 @@ static TRef fori_arg(jit_State *J, const BCIns *pc, BCReg slot, IRType t)
   }
   if (J->base[slot])
     return J->base[slot];
-  else
-    return sloadt(J, (int32_t)slot, t, IRSLOAD_READONLY|IRSLOAD_INHERIT);
+  if (t == IRT_INT)
+    t |= IRT_GUARD;
+  return sloadt(J, (int32_t)slot, t, IRSLOAD_READONLY|IRSLOAD_INHERIT);
 }
 
 /* Simulate the runtime behavior of the FOR loop iterator.
@@ -2107,6 +2109,8 @@ static void rec_setup_forl(jit_State *J, const BCIns *fori)
     k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
     emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k));
   }
+  if (t == IRT_INT)
+    t |= IRT_GUARD;
   J->base[ra+FORL_EXT] = sloadt(J, (int32_t)(ra+FORL_IDX), t, IRSLOAD_INHERIT);
   J->maxslot = ra+FORL_EXT+1;
 }
@@ -2195,7 +2199,7 @@ static void rec_setup_side(jit_State *J, Trace *T)
          tr = emitir_raw(IRT(IR_FRAME, IRT_PTR), tr, tr);
        }
        break;
-      case IR_SLOAD:  /* Inherited SLOADs don't need a guard. */
+      case IR_SLOAD:  /* Inherited SLOADs don't need a guard or type check. */
        tr = emitir_raw(ir->ot & ~IRT_GUARD, s,
               (ir->op2&IRSLOAD_READONLY) | IRSLOAD_INHERIT|IRSLOAD_PARENT);
        break;