Do not eliminate PHIs for values only referenced from side exits.

This commit is contained in:
Mike Pall 2010-06-30 23:30:08 +02:00
parent 9f6707ddbb
commit bbd1584d5f

View File

@ -101,7 +101,8 @@
/* -- 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;
@ -120,11 +121,21 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi)
}
/* 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;
@ -133,11 +144,7 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi)
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)
@ -222,7 +229,8 @@ static void loop_unroll(jit_State *J)
IRRef1 phi[LJ_MAX_PHI];
uint32_t nphi = 0;
IRRef1 *subst;
SnapShot *osnap;
SnapNo onsnap;
SnapShot *osnap, *loopsnap;
SnapEntry *loopmap, *psentinel;
IRRef ins, invar;
@ -244,20 +252,17 @@ static void loop_unroll(jit_State *J)
** 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];
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];
@ -308,11 +313,11 @@ static void loop_unroll(jit_State *J)
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];
@ -346,7 +351,7 @@ static TValue *cploop_opt(lua_State *L, lua_CFunction dummy, void *ud)
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;