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); |