Fix base register coalescing in side trace.

Thanks to Sergey Kaplun, NiLuJe and Peter Cawley. #1031 #1016
This commit is contained in:
Mike Pall 2023-07-12 21:56:17 +02:00
parent a01cba9d2d
commit aa2db7ebd1
5 changed files with 21 additions and 17 deletions

View File

@ -1366,6 +1366,7 @@ static void asm_head_side(ASMState *as)
RegSet allow = RSET_ALL; /* Inverse of all coalesced registers. */
RegSet live = RSET_EMPTY; /* Live parent registers. */
RegSet pallow = RSET_GPR; /* Registers needed by the parent stack check. */
Reg pbase;
IRIns *irp = &as->parent->ir[REF_BASE]; /* Parent base. */
int32_t spadj, spdelta;
int pass2 = 0;
@ -1377,7 +1378,11 @@ static void asm_head_side(ASMState *as)
as->snapno = 0;
asm_snap_alloc(as);
}
allow = asm_head_side_base(as, irp, allow);
pbase = asm_head_side_base(as, irp);
if (pbase != RID_NONE) {
rset_clear(allow, pbase);
rset_clear(pallow, pbase);
}
/* Scan all parent SLOADs and collect register dependencies. */
for (i = as->stopins; i > REF_BASE; i--) {

View File

@ -2114,7 +2114,7 @@ static void asm_head_root_base(ASMState *as)
}
/* Coalesce BASE register for a side trace. */
static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
static Reg asm_head_side_base(ASMState *as, IRIns *irp)
{
IRIns *ir;
asm_head_lreg(as);
@ -2122,16 +2122,15 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
if (ra_hasreg(ir->r) && (rset_test(as->modset, ir->r) || irt_ismarked(ir->t)))
ra_spill(as, ir);
if (ra_hasspill(irp->s)) {
rset_clear(allow, ra_dest(as, ir, allow));
return ra_dest(as, ir, RSET_GPR);
} else {
Reg r = irp->r;
lua_assert(ra_hasreg(r));
rset_clear(allow, r);
if (r != ir->r && !rset_test(as->freeset, r))
ra_restore(as, regcost_ref(as->cost[r]));
ra_destreg(as, ir, r);
return r;
}
return allow;
}
/* -- Tail of trace ------------------------------------------------------- */

View File

@ -1732,7 +1732,7 @@ static void asm_head_root_base(ASMState *as)
}
/* Coalesce BASE register for a side trace. */
static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
static Reg asm_head_side_base(ASMState *as, IRIns *irp)
{
IRIns *ir = IR(REF_BASE);
Reg r = ir->r;
@ -1742,15 +1742,15 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
if (rset_test(as->modset, r) || irt_ismarked(ir->t))
ir->r = RID_INIT; /* No inheritance for modified BASE register. */
if (irp->r == r) {
rset_clear(allow, r); /* Mark same BASE register as coalesced. */
return r; /* Same BASE register already coalesced. */
} else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) {
rset_clear(allow, irp->r);
emit_move(as, r, irp->r); /* Move from coalesced parent reg. */
return irp->r;
} else {
emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
}
}
return allow;
return RID_NONE;
}
/* -- Tail of trace ------------------------------------------------------- */

View File

@ -1915,7 +1915,7 @@ static void asm_head_root_base(ASMState *as)
}
/* Coalesce BASE register for a side trace. */
static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
static Reg asm_head_side_base(ASMState *as, IRIns *irp)
{
IRIns *ir = IR(REF_BASE);
Reg r = ir->r;
@ -1924,15 +1924,15 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
if (rset_test(as->modset, r) || irt_ismarked(ir->t))
ir->r = RID_INIT; /* No inheritance for modified BASE register. */
if (irp->r == r) {
rset_clear(allow, r); /* Mark same BASE register as coalesced. */
return r; /* Same BASE register already coalesced. */
} else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) {
rset_clear(allow, irp->r);
emit_mr(as, r, irp->r); /* Move from coalesced parent reg. */
return irp->r;
} else {
emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
}
}
return allow;
return RID_NONE;
}
/* -- Tail of trace ------------------------------------------------------- */

View File

@ -2502,7 +2502,7 @@ static void asm_head_root_base(ASMState *as)
}
/* Coalesce or reload BASE register for a side trace. */
static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
static Reg asm_head_side_base(ASMState *as, IRIns *irp)
{
IRIns *ir = IR(REF_BASE);
Reg r = ir->r;
@ -2511,15 +2511,15 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
if (rset_test(as->modset, r) || irt_ismarked(ir->t))
ir->r = RID_INIT; /* No inheritance for modified BASE register. */
if (irp->r == r) {
rset_clear(allow, r); /* Mark same BASE register as coalesced. */
return r; /* Same BASE register already coalesced. */
} else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) {
rset_clear(allow, irp->r);
emit_rr(as, XO_MOV, r, irp->r); /* Move from coalesced parent reg. */
return irp->r;
} else {
emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
}
}
return allow;
return RID_NONE;
}
/* -- Tail of trace ------------------------------------------------------- */