diff options
| author | Mike Pall <mike> | 2010-12-09 16:12:59 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-12-09 16:12:59 +0100 |
| commit | 1d860909269ebc89f475793b4034d565544a0869 (patch) | |
| tree | 5e15c5dc1a5377b24ec9238985bea4dc906be17a /src | |
| parent | 36fed9f3e1af587d331e8c070059163f2ac6432e (diff) | |
| download | luajit-1d860909269ebc89f475793b4034d565544a0869.tar.gz luajit-1d860909269ebc89f475793b4034d565544a0869.tar.bz2 luajit-1d860909269ebc89f475793b4034d565544a0869.zip | |
Strength-reduce 32 to 64 bit widening using scalar evolution analysis.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_crecord.c | 10 | ||||
| -rw-r--r-- | src/lj_opt_fold.c | 45 |
2 files changed, 49 insertions, 6 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index c7c99133..566c064b 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
| @@ -335,15 +335,17 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) | |||
| 335 | IRIns *ir = IR(tref_ref(idx)); | 335 | IRIns *ir = IR(tref_ref(idx)); |
| 336 | if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && | 336 | if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && |
| 337 | ir->o == IR_ADD && irref_isk(ir->op2)) { | 337 | ir->o == IR_ADD && irref_isk(ir->op2)) { |
| 338 | IRIns *irk = IR(ir->op2); | ||
| 339 | idx = ir->op1; | ||
| 338 | /* This would be rather difficult in FOLD, so do it here: | 340 | /* This would be rather difficult in FOLD, so do it here: |
| 339 | ** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz) | 341 | ** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz) |
| 340 | */ | 342 | */ |
| 341 | idx = ir->op1; | ||
| 342 | #if LJ_64 | 343 | #if LJ_64 |
| 343 | ofs += (int64_t)ir_kint64(IR(ir->op2))->u64 * sz; | 344 | if (irk->o == IR_KINT64) |
| 344 | #else | 345 | ofs += (ptrdiff_t)ir_kint64(irk)->u64 * sz; |
| 345 | ofs += IR(ir->op2)->i * sz; | 346 | else |
| 346 | #endif | 347 | #endif |
| 348 | ofs += (ptrdiff_t)irk->i * sz; | ||
| 347 | } | 349 | } |
| 348 | idx = emitir(IRT(IR_MUL, IRT_INTP), idx, lj_ir_kintp(J, sz)); | 350 | idx = emitir(IRT(IR_MUL, IRT_INTP), idx, lj_ir_kintp(J, sz)); |
| 349 | ptr = emitir(IRT(IR_ADD, IRT_PTR), idx, ptr); | 351 | ptr = emitir(IRT(IR_ADD, IRT_PTR), idx, ptr); |
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index d650f09c..e8e81a3e 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
| @@ -644,8 +644,8 @@ LJFOLD(TOINT ADD any) | |||
| 644 | LJFOLD(TOINT SUB any) | 644 | LJFOLD(TOINT SUB any) |
| 645 | LJFOLD(TOBIT ADD KNUM) | 645 | LJFOLD(TOBIT ADD KNUM) |
| 646 | LJFOLD(TOBIT SUB KNUM) | 646 | LJFOLD(TOBIT SUB KNUM) |
| 647 | LJFOLD(TOI64 ADD any) | 647 | LJFOLD(TOI64 ADD 5) /* IRTOINT_TRUNCI64 */ |
| 648 | LJFOLD(TOI64 SUB any) | 648 | LJFOLD(TOI64 SUB 5) /* IRTOINT_TRUNCI64 */ |
| 649 | LJFOLDF(narrow_convert) | 649 | LJFOLDF(narrow_convert) |
| 650 | { | 650 | { |
| 651 | PHIBARRIER(fleft); | 651 | PHIBARRIER(fleft); |
| @@ -669,6 +669,47 @@ LJFOLDF(cse_toint) | |||
| 669 | return EMITFOLD; /* No fallthrough to regular CSE. */ | 669 | return EMITFOLD; /* No fallthrough to regular CSE. */ |
| 670 | } | 670 | } |
| 671 | 671 | ||
| 672 | /* -- Strength reduction of widening -------------------------------------- */ | ||
| 673 | |||
| 674 | LJFOLD(TOI64 any 3) /* IRTOINT_ZEXT64 */ | ||
| 675 | LJFOLDF(simplify_zext64) | ||
| 676 | { | ||
| 677 | #if LJ_TARGET_X64 | ||
| 678 | /* Eliminate widening. All 32 bit ops implicitly zero-extend the result. */ | ||
| 679 | return LEFTFOLD; | ||
| 680 | #else | ||
| 681 | UNUSED(J); | ||
| 682 | return NEXTFOLD; | ||
| 683 | #endif | ||
| 684 | } | ||
| 685 | |||
| 686 | LJFOLD(TOI64 any 4) /* IRTOINT_SEXT64 */ | ||
| 687 | LJFOLDF(simplify_sext64) | ||
| 688 | { | ||
| 689 | IRRef ref = fins->op1; | ||
| 690 | int64_t ofs = 0; | ||
| 691 | if (fleft->o == IR_ADD && irref_isk(fleft->op2)) { | ||
| 692 | ofs = (int64_t)IR(fleft->op2)->i; | ||
| 693 | ref = fleft->op1; | ||
| 694 | } | ||
| 695 | /* Use scalar evolution analysis results to strength-reduce sign-extension. */ | ||
| 696 | if (ref == J->scev.idx) { | ||
| 697 | IRRef lo = J->scev.dir ? J->scev.start : J->scev.stop; | ||
| 698 | lua_assert(irt_isint(J->scev.t)); | ||
| 699 | if (lo && IR(lo)->i + ofs >= 0) { | ||
| 700 | #if LJ_TARGET_X64 | ||
| 701 | /* Eliminate widening. All 32 bit ops do an implicit zero-extension. */ | ||
| 702 | return LEFTFOLD; | ||
| 703 | #else | ||
| 704 | /* Reduce to a (cheaper) zero-extension. */ | ||
| 705 | fins->op2 = IRTOINT_ZEXT64; | ||
| 706 | return RETRYFOLD; | ||
| 707 | #endif | ||
| 708 | } | ||
| 709 | } | ||
| 710 | return NEXTFOLD; | ||
| 711 | } | ||
| 712 | |||
| 672 | /* -- Integer algebraic simplifications ----------------------------------- */ | 713 | /* -- Integer algebraic simplifications ----------------------------------- */ |
| 673 | 714 | ||
| 674 | LJFOLD(ADD any KINT) | 715 | LJFOLD(ADD any KINT) |
