aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-02-01 23:32:26 +0100
committerMike Pall <mike>2010-02-01 23:32:26 +0100
commit61c5a60dc35d96125297ca5bdadc33a3e7565036 (patch)
treeb7737b845e8a6e63dfcda595fc2db902c8f0e542 /src
parent9a682f341decbecc649c006c1e7bd91b214a93ce (diff)
downloadluajit-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.c68
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. */
2819static 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. */
2819static void asm_head_root(ASMState *as) 2833static 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. */
2829static 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*/
2847static void asm_checkstack(ASMState *as, BCReg topslot, RegSet allow) 2847static 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. */
2867static 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);