Add required PHIs for implicit conversions (via XREF fwd).

This commit is contained in:
Mike Pall 2012-04-19 15:05:55 +02:00
parent ac6b678d4c
commit ba3cad0dd9

View File

@ -321,29 +321,37 @@ static void loop_unroll(jit_State *J)
IRType1 t = ir->t; /* Get this first, since emitir may invalidate ir. */ IRType1 t = ir->t; /* Get this first, since emitir may invalidate ir. */
IRRef ref = tref_ref(emitir(ir->ot & ~IRT_ISPHI, op1, op2)); IRRef ref = tref_ref(emitir(ir->ot & ~IRT_ISPHI, op1, op2));
subst[ins] = (IRRef1)ref; subst[ins] = (IRRef1)ref;
if (ref != ins && ref < invar) { /* Loop-carried dependency? */ if (ref != ins) {
IRIns *irr = IR(ref); IRIns *irr = IR(ref);
/* Potential PHI? */ if (ref < invar) { /* Loop-carried dependency? */
if (!irref_isk(ref) && !irt_isphi(irr->t) && !irt_ispri(irr->t)) { /* Potential PHI? */
irt_setphi(irr->t); if (!irref_isk(ref) && !irt_isphi(irr->t) && !irt_ispri(irr->t)) {
if (nphi >= LJ_MAX_PHI) irt_setphi(irr->t);
lj_trace_err(J, LJ_TRERR_PHIOV); if (nphi >= LJ_MAX_PHI)
phi[nphi++] = (IRRef1)ref; lj_trace_err(J, LJ_TRERR_PHIOV);
} phi[nphi++] = (IRRef1)ref;
/* Check all loop-carried dependencies for type instability. */ }
if (!irt_sametype(t, irr->t)) { /* Check all loop-carried dependencies for type instability. */
if (irt_isinteger(t) && irt_isinteger(irr->t)) if (!irt_sametype(t, irr->t)) {
continue; if (irt_isinteger(t) && irt_isinteger(irr->t))
else if (irt_isnum(t) && irt_isinteger(irr->t)) /* Fix int->num. */ continue; //XXX
ref = tref_ref(emitir(IRTN(IR_CONV), ref, IRCONV_NUM_INT)); else if (irt_isnum(t) && irt_isinteger(irr->t)) /* Fix int->num. */
else if (irt_isnum(irr->t) && irt_isinteger(t)) /* Fix num->int. */ ref = tref_ref(emitir(IRTN(IR_CONV), ref, IRCONV_NUM_INT));
ref = tref_ref(emitir(IRTGI(IR_CONV), ref, else if (irt_isnum(irr->t) && irt_isinteger(t)) /* Fix num->int. */
IRCONV_INT_NUM|IRCONV_CHECK)); ref = tref_ref(emitir(IRTGI(IR_CONV), ref,
else IRCONV_INT_NUM|IRCONV_CHECK));
lj_trace_err(J, LJ_TRERR_TYPEINS); else
subst[ins] = (IRRef1)ref; lj_trace_err(J, LJ_TRERR_TYPEINS);
/* May need a PHI for the CONV, too. */ subst[ins] = (IRRef1)ref;
irr = IR(ref);
goto phiconv;
}
} else if (ref != REF_DROP && irr->o == IR_CONV &&
ref > invar && irr->op1 < invar) {
/* May need an extra PHI for a CONV. */
ref = irr->op1;
irr = IR(ref); irr = IR(ref);
phiconv:
if (ref < invar && !irref_isk(ref) && !irt_isphi(irr->t)) { if (ref < invar && !irref_isk(ref) && !irt_isphi(irr->t)) {
irt_setphi(irr->t); irt_setphi(irr->t);
if (nphi >= LJ_MAX_PHI) if (nphi >= LJ_MAX_PHI)