Fix handling of redundant PHIs.

This commit is contained in:
Mike Pall 2013-10-26 17:31:23 +02:00
parent 7e538b5f0a
commit 8944e27762

View File

@ -105,20 +105,24 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi,
SnapNo onsnap) SnapNo onsnap)
{ {
int passx = 0; int passx = 0;
IRRef i, nslots; IRRef i, j, nslots;
IRRef invar = J->chain[IR_LOOP]; IRRef invar = J->chain[IR_LOOP];
/* Pass #1: mark redundant and potentially redundant PHIs. */ /* Pass #1: mark redundant and potentially redundant PHIs. */
for (i = 0; i < nphi; i++) { for (i = 0, j = 0; i < nphi; i++) {
IRRef lref = phi[i]; IRRef lref = phi[i];
IRRef rref = subst[lref]; IRRef rref = subst[lref];
if (lref == rref || rref == REF_DROP) { /* Invariants are redundant. */ if (lref == rref || rref == REF_DROP) { /* Invariants are redundant. */
irt_setmark(IR(lref)->t); irt_clearphi(IR(lref)->t);
} else if (!(IR(rref)->op1 == lref || IR(rref)->op2 == lref)) { } else {
/* Quick check for simple recurrences failed, need pass2. */ phi[j++] = (IRRef1)lref;
irt_setmark(IR(lref)->t); if (!(IR(rref)->op1 == lref || IR(rref)->op2 == lref)) {
passx = 1; /* Quick check for simple recurrences failed, need pass2. */
irt_setmark(IR(lref)->t);
passx = 1;
}
} }
} }
nphi = j;
/* Pass #2: traverse variant part and clear marks of non-redundant PHIs. */ /* Pass #2: traverse variant part and clear marks of non-redundant PHIs. */
if (passx) { if (passx) {
SnapNo s; SnapNo s;
@ -174,15 +178,10 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi,
IRRef lref = phi[i]; IRRef lref = phi[i];
IRIns *ir = IR(lref); IRIns *ir = IR(lref);
if (!irt_ismarked(ir->t)) { /* Propagate only from unmarked PHIs. */ if (!irt_ismarked(ir->t)) { /* Propagate only from unmarked PHIs. */
IRRef rref = subst[lref]; IRIns *irr = IR(subst[lref]);
if (lref == rref) { /* Mark redundant PHI. */ if (irt_ismarked(irr->t)) { /* Right ref points to other PHI? */
irt_setmark(ir->t); irt_clearmark(irr->t); /* Mark that PHI as non-redundant. */
} else { passx = 1; /* Retry. */
IRIns *irr = IR(rref);
if (irt_ismarked(irr->t)) { /* Right ref points to other PHI? */
irt_clearmark(irr->t); /* Mark that PHI as non-redundant. */
passx = 1; /* Retry. */
}
} }
} }
} }