aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-06-20 21:51:31 +0200
committerMike Pall <mike>2011-06-20 21:51:31 +0200
commit4df40a228fe2d7aabf75aa5f75af66eec15e03c5 (patch)
tree156b36489fed98897ce9eafc88879a8fd40f030c /src
parent31d566428fe85cdd8c94a01ccab5a2d602286db8 (diff)
downloadluajit-4df40a228fe2d7aabf75aa5f75af66eec15e03c5.tar.gz
luajit-4df40a228fe2d7aabf75aa5f75af66eec15e03c5.tar.bz2
luajit-4df40a228fe2d7aabf75aa5f75af66eec15e03c5.zip
Fix recording of loops with instable directions in side traces.
Diffstat (limited to 'src')
-rw-r--r--src/lj_record.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/src/lj_record.c b/src/lj_record.c
index edfff50b..63d5e4c1 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -333,14 +333,15 @@ static LoopEvent rec_for_iter(IROp *op, cTValue *o, int isforl)
333} 333}
334 334
335/* Record checks for FOR loop overflow and step direction. */ 335/* Record checks for FOR loop overflow and step direction. */
336static void rec_for_check(jit_State *J, IRType t, int dir, TRef stop, TRef step) 336static void rec_for_check(jit_State *J, IRType t, int dir,
337 TRef stop, TRef step, int init)
337{ 338{
338 if (!tref_isk(step)) { 339 if (!tref_isk(step)) {
339 /* Non-constant step: need a guard for the direction. */ 340 /* Non-constant step: need a guard for the direction. */
340 TRef zero = (t == IRT_INT) ? lj_ir_kint(J, 0) : lj_ir_knum_zero(J); 341 TRef zero = (t == IRT_INT) ? lj_ir_kint(J, 0) : lj_ir_knum_zero(J);
341 emitir(IRTG(dir ? IR_GE : IR_LT, t), step, zero); 342 emitir(IRTG(dir ? IR_GE : IR_LT, t), step, zero);
342 /* Add hoistable overflow checks for a narrowed FORL index. */ 343 /* Add hoistable overflow checks for a narrowed FORL index. */
343 if (t == IRT_INT) { 344 if (init && t == IRT_INT) {
344 if (tref_isk(stop)) { 345 if (tref_isk(stop)) {
345 /* Constant stop: optimize check away or to a range check for step. */ 346 /* Constant stop: optimize check away or to a range check for step. */
346 int32_t k = IR(tref_ref(stop))->i; 347 int32_t k = IR(tref_ref(stop))->i;
@@ -357,7 +358,7 @@ static void rec_for_check(jit_State *J, IRType t, int dir, TRef stop, TRef step)
357 emitir(IRTI(IR_USE), tr, 0); /* ADDOV is weak. Avoid dead result. */ 358 emitir(IRTI(IR_USE), tr, 0); /* ADDOV is weak. Avoid dead result. */
358 } 359 }
359 } 360 }
360 } else if (t == IRT_INT && !tref_isk(stop)) { 361 } else if (init && t == IRT_INT && !tref_isk(stop)) {
361 /* Constant step: optimize overflow check to a range check for stop. */ 362 /* Constant step: optimize overflow check to a range check for stop. */
362 int32_t k = IR(tref_ref(step))->i; 363 int32_t k = IR(tref_ref(step))->i;
363 k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k; 364 k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
@@ -384,8 +385,7 @@ static void rec_for_loop(jit_State *J, const BCIns *fori, ScEvEntry *scev,
384 scev->dir = dir; 385 scev->dir = dir;
385 scev->stop = tref_ref(stop); 386 scev->stop = tref_ref(stop);
386 scev->step = tref_ref(step); 387 scev->step = tref_ref(step);
387 if (init) 388 rec_for_check(J, t, dir, stop, step, init);
388 rec_for_check(J, t, dir, stop, step);
389 scev->start = tref_ref(find_kinit(J, fori, ra+FORL_IDX, IRT_INT)); 389 scev->start = tref_ref(find_kinit(J, fori, ra+FORL_IDX, IRT_INT));
390 tc = (LJ_DUALNUM && 390 tc = (LJ_DUALNUM &&
391 !(scev->start && irref_isk(scev->stop) && irref_isk(scev->step) && 391 !(scev->start && irref_isk(scev->stop) && irref_isk(scev->step) &&
@@ -447,7 +447,8 @@ static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl)
447 } 447 }
448 tr[FORL_EXT] = tr[FORL_IDX]; 448 tr[FORL_EXT] = tr[FORL_IDX];
449 stop = tr[FORL_STOP]; 449 stop = tr[FORL_STOP];
450 rec_for_check(J, t, rec_for_direction(&tv[FORL_STEP]), stop, tr[FORL_STEP]); 450 rec_for_check(J, t, rec_for_direction(&tv[FORL_STEP]),
451 stop, tr[FORL_STEP], 1);
451 } 452 }
452 453
453 ev = rec_for_iter(&op, tv, isforl); 454 ev = rec_for_iter(&op, tv, isforl);