kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit cec5aeab9c5d70fee51c0e90ae8cf9f673fade85
parent 04a7d100199049a9550ce78eaee8a5835c571c64
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Mon, 18 May 2026 21:19:28 -0700

Fix x64 atomic compare-exchange register pressure

Diffstat:
Msrc/api/cg.c | 36+++++++++++++++++++++++++++++++++---
1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/src/api/cg.c b/src/api/cg.c @@ -4421,6 +4421,33 @@ void cfree_cg_atomic_rmw(CfreeCg *g, CfreeCgMemAccess access, api_push(g, api_make_sv(dst, val_ty)); } +static int api_take_dead_owned_reg(ApiSValue *sv, u8 cls, Reg avoid, Reg *out) { + Reg r; + if (sv->res != RES_REG || sv->pinned) + return 0; + if (api_class_of_sv(sv) != cls) + return 0; + r = api_reg_of_sv(sv); + if (r == (Reg)REG_NONE || r == avoid) + return 0; + sv->res = RES_INHERENT; + *out = r; + return 1; +} + +static Reg api_alloc_dead_input_or_spill(CfreeCg *g, ApiSValue *a, + ApiSValue *b, ApiSValue *c, u8 cls, + CfreeCgTypeId ty, Reg avoid) { + Reg r; + if (api_take_dead_owned_reg(a, cls, avoid, &r)) + return r; + if (api_take_dead_owned_reg(b, cls, avoid, &r)) + return r; + if (api_take_dead_owned_reg(c, cls, avoid, &r)) + return r; + return api_alloc_reg_or_spill(g, cls, ty); +} + void cfree_cg_atomic_cmpxchg(CfreeCg *g, CfreeCgMemAccess access, CfreeCgMemOrder success, CfreeCgMemOrder failure, int weak) { @@ -4444,7 +4471,6 @@ void cfree_cg_atomic_cmpxchg(CfreeCg *g, CfreeCgMemAccess access, api_sv_type(&expected)); api_validate_memory_value(g, "atomic_cmpxchg desired", val_ty, api_sv_type(&desired)); - bool_ty = builtin_id(CFREE_CG_BUILTIN_BOOL); addr = api_force_reg(g, &ptr, pty); exp_op = api_sv_op_is_reg_or_imm(&expected) ? expected.op @@ -4452,8 +4478,12 @@ void cfree_cg_atomic_cmpxchg(CfreeCg *g, CfreeCgMemAccess access, des_op = api_sv_op_is_reg_or_imm(&desired) ? desired.op : api_force_reg(g, &desired, val_ty); - pr = api_alloc_reg_or_spill(g, api_type_class(val_ty), val_ty); - kr = api_alloc_reg_or_spill(g, RC_INT, bool_ty); + bool_ty = builtin_id(CFREE_CG_BUILTIN_BOOL); + pr = api_alloc_dead_input_or_spill(g, &ptr, &expected, &desired, + api_type_class(val_ty), val_ty, + (Reg)REG_NONE); + kr = api_alloc_dead_input_or_spill(g, &ptr, &expected, &desired, RC_INT, + bool_ty, pr); prior = api_op_reg(pr, val_ty); ok = api_op_reg(kr, bool_ty); g->target->atomic_cas(g->target, prior, ok, addr, exp_op, des_op,