mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 15:14:08 +00:00
Improve coalescing of BASE register in side traces.
This commit is contained in:
parent
9a682f341d
commit
61c5a60dc3
68
src/lj_asm.c
68
src/lj_asm.c
@ -2807,7 +2807,7 @@ static void asm_const_remat(ASMState *as)
|
||||
while (work) {
|
||||
Reg r = rset_pickbot(work);
|
||||
IRRef ref = regcost_ref(as->cost[r]);
|
||||
if (irref_isk(ref) || ref == REF_BASE) {
|
||||
if (irref_isk(ref)) {
|
||||
ra_rematk(as, IR(ref));
|
||||
checkmclim(as);
|
||||
}
|
||||
@ -2815,36 +2815,36 @@ static void asm_const_remat(ASMState *as)
|
||||
}
|
||||
}
|
||||
|
||||
/* Coalesce BASE register for a root trace. */
|
||||
static void asm_head_root_base(ASMState *as)
|
||||
{
|
||||
IRIns *ir = IR(REF_BASE);
|
||||
Reg r = ir->r;
|
||||
if (ra_hasreg(r)) {
|
||||
ra_free(as, r);
|
||||
if (rset_test(as->modset, r))
|
||||
ir->r = RID_INIT; /* No inheritance for modified BASE register. */
|
||||
if (r != RID_BASE)
|
||||
emit_rr(as, XO_MOV, r, RID_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Head of a root trace. */
|
||||
static void asm_head_root(ASMState *as)
|
||||
{
|
||||
int32_t spadj;
|
||||
asm_head_root_base(as);
|
||||
emit_setgli(as, vmstate, (int32_t)as->J->curtrace);
|
||||
spadj = sps_adjust(as->evenspill);
|
||||
as->T->spadjust = (uint16_t)spadj;
|
||||
emit_addptr(as, RID_ESP, -spadj);
|
||||
}
|
||||
|
||||
/* Handle BASE coalescing for a root trace. */
|
||||
static void asm_head_base(ASMState *as)
|
||||
{
|
||||
IRIns *ir = IR(REF_BASE);
|
||||
Reg r = ir->r;
|
||||
lua_assert(!ra_hasspill(ir->s));
|
||||
if (ra_hasreg(r)) {
|
||||
ra_free(as, r);
|
||||
if (r != RID_BASE) {
|
||||
ra_scratch(as, RID2RSET(RID_BASE));
|
||||
emit_rr(as, XO_MOV, r, RID_BASE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check Lua stack size for overflow at the start of a side trace.
|
||||
** Stack overflow is rare, so let the regular exit handling fix this up.
|
||||
** This is done in the context of the *parent* trace and parent exitno!
|
||||
*/
|
||||
static void asm_checkstack(ASMState *as, BCReg topslot, RegSet allow)
|
||||
static void asm_checkstack(ASMState *as, BCReg topslot, Reg pbase, RegSet allow)
|
||||
{
|
||||
/* Try to get an unused temp. register, otherwise spill/restore eax. */
|
||||
Reg r = allow ? rset_pickbot(allow) : RID_EAX;
|
||||
@ -2852,13 +2852,38 @@ static void asm_checkstack(ASMState *as, BCReg topslot, RegSet allow)
|
||||
if (allow == RSET_EMPTY) /* Restore temp. register. */
|
||||
emit_rmro(as, XO_MOV, r, RID_ESP, sps_scale(SPS_TEMP1));
|
||||
emit_gri(as, XG_ARITHi(XOg_CMP), r, (int32_t)(8*topslot));
|
||||
emit_rmro(as, XO_ARITH(XOg_SUB), r, RID_NONE, ptr2addr(&J2G(as->J)->jit_base));
|
||||
if (ra_hasreg(pbase) && pbase != r)
|
||||
emit_rr(as, XO_ARITH(XOg_SUB), r, pbase);
|
||||
else
|
||||
emit_rmro(as, XO_ARITH(XOg_SUB), r, RID_NONE,
|
||||
ptr2addr(&J2G(as->J)->jit_base));
|
||||
emit_rmro(as, XO_MOV, r, r, offsetof(lua_State, maxstack));
|
||||
emit_getgl(as, r, jit_L);
|
||||
if (allow == RSET_EMPTY) /* Spill temp. register. */
|
||||
emit_rmro(as, XO_MOVto, r, RID_ESP, sps_scale(SPS_TEMP1));
|
||||
}
|
||||
|
||||
/* Coalesce or reload BASE register for a side trace. */
|
||||
static RegSet asm_head_side_base(ASMState *as, Reg pbase, RegSet allow)
|
||||
{
|
||||
IRIns *ir = IR(REF_BASE);
|
||||
Reg r = ir->r;
|
||||
if (ra_hasreg(r)) {
|
||||
ra_free(as, r);
|
||||
if (rset_test(as->modset, r))
|
||||
ir->r = RID_INIT; /* No inheritance for modified BASE register. */
|
||||
if (pbase == r) {
|
||||
rset_clear(allow, r); /* Mark same BASE register as coalesced. */
|
||||
} else if (ra_hasreg(pbase) && rset_test(as->freeset, pbase)) {
|
||||
rset_clear(allow, pbase);
|
||||
emit_rr(as, XO_MOV, r, pbase); /* Move from coalesced parent register. */
|
||||
} else {
|
||||
emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
|
||||
}
|
||||
}
|
||||
return allow;
|
||||
}
|
||||
|
||||
/* Head of a side trace.
|
||||
**
|
||||
** The current simplistic algorithm requires that all slots inherited
|
||||
@ -2872,11 +2897,14 @@ static void asm_head_side(ASMState *as)
|
||||
IRRef1 sloadins[RID_MAX];
|
||||
RegSet allow = RSET_ALL; /* Inverse of all coalesced registers. */
|
||||
RegSet live = RSET_EMPTY; /* Live parent registers. */
|
||||
Reg pbase = as->parent->ir[REF_BASE].r; /* Parent base register (if any). */
|
||||
int32_t spadj, spdelta;
|
||||
int pass2 = 0;
|
||||
int pass3 = 0;
|
||||
IRRef i;
|
||||
|
||||
allow = asm_head_side_base(as, pbase, allow);
|
||||
|
||||
/* Scan all parent SLOADs and collect register dependencies. */
|
||||
for (i = as->curins; i > REF_BASE; i--) {
|
||||
IRIns *ir = IR(i);
|
||||
@ -3001,7 +3029,7 @@ static void asm_head_side(ASMState *as)
|
||||
|
||||
/* Check Lua stack size if frames have been added. */
|
||||
if (as->topslot)
|
||||
asm_checkstack(as, as->topslot, allow & RSET_GPR);
|
||||
asm_checkstack(as, as->topslot, pbase, allow & RSET_GPR);
|
||||
}
|
||||
|
||||
/* -- Tail of trace ------------------------------------------------------- */
|
||||
@ -3464,8 +3492,6 @@ void lj_asm_trace(jit_State *J, Trace *T)
|
||||
checkmclim(as);
|
||||
if (as->gcsteps)
|
||||
asm_gc_check(as, &as->T->snap[0]);
|
||||
if (!J->parent)
|
||||
asm_head_base(as);
|
||||
asm_const_remat(as);
|
||||
if (J->parent)
|
||||
asm_head_side(as);
|
||||
|
Loading…
Reference in New Issue
Block a user