Browse Source

FFI: Fix snapshot substitution in SPLIT pass.

Mike Pall 12 years ago
parent
commit
172bd95365
1 changed files with 27 additions and 19 deletions
  1. 27 19
      src/lj_opt_split.c

+ 27 - 19
src/lj_opt_split.c

@@ -195,6 +195,19 @@ static IRRef split_ptr(jit_State *J, IRIns *oir, IRRef ref)
   return split_emit(J, IRTI(IR_ADD), nref, lj_ir_kint(J, ofs));
 }
 
+/* Substitute references of a snapshot. */
+static void split_subst_snap(jit_State *J, SnapShot *snap, IRIns *oir)
+{
+  SnapEntry *map = &J->cur.snapmap[snap->mapofs];
+  MSize n, nent = snap->nent;
+  for (n = 0; n < nent; n++) {
+    SnapEntry sn = map[n];
+    IRIns *ir = &oir[snap_ref(sn)];
+    if (!(LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && irref_isk(snap_ref(sn))))
+      map[n] = ((sn & 0xffff0000) | ir->prev);
+  }
+}
+
 /* Transform the old IR to the new IR. */
 static void split_ir(jit_State *J)
 {
@@ -203,7 +216,8 @@ static void split_ir(jit_State *J)
   MSize need = (irlen+1)*(sizeof(IRIns) + sizeof(IRRef1));
   IRIns *oir = (IRIns *)lj_str_needbuf(J->L, &G(J->L)->tmpbuf, need);
   IRRef1 *hisubst;
-  IRRef ref;
+  IRRef ref, snref;
+  SnapShot *snap;
 
   /* Copy old IR to buffer. */
   memcpy(oir, IR(nk), irlen*sizeof(IRIns));
@@ -230,12 +244,20 @@ static void split_ir(jit_State *J)
   }
 
   /* Process old IR instructions. */
+  snap = J->cur.snap;
+  snref = snap->ref;
   for (ref = REF_FIRST; ref < nins; ref++) {
     IRIns *ir = &oir[ref];
     IRRef nref = lj_ir_nextins(J);
     IRIns *nir = IR(nref);
     IRRef hi = 0;
 
+    if (ref >= snref) {
+      snap->ref = nref;
+      split_subst_snap(J, snap++, oir);
+      snref = snap < &J->cur.snap[J->cur.nsnap] ? snap->ref : ~(IRRef)0;
+    }
+
     /* Copy-substitute old instruction to new instruction. */
     nir->op1 = ir->op1 < nk ? ir->op1 : oir[ir->op1].prev;
     nir->op2 = ir->op2 < nk ? ir->op2 : oir[ir->op2].prev;
@@ -635,6 +657,10 @@ static void split_ir(jit_State *J)
     }
     hisubst[ref] = hi;  /* Store hiword substitution. */
   }
+  if (snref == nins) {  /* Substitution for last snapshot. */
+    snap->ref = J->cur.nins;
+    split_subst_snap(J, snap, oir);
+  }
 
   /* Add PHI marks. */
   for (ref = J->cur.nins-1; ref >= REF_FIRST; ref--) {
@@ -643,24 +669,6 @@ static void split_ir(jit_State *J)
     if (!irref_isk(ir->op1)) irt_setphi(IR(ir->op1)->t);
     if (ir->op2 > J->loopref) irt_setphi(IR(ir->op2)->t);
   }
-
-  /* Substitute snapshot maps. */
-  oir[nins].prev = J->cur.nins;  /* Substitution for last snapshot. */
-  {
-    SnapNo i, nsnap = J->cur.nsnap;
-    for (i = 0; i < nsnap; i++) {
-      SnapShot *snap = &J->cur.snap[i];
-      SnapEntry *map = &J->cur.snapmap[snap->mapofs];
-      MSize n, nent = snap->nent;
-      snap->ref = snap->ref == REF_FIRST ? REF_FIRST : oir[snap->ref].prev;
-      for (n = 0; n < nent; n++) {
-	SnapEntry sn = map[n];
-	IRIns *ir = &oir[snap_ref(sn)];
-	if (!(LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && irref_isk(snap_ref(sn))))
-	  map[n] = ((sn & 0xffff0000) | ir->prev);
-      }
-    }
-  }
 }
 
 /* Protected callback for split pass. */