Просмотр исходного кода

Copy destination type for CONV from ir->t to op2, too.

Mike Pall 14 лет назад
Родитель
Сommit
65b194a2f8
8 измененных файлов с 49 добавлено и 29 удалено
  1. 4 3
      lib/dump.lua
  2. 7 0
      src/buildvm.c
  3. 1 0
      src/buildvm.h
  4. 8 0
      src/buildvm_fold.c
  5. 1 1
      src/lj_asm.c
  6. 17 14
      src/lj_crecord.c
  7. 7 5
      src/lj_ir.h
  8. 4 6
      src/lj_opt_fold.c

+ 4 - 3
lib/dump.lua

@@ -238,9 +238,10 @@ local litname = {
   ["XLOAD "] = { [0] = "", "R", "U", "RU", },
   ["CONV  "] = setmetatable({}, { __index = function(t, mode)
     local s = irtype[band(mode, 31)]
-    if band(mode, 0x100) ~= 0 then s = s.." trunc"
-    elseif band(mode, 0x200) ~= 0 then s = s.." sext" end
-    local c = shr(mode, 10)
+    s = irtype[band(shr(mode, 5), 31)].."."..s
+    if band(mode, 0x400) ~= 0 then s = s.." trunc"
+    elseif band(mode, 0x800) ~= 0 then s = s.." sext" end
+    local c = shr(mode, 14)
     if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end
     t[mode] = s
     return s

+ 7 - 0
src/buildvm.c

@@ -253,6 +253,13 @@ IRDEF(IRNAME)
   NULL
 };
 
+const char *const irt_names[] = {
+#define IRTNAME(name)	#name,
+IRTDEF(IRTNAME)
+#undef IRTNAME
+  NULL
+};
+
 const char *const irfpm_names[] = {
 #define FPMNAME(name)		#name,
 IRFPMDEF(FPMNAME)

+ 1 - 0
src/buildvm.h

@@ -96,6 +96,7 @@ extern void emit_fold(BuildCtx *ctx);
 
 extern const char *const bc_names[];
 extern const char *const ir_names[];
+extern const char *const irt_names[];
 extern const char *const irfpm_names[];
 extern const char *const irfield_names[];
 extern const char *const ircall_names[];

+ 8 - 0
src/buildvm_fold.c

@@ -110,6 +110,14 @@ static uint32_t nexttoken(char **pp, int allowlit, int allowany)
       for (i = 0; ircall_names[i]; i++)
 	if (!strcmp(ircall_names[i], p+7))
 	  return i;
+    } else if (allowlit && !strncmp(p, "IRCONV_", 7)) {
+      for (i = 0; irt_names[i]; i++)
+	if (!strncmp(irt_names[i], p+7, 3) && p[10] == '_') {
+	  uint32_t j;
+	  for (j = 0; irt_names[j]; j++)
+	    if (!strncmp(irt_names[j], p+11, 3))
+	      return (i << 5) + j;
+	}
     } else if (allowlit && *p >= '0' && *p <= '9') {
       for (i = 0; *p >= '0' && *p <= '9'; p++)
 	i = i*10 + (*p - '0');

+ 1 - 1
src/lj_asm.c

@@ -1656,7 +1656,7 @@ static void asm_toi64(ASMState *as, IRIns *ir)
 
 static void asm_conv(ASMState *as, IRIns *ir)
 {
-  IRType st = (IRType)(ir->op2 & 0x1f);
+  IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
   int st64 = (st == IRT_I64 || st == IRT_U64 || (LJ_64 && st == IRT_P64));
   int stfp = (st == IRT_NUM || st == IRT_FLOAT);
   IRRef lref = ir->op1;

+ 17 - 14
src/lj_crecord.c

@@ -29,6 +29,9 @@
 /* Pass IR on to next optimization in chain (FOLD). */
 #define emitir(ot, a, b)	(lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
 
+#define emitconv(a, dt, st, flags) \
+  emitir(IRT(IR_CONV, (dt)), (a), (st)|((dt) << 5)|(flags))
+
 /* -- C type checks ------------------------------------------------------- */
 
 static GCcdata *argv2cdata(jit_State *J, TRef tr, cTValue *o)
@@ -145,15 +148,14 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
 #if LJ_64
     /* Sign-extend 32 to 64 bit integer. */
     if (dsize == 8 && ssize < 8 && !(sinfo & CTF_UNSIGNED))
-      sp = emitir(IRT(IR_CONV, dt), sp, IRT_INT|IRCONV_SEXT);
+      sp = emitconv(sp, dt, IRT_INT, IRCONV_SEXT);
     /* All other conversions are no-ops on x64. */
 #else
     if (dsize == 8 && ssize < 8)  /* Extend to 64 bit integer. */
-      sp = emitir(IRT(IR_CONV, dt), sp,
-		  (st < IRT_INT ? IRT_INT : st) |
-		  ((sinfo & CTF_UNSIGNED) ? 0 : IRCONV_SEXT));
+      sp = emitconv(sp, dt, ssize < 4 ? IRT_INT : st,
+		    (sinfo & CTF_UNSIGNED) ? 0 : IRCONV_SEXT);
     else if (dsize < 8 && ssize == 8)  /* Truncate from 64 bit integer. */
-      sp = emitir(IRT(IR_CONV, dt < IRT_INT ? IRT_INT : dt), sp, st);
+      sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, 0);
 #endif
   xstore:
     emitir(IRT(IR_XSTORE, dt), dp, sp);
@@ -163,7 +165,7 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
     /* fallthrough */
   case CCX(I, F):
     if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
-    sp = emitir(IRT(IR_CONV, dsize < 4 ? IRT_INT : dt), sp, st|IRCONV_TRUNC);
+    sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, IRCONV_TRUNC);
     goto xstore;
   case CCX(I, P):
   case CCX(I, A):
@@ -177,7 +179,7 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
   case CCX(F, I):
   conv_F_I:
     if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
-    sp = emitir(IRT(IR_CONV, dt), sp, st < IRT_INT ? IRT_INT : st);
+    sp = emitconv(sp, dt, ssize < 4 ? IRT_INT : st, 0);
     goto xstore;
   case CCX(F, C):
     sp = emitir(IRT(IR_XLOAD, st), sp, 0);  /* Load re. */
@@ -185,7 +187,7 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
   case CCX(F, F):
   conv_F_F:
     if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
-    if (dt != st) sp = emitir(IRT(IR_CONV, dt), sp, st);
+    if (dt != st) sp = emitconv(sp, dt, st, 0);
     goto xstore;
 
   /* Destination is a complex number. */
@@ -206,8 +208,8 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
       ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, (ssize >> 1)));
       im = emitir(IRT(IR_XLOAD, st), ptr, 0);
       if (dt != st) {
-	re = emitir(IRT(IR_CONV, dt), re, st);
-	im = emitir(IRT(IR_CONV, dt), im, st);
+	re = emitconv(re, dt, st, 0);
+	im = emitconv(im, dt, st, 0);
       }
       emitir(IRT(IR_XSTORE, dt), dp, re);
       ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, (dsize >> 1)));
