aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2012-04-19 15:05:55 +0200
committerMike Pall <mike>2012-04-19 15:05:55 +0200
commitba3cad0dd9905b873318f8415491ea9cd68bdca4 (patch)
tree703f95c0149a4c7afa447c8b8139512aa3543d49
parentac6b678d4c127859f09267c00db99578d73ef47c (diff)
downloadluajit-ba3cad0dd9905b873318f8415491ea9cd68bdca4.tar.gz
luajit-ba3cad0dd9905b873318f8415491ea9cd68bdca4.tar.bz2
luajit-ba3cad0dd9905b873318f8415491ea9cd68bdca4.zip
Add required PHIs for implicit conversions (via XREF fwd).
-rw-r--r--src/lj_opt_loop.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/src/lj_opt_loop.c b/src/lj_opt_loop.c
index ed7d9252..923387cc 100644
--- a/src/lj_opt_loop.c
+++ b/src/lj_opt_loop.c
@@ -321,29 +321,37 @@ static void loop_unroll(jit_State *J)
321 IRType1 t = ir->t; /* Get this first, since emitir may invalidate ir. */ 321 IRType1 t = ir->t; /* Get this first, since emitir may invalidate ir. */
322 IRRef ref = tref_ref(emitir(ir->ot & ~IRT_ISPHI, op1, op2)); 322 IRRef ref = tref_ref(emitir(ir->ot & ~IRT_ISPHI, op1, op2));
323 subst[ins] = (IRRef1)ref; 323 subst[ins] = (IRRef1)ref;
324 if (ref != ins && ref < invar) { /* Loop-carried dependency? */ 324 if (ref != ins) {
325 IRIns *irr = IR(ref); 325 IRIns *irr = IR(ref);
326 /* Potential PHI? */ 326 if (ref < invar) { /* Loop-carried dependency? */
327 if (!irref_isk(ref) && !irt_isphi(irr->t) && !irt_ispri(irr->t)) { 327 /* Potential PHI? */
328 irt_setphi(irr->t); 328 if (!irref_isk(ref) && !irt_isphi(irr->t) && !irt_ispri(irr->t)) {
329 if (nphi >= LJ_MAX_PHI) 329 irt_setphi(irr->t);
330 lj_trace_err(J, LJ_TRERR_PHIOV); 330 if (nphi >= LJ_MAX_PHI)
331 phi[nphi++] = (IRRef1)ref; 331 lj_trace_err(J, LJ_TRERR_PHIOV);
332 } 332 phi[nphi++] = (IRRef1)ref;
333 /* Check all loop-carried dependencies for type instability. */ 333 }
334 if (!irt_sametype(t, irr->t)) { 334 /* Check all loop-carried dependencies for type instability. */
335 if (irt_isinteger(t) && irt_isinteger(irr->t)) 335 if (!irt_sametype(t, irr->t)) {
336 continue; 336 if (irt_isinteger(t) && irt_isinteger(irr->t))
337 else if (irt_isnum(t) && irt_isinteger(irr->t)) /* Fix int->num. */ 337 continue; //XXX
338 ref = tref_ref(emitir(IRTN(IR_CONV), ref, IRCONV_NUM_INT)); 338 else if (irt_isnum(t) && irt_isinteger(irr->t)) /* Fix int->num. */
339 else if (irt_isnum(irr->t) && irt_isinteger(t)) /* Fix num->int. */ 339 ref = tref_ref(emitir(IRTN(IR_CONV), ref, IRCONV_NUM_INT));
340 ref = tref_ref(emitir(IRTGI(IR_CONV), ref, 340 else if (irt_isnum(irr->t) && irt_isinteger(t)) /* Fix num->int. */
341 IRCONV_INT_NUM|IRCONV_CHECK)); 341 ref = tref_ref(emitir(IRTGI(IR_CONV), ref,
342 else 342 IRCONV_INT_NUM|IRCONV_CHECK));
343 lj_trace_err(J, LJ_TRERR_TYPEINS); 343 else
344 subst[ins] = (IRRef1)ref; 344 lj_trace_err(J, LJ_TRERR_TYPEINS);
345 /* May need a PHI for the CONV, too. */ 345 subst[ins] = (IRRef1)ref;
346 irr = IR(ref);
347 goto phiconv;
348 }
349 } else if (ref != REF_DROP && irr->o == IR_CONV &&
350 ref > invar && irr->op1 < invar) {
351 /* May need an extra PHI for a CONV. */
352 ref = irr->op1;
346 irr = IR(ref); 353 irr = IR(ref);
354 phiconv:
347 if (ref < invar && !irref_isk(ref) && !irt_isphi(irr->t)) { 355 if (ref < invar && !irref_isk(ref) && !irt_isphi(irr->t)) {
348 irt_setphi(irr->t); 356 irt_setphi(irr->t);
349 if (nphi >= LJ_MAX_PHI) 357 if (nphi >= LJ_MAX_PHI)