/* -- PHI elimination ----------------------------------------------------- */
/* Emit or eliminate collected PHIs. */
-static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi)
+static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi,
+ SnapNo onsnap)
{
int pass2 = 0;
IRRef i, nslots;
}
/* Pass #2: traverse variant part and clear marks of non-redundant PHIs. */
if (pass2) {
+ SnapNo s;
for (i = J->cur.nins-1; i > invar; i--) {
IRIns *ir = IR(i);
if (!irref_isk(ir->op1)) irt_clearmark(IR(ir->op1)->t);
if (!irref_isk(ir->op2)) irt_clearmark(IR(ir->op2)->t);
}
+ for (s = J->cur.nsnap-1; s >= onsnap; s--) {
+ SnapShot *snap = &J->cur.snap[s];
+ SnapEntry *map = &J->cur.snapmap[snap->mapofs];
+ MSize n, nent = snap->nent;
+ for (n = 0; n < nent; n++) {
+ IRRef ref = snap_ref(map[n]);
+ if (!irref_isk(ref)) irt_clearmark(IR(ref)->t);
+ }
+ }
}
/* Pass #3: add PHIs for variant slots without a corresponding SLOAD. */
nslots = J->baseslot+J->maxslot;
while (!irref_isk(ref) && ref != subst[ref]) {
IRIns *ir = IR(ref);
irt_clearmark(ir->t); /* Unmark potential uses, too. */
- if (irt_isphi(ir->t)) {
- irt_clearmark(IR(subst[ref])->t);
- break;
- }
- if (irt_ispri(ir->t))
+ if (irt_isphi(ir->t) || irt_ispri(ir->t))
break;
irt_setphi(ir->t);
if (nphi >= LJ_MAX_PHI)
IRRef1 phi[LJ_MAX_PHI];
uint32_t nphi = 0;
IRRef1 *subst;
- SnapShot *osnap;
+ SnapNo onsnap;
+ SnapShot *osnap, *loopsnap;
SnapEntry *loopmap, *psentinel;
IRRef ins, invar;
** from the loop snapshot entries for each new snapshot.
** Caveat: both calls may reallocate J->cur.snap and J->cur.snapmap!
*/
- {
- MSize nsnap = J->cur.nsnap;
- SnapShot *loopsnap;
- lj_snap_grow_buf(J, 2*nsnap-2);
- lj_snap_grow_map(J, J->cur.nsnapmap*2+(nsnap-2)*J->cur.snap[nsnap-1].nent);
+ onsnap = J->cur.nsnap;
+ lj_snap_grow_buf(J, 2*onsnap-2);
+ lj_snap_grow_map(J, J->cur.nsnapmap*2+(onsnap-2)*J->cur.snap[onsnap-1].nent);
- /* The loop snapshot is used for fallback substitutions. */
- loopsnap = &J->cur.snap[nsnap-1];
- loopmap = &J->cur.snapmap[loopsnap->mapofs];
- /* The PC of snapshot #0 and the loop snapshot must match. */
- psentinel = &loopmap[loopsnap->nent];
- lua_assert(*psentinel == J->cur.snapmap[J->cur.snap[0].nent]);
- *psentinel = SNAP(255, 0, 0); /* Replace PC with temporary sentinel. */
- }
+ /* The loop snapshot is used for fallback substitutions. */
+ loopsnap = &J->cur.snap[onsnap-1];
+ loopmap = &J->cur.snapmap[loopsnap->mapofs];
+ /* The PC of snapshot #0 and the loop snapshot must match. */
+ psentinel = &loopmap[loopsnap->nent];
+ lua_assert(*psentinel == J->cur.snapmap[J->cur.snap[0].nent]);
+ *psentinel = SNAP(255, 0, 0); /* Replace PC with temporary sentinel. */
/* Start substitution with snapshot #1 (#0 is empty for root traces). */
osnap = &J->cur.snap[1];
lua_assert(J->cur.nsnapmap <= J->sizesnapmap);
*psentinel = J->cur.snapmap[J->cur.snap[0].nent]; /* Restore PC. */
- loop_emit_phi(J, subst, phi, nphi);
+ loop_emit_phi(J, subst, phi, nphi, onsnap);
}
/* Undo any partial changes made by the loop optimization. */
-static void loop_undo(jit_State *J, IRRef ins, MSize nsnap)
+static void loop_undo(jit_State *J, IRRef ins, SnapNo nsnap)
{
ptrdiff_t i;
SnapShot *snap = &J->cur.snap[nsnap-1];
int lj_opt_loop(jit_State *J)
{
IRRef nins = J->cur.nins;
- MSize nsnap = J->cur.nsnap;
+ SnapNo nsnap = J->cur.nsnap;
int errcode = lj_vm_cpcall(J->L, NULL, J, cploop_opt);
if (LJ_UNLIKELY(errcode)) {
lua_State *L = J->L;