diff options
-rw-r--r-- | src/lj_opt_loop.c | 50 |
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) |