diff options
| author | Mike Pall <mike> | 2010-02-01 23:32:26 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-02-01 23:32:26 +0100 |
| commit | 61c5a60dc35d96125297ca5bdadc33a3e7565036 (patch) | |
| tree | b7737b845e8a6e63dfcda595fc2db902c8f0e542 /src | |
| parent | 9a682f341decbecc649c006c1e7bd91b214a93ce (diff) | |
| download | luajit-61c5a60dc35d96125297ca5bdadc33a3e7565036.tar.gz luajit-61c5a60dc35d96125297ca5bdadc33a3e7565036.tar.bz2 luajit-61c5a60dc35d96125297ca5bdadc33a3e7565036.zip | |
Improve coalescing of BASE register in side traces.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_asm.c | 68 |
1 files changed, 47 insertions, 21 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 6562a971..38bbb1c2 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
| @@ -2807,7 +2807,7 @@ static void asm_const_remat(ASMState *as) | |||
| 2807 | while (work) { | 2807 | while (work) { |
| 2808 | Reg r = rset_pickbot(work); | 2808 | Reg r = rset_pickbot(work); |
| 2809 | IRRef ref = regcost_ref(as->cost[r]); | 2809 | IRRef ref = regcost_ref(as->cost[r]); |
| 2810 | if (irref_isk(ref) || ref == REF_BASE) { | 2810 | if (irref_isk(ref)) { |
| 2811 | ra_rematk(as, IR(ref)); | 2811 | ra_rematk(as, IR(ref)); |
| 2812 | checkmclim(as); | 2812 | checkmclim(as); |
| 2813 | } | 2813 | } |
| @@ -2815,36 +2815,36 @@ static void asm_const_remat(ASMState *as) | |||
| 2815 | } | 2815 | } |
| 2816 | } | 2816 | } |
| 2817 | 2817 | ||
| 2818 | /* Coalesce BASE register for a root trace. */ | ||
| 2819 | static void asm_head_root_base(ASMState *as) | ||
| 2820 | { | ||
| 2821 | IRIns *ir = IR(REF_BASE); | ||
| 2822 | Reg r = ir->r; | ||
| 2823 | if (ra_hasreg(r)) { | ||
| 2824 | ra_free(as, r); | ||
| 2825 | if (rset_test(as->modset, r)) | ||
| 2826 | ir->r = RID_INIT; /* No inheritance for modified BASE register. */ | ||
| 2827 | if (r != RID_BASE) | ||
| 2828 | emit_rr(as, XO_MOV, r, RID_BASE); | ||
| 2829 | } | ||
| 2830 | } | ||
| 2831 | |||
| 2818 | /* Head of a root trace. */ | 2832 | /* Head of a root trace. */ |
| 2819 | static void asm_head_root(ASMState *as) | 2833 | static void asm_head_root(ASMState *as) |
| 2820 | { | 2834 | { |
| 2821 | int32_t spadj; | 2835 | int32_t spadj; |
| 2836 | asm_head_root_base(as); | ||
| 2822 | emit_setgli(as, vmstate, (int32_t)as->J->curtrace); | 2837 | emit_setgli(as, vmstate, (int32_t)as->J->curtrace); |
| 2823 | spadj = sps_adjust(as->evenspill); | 2838 | spadj = sps_adjust(as->evenspill); |
| 2824 | as->T->spadjust = (uint16_t)spadj; | 2839 | as->T->spadjust = (uint16_t)spadj; |
| 2825 | emit_addptr(as, RID_ESP, -spadj); | 2840 | emit_addptr(as, RID_ESP, -spadj); |
| 2826 | } | 2841 | } |
| 2827 | 2842 | ||
| 2828 | /* Handle BASE coalescing for a root trace. */ | ||
| 2829 | static void asm_head_base(ASMState *as) | ||
| 2830 | { | ||
| 2831 | IRIns *ir = IR(REF_BASE); | ||
| 2832 | Reg r = ir->r; | ||
| 2833 | lua_assert(!ra_hasspill(ir->s)); | ||
| 2834 | if (ra_hasreg(r)) { | ||
| 2835 | ra_free(as, r); | ||
| 2836 | if (r != RID_BASE) { | ||
| 2837 | ra_scratch(as, RID2RSET(RID_BASE)); | ||
| 2838 | emit_rr(as, XO_MOV, r, RID_BASE); | ||
| 2839 | } | ||
| 2840 | } | ||
| 2841 | } | ||
| 2842 | |||
| 2843 | /* Check Lua stack size for overflow at the start of a side trace. | 2843 | /* Check Lua stack size for overflow at the start of a side trace. |
| 2844 | ** Stack overflow is rare, so let the regular exit handling fix this up. | 2844 | ** Stack overflow is rare, so let the regular exit handling fix this up. |
| 2845 | ** This is done in the context of the *parent* trace and parent exitno! | 2845 | ** This is done in the context of the *parent* trace and parent exitno! |
| 2846 | */ | 2846 | */ |
| 2847 | static void asm_checkstack(ASMState *as, BCReg topslot, RegSet allow) | 2847 | static void asm_checkstack(ASMState *as, BCReg topslot, Reg pbase, RegSet allow) |
| 2848 | { | 2848 | { |
| 2849 | /* Try to get an unused temp. register, otherwise spill/restore eax. */ | 2849 | /* Try to get an unused temp. register, otherwise spill/restore eax. */ |
| 2850 | Reg r = allow ? rset_pickbot(allow) : RID_EAX; | 2850 | Reg r = allow ? rset_pickbot(allow) : RID_EAX; |
| @@ -2852,13 +2852,38 @@ static void asm_checkstack(ASMState *as, BCReg topslot, RegSet allow) | |||
| 2852 | if (allow == RSET_EMPTY) /* Restore temp. register. */ | 2852 | if (allow == RSET_EMPTY) /* Restore temp. register. */ |
| 2853 | emit_rmro(as, XO_MOV, r, RID_ESP, sps_scale(SPS_TEMP1)); | 2853 | emit_rmro(as, XO_MOV, r, RID_ESP, sps_scale(SPS_TEMP1)); |
| 2854 | emit_gri(as, XG_ARITHi(XOg_CMP), r, (int32_t)(8*topslot)); | 2854 | emit_gri(as, XG_ARITHi(XOg_CMP), r, (int32_t)(8*topslot)); |
| 2855 | emit_rmro(as, XO_ARITH(XOg_SUB), r, RID_NONE, ptr2addr(&J2G(as->J)->jit_base)); | 2855 | if (ra_hasreg(pbase) && pbase != r) |
| 2856 | emit_rr(as, XO_ARITH(XOg_SUB), r, pbase); | ||
| 2857 | else | ||
| 2858 | emit_rmro(as, XO_ARITH(XOg_SUB), r, RID_NONE, | ||
| 2859 | ptr2addr(&J2G(as->J)->jit_base)); | ||
| 2856 | emit_rmro(as, XO_MOV, r, r, offsetof(lua_State, maxstack)); | 2860 | emit_rmro(as, XO_MOV, r, r, offsetof(lua_State, maxstack)); |
| 2857 | emit_getgl(as, r, jit_L); | 2861 | emit_getgl(as, r, jit_L); |
| 2858 | if (allow == RSET_EMPTY) /* Spill temp. register. */ | 2862 | if (allow == RSET_EMPTY) /* Spill temp. register. */ |
| 2859 | emit_rmro(as, XO_MOVto, r, RID_ESP, sps_scale(SPS_TEMP1)); | 2863 | emit_rmro(as, XO_MOVto, r, RID_ESP, sps_scale(SPS_TEMP1)); |
| 2860 | } | 2864 | } |
| 2861 | 2865 | ||
| 2866 | /* Coalesce or reload BASE register for a side trace. */ | ||
| 2867 | static RegSet asm_head_side_base(ASMState *as, Reg pbase, RegSet allow) | ||
| 2868 | { | ||
| 2869 | IRIns *ir = IR(REF_BASE); | ||
| 2870 | Reg r = ir->r; | ||
| 2871 | if (ra_hasreg(r)) { | ||
| 2872 | ra_free(as, r); | ||
| 2873 | if (rset_test(as->modset, r)) | ||
| 2874 | ir->r = RID_INIT; /* No inheritance for modified BASE register. */ | ||
| 2875 | if (pbase == r) { | ||
| 2876 | rset_clear(allow, r); /* Mark same BASE register as coalesced. */ | ||
| 2877 | } else if (ra_hasreg(pbase) && rset_test(as->freeset, pbase)) { | ||
| 2878 | rset_clear(allow, pbase); | ||
| 2879 | emit_rr(as, XO_MOV, r, pbase); /* Move from coalesced parent register. */ | ||
| 2880 | } else { | ||
| 2881 | emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */ | ||
| 2882 | } | ||
| 2883 | } | ||
| 2884 | return allow; | ||
| 2885 | } | ||
| 2886 | |||
| 2862 | /* Head of a side trace. | 2887 | /* Head of a side trace. |
| 2863 | ** | 2888 | ** |
| 2864 | ** The current simplistic algorithm requires that all slots inherited | 2889 | ** The current simplistic algorithm requires that all slots inherited |
| @@ -2872,11 +2897,14 @@ static void asm_head_side(ASMState *as) | |||
| 2872 | IRRef1 sloadins[RID_MAX]; | 2897 | IRRef1 sloadins[RID_MAX]; |
| 2873 | RegSet allow = RSET_ALL; /* Inverse of all coalesced registers. */ | 2898 | RegSet allow = RSET_ALL; /* Inverse of all coalesced registers. */ |
| 2874 | RegSet live = RSET_EMPTY; /* Live parent registers. */ | 2899 | RegSet live = RSET_EMPTY; /* Live parent registers. */ |
| 2900 | Reg pbase = as->parent->ir[REF_BASE].r; /* Parent base register (if any). */ | ||
| 2875 | int32_t spadj, spdelta; | 2901 | int32_t spadj, spdelta; |
| 2876 | int pass2 = 0; | 2902 | int pass2 = 0; |
| 2877 | int pass3 = 0; | 2903 | int pass3 = 0; |
| 2878 | IRRef i; | 2904 | IRRef i; |
| 2879 | 2905 | ||
| 2906 | allow = asm_head_side_base(as, pbase, allow); | ||
| 2907 | |||
| 2880 | /* Scan all parent SLOADs and collect register dependencies. */ | 2908 | /* Scan all parent SLOADs and collect register dependencies. */ |
| 2881 | for (i = as->curins; i > REF_BASE; i--) { | 2909 | for (i = as->curins; i > REF_BASE; i--) { |
| 2882 | IRIns *ir = IR(i); | 2910 | IRIns *ir = IR(i); |
| @@ -3001,7 +3029,7 @@ static void asm_head_side(ASMState *as) | |||
| 3001 | 3029 | ||
| 3002 | /* Check Lua stack size if frames have been added. */ | 3030 | /* Check Lua stack size if frames have been added. */ |
| 3003 | if (as->topslot) | 3031 | if (as->topslot) |
| 3004 | asm_checkstack(as, as->topslot, allow & RSET_GPR); | 3032 | asm_checkstack(as, as->topslot, pbase, allow & RSET_GPR); |
| 3005 | } | 3033 | } |
| 3006 | 3034 | ||
| 3007 | /* -- Tail of trace ------------------------------------------------------- */ | 3035 | /* -- Tail of trace ------------------------------------------------------- */ |
| @@ -3464,8 +3492,6 @@ void lj_asm_trace(jit_State *J, Trace *T) | |||
| 3464 | checkmclim(as); | 3492 | checkmclim(as); |
| 3465 | if (as->gcsteps) | 3493 | if (as->gcsteps) |
| 3466 | asm_gc_check(as, &as->T->snap[0]); | 3494 | asm_gc_check(as, &as->T->snap[0]); |
| 3467 | if (!J->parent) | ||
| 3468 | asm_head_base(as); | ||
| 3469 | asm_const_remat(as); | 3495 | asm_const_remat(as); |
| 3470 | if (J->parent) | 3496 | if (J->parent) |
| 3471 | asm_head_side(as); | 3497 | asm_head_side(as); |
