From 8dc76ee3276e504d739818322e4dff37e6ae1c11 Mon Sep 17 00:00:00 2001
From: Mike Pall <mike>
Date: Tue, 14 Sep 2010 19:58:27 +0200
Subject: Add IR_VLOAD for vararg loads.

Also fixes the broken AA improvement in the last commit.
---
 src/lj_asm.c      | 11 ++++++++---
 src/lj_ir.h       |  3 ++-
 src/lj_opt_fold.c |  1 +
 src/lj_opt_mem.c  |  3 ---
 src/lj_record.c   |  4 ++--
 5 files changed, 13 insertions(+), 9 deletions(-)

(limited to 'src')

diff --git a/src/lj_asm.c b/src/lj_asm.c
index d26d0b4b..e7f2cb72 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -96,7 +96,7 @@ typedef struct ASMState {
 #define neverfuse(as)		(as->fuseref == FUSE_DISABLED)
 #define opisfusableload(o) \
   ((o) == IR_ALOAD || (o) == IR_HLOAD || (o) == IR_ULOAD || \
-   (o) == IR_FLOAD || (o) == IR_SLOAD || (o) == IR_XLOAD)
+   (o) == IR_FLOAD || (o) == IR_XLOAD || (o) == IR_SLOAD || (o) == IR_VLOAD)
 
 /* Instruction selection for XMM moves. */
 #define XMM_MOVRR(as)	((as->flags & JIT_F_SPLIT_XMM) ? XO_MOVSD : XO_MOVAPS)
@@ -1315,6 +1315,9 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
 	asm_fusexref(as, IR(ir->op1), xallow);
 	return RID_MRM;
       }
+    } else if (ir->o == IR_VLOAD) {
+      asm_fuseahuref(as, ir->op1, xallow);
+      return RID_MRM;
     }
   }
   if (!(as->freeset & allow) &&
@@ -1978,7 +1981,7 @@ static Reg asm_load_lightud64(ASMState *as, IRIns *ir, int typecheck)
 }
 #endif
 
-static void asm_ahuload(ASMState *as, IRIns *ir)
+static void asm_ahuvload(ASMState *as, IRIns *ir)
 {
   lua_assert(irt_isnum(ir->t) || irt_ispri(ir->t) || irt_isaddr(ir->t));
 #if LJ_64
@@ -3385,7 +3388,9 @@ static void asm_ir(ASMState *as, IRIns *ir)
   case IR_STRREF: asm_strref(as, ir); break;
 
   /* Loads and stores. */
-  case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: asm_ahuload(as, ir); break;
+  case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
+    asm_ahuvload(as, ir);
+    break;
   case IR_FLOAD: case IR_XLOAD: asm_fxload(as, ir); break;
   case IR_SLOAD: asm_sload(as, ir); break;
 
diff --git a/src/lj_ir.h b/src/lj_ir.h
index cc57560d..c483e60f 100644
--- a/src/lj_ir.h
+++ b/src/lj_ir.h
@@ -95,8 +95,9 @@
   _(HLOAD,	L , ref, ___) \
   _(ULOAD,	L , ref, ___) \
   _(FLOAD,	L , ref, lit) \
-  _(SLOAD,	L , lit, lit) \
   _(XLOAD,	L , ref, lit) \
+  _(SLOAD,	L , lit, lit) \
+  _(VLOAD,	L , ref, ___) \
   \
   _(ASTORE,	S , ref, ref) \
   _(HSTORE,	S , ref, ref) \
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index 90520d8c..5a6ea29b 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -1308,6 +1308,7 @@ LJFOLDF(fload_str_len_snew)
 }
 
 LJFOLD(FLOAD any IRFL_STR_LEN)
+LJFOLD(VLOAD any any)  /* Vararg loads have no corresponding stores. */
 LJFOLDX(lj_opt_cse)
 
 /* All other field loads need alias analysis. */
diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c
index c862e67e..8674ddea 100644
--- a/src/lj_opt_mem.c
+++ b/src/lj_opt_mem.c
@@ -102,9 +102,6 @@ static TRef fwd_ahload(jit_State *J, IRRef xref)
   IRRef lim = xref;  /* Search limit. */
   IRRef ref;
 
-  if (IR(xr->op1)->o != IR_FLOAD)  /* Varargs have no corresponding stores. */
-    goto cselim;
-
   /* Search for conflicting stores. */
   ref = J->chain[fins->o+IRDELTA_L2S];
   while (ref > xref) {
diff --git a/src/lj_record.c b/src/lj_record.c
index 42bcca1a..6e396729 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -1998,7 +1998,7 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults)
 	  IRType t = itype2irt(&J->L->base[i-1-nvararg]);
 	  TRef aref = emitir(IRT(IR_AREF, IRT_PTR),
 			     vbase, lj_ir_kint(J, (int32_t)i));
-	  TRef tr = emitir(IRTG(IR_ALOAD, t), aref, 0);
+	  TRef tr = emitir(IRTG(IR_VLOAD, t), aref, 0);
 	  if (irtype_ispri(t)) tr = TREF_PRI(t);  /* Canonicalize primitives. */
 	  J->base[dst+i] = tr;
 	}
@@ -2044,7 +2044,7 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults)
 	vbase = emitir(IRT(IR_ADD, IRT_PTR), vbase, lj_ir_kint(J, frofs-8));
 	t = itype2irt(&J->L->base[idx-2-nvararg]);
 	aref = emitir(IRT(IR_AREF, IRT_PTR), vbase, tridx);
-	tr = emitir(IRTG(IR_ALOAD, t), aref, 0);
+	tr = emitir(IRTG(IR_VLOAD, t), aref, 0);
 	if (irtype_ispri(t)) tr = TREF_PRI(t);  /* Canonicalize primitives. */
       }
       J->base[dst-2] = tr;
-- 
cgit v1.2.3-55-g6feb