diff options
| author | Mike Pall <mike> | 2011-06-20 21:51:31 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-06-20 21:51:31 +0200 |
| commit | 4df40a228fe2d7aabf75aa5f75af66eec15e03c5 (patch) | |
| tree | 156b36489fed98897ce9eafc88879a8fd40f030c | |
| parent | 31d566428fe85cdd8c94a01ccab5a2d602286db8 (diff) | |
| download | luajit-4df40a228fe2d7aabf75aa5f75af66eec15e03c5.tar.gz luajit-4df40a228fe2d7aabf75aa5f75af66eec15e03c5.tar.bz2 luajit-4df40a228fe2d7aabf75aa5f75af66eec15e03c5.zip | |
Fix recording of loops with instable directions in side traces.
| -rw-r--r-- | src/lj_record.c | 13 |
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. */ |
| 336 | static void rec_for_check(jit_State *J, IRType t, int dir, TRef stop, TRef step) | 336 | static 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); |