@@ -233,13 +235,13 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp)
   case CCX(P, I):
     if (st == IRT_CDATA) goto err_nyi;
     if (!LJ_64 && ssize == 8)  /* Truncate from 64 bit integer. */
-      sp = emitir(IRT(IR_CONV, IRT_U32), sp, st);
+      sp = emitconv(sp, IRT_U32, st, 0);
     goto xstore;
   case CCX(P, F):
     if (st == IRT_CDATA) goto err_nyi;
     /* The signed conversion is cheaper. x64 really has 47 bit pointers. */
-    sp = emitir(IRT(IR_CONV, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32),
-		sp, st|IRCONV_TRUNC);
+    sp = emitconv(sp, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32,
+		  st, IRCONV_TRUNC);
     goto xstore;
 
   /* Destination is an array. */
@@ -274,7 +276,7 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
       goto err_nyi;  /* NYI: copyval of >64 bit integers. */
     tr = emitir(IRT(IR_XLOAD, t), sp, 0);
     if (t == IRT_FLOAT || t == IRT_U32) {  /* Keep uint32_t/float as numbers. */
-      tr = emitir(IRT(IR_CONV, IRT_NUM), tr, t);
+      tr = emitconv(tr, IRT_NUM, t, 0);
     } else if (t == IRT_I64 || t == IRT_U64) {  /* Box 64 bit integer. */
       TRef dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL);
       TRef ptr = emitir(IRT(IR_ADD, IRT_PTR), dp,
@@ -567,5 +569,6 @@ void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd)
 
 #undef IR
 #undef emitir
+#undef emitconv
 
 #endif

+ 7 - 5
src/lj_ir.h

@@ -219,11 +219,13 @@ IRFLDEF(FLENUM)
 #define IRTOINT_TRUNCI64	5	/* Truncate number to int64_t. */
 #define IRTOINT_TOBIT		6	/* Cache only: TOBIT conversion. */
 
-/* CONV mode, stored in op2. Lowest 8 bits is the IRType of the source. */
-#define IRCONV_TRUNC		0x100	/* Truncate number to integer. */
-#define IRCONV_SEXT		0x200	/* Sign-extend integer to integer. */
-#define IRCONV_MODEMASK		0x3ff
-#define IRCONV_CSH		10
+/* CONV mode, stored in op2. */
+#define IRCONV_SRCMASK		0x001f	/* Source IRType. */
+#define IRCONV_DSTMASK		0x03e0	/* Dest. IRType (also in ir->t). */
+#define IRCONV_TRUNC		0x0400	/* Truncate number to integer. */
+#define IRCONV_SEXT		0x0800	/* Sign-extend integer to integer. */
+#define IRCONV_MODEMASK		0x0fff
+#define IRCONV_CSH		12
 /* Number to integer conversion mode. Ordered by strength of the checks. */
 #define IRCONV_TOBIT  (0<<IRCONV_CSH)	/* None. Cache only: TOBIT conv. */
 #define IRCONV_ANY    (1<<IRCONV_CSH)	/* Any FP number is ok. */

+ 4 - 6
src/lj_opt_fold.c

@@ -781,11 +781,9 @@ LJFOLDF(cse_conv)
     IRRef ref = J->chain[IR_CONV];
     while (ref > op1) {
       IRIns *ir = IR(ref);
-      /* CSE also depends on the target type!
-      ** OTOH commoning with stronger checks is ok, too.
-      */
-      if (ir->op1 == op1 && irt_sametype(ir->t, fins->t) &&
-	  (ir->op2 & IRCONV_MODEMASK) == op2 && irt_isguard(ir->t) >= guard)
+      /* Commoning with stronger checks is ok. */
+      if (ir->op1 == op1 && (ir->op2 & IRCONV_MODEMASK) == op2 &&
+	  irt_isguard(ir->t) >= guard)
 	return ref;
       ref = ir->prev;
     }
@@ -1773,7 +1771,7 @@ retry:
     key += (uint32_t)IR(fins->op2)->o;
     *fright = *IR(fins->op2);
   } else {
-    key += (fins->op2 & 0xffu);  /* For IRFPM_* and IRFL_*. */
+    key += (fins->op2 & 0x3ffu);  /* Literal mask. Must include IRCONV_*MASK. */
   }
 
   /* Check for a match in order from most specific to least specific. */