kit

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

commit b8de5c0b45f3724531f7f6a797f82cb719da4e87
parent 6f48bfde8f810cd7e705dc9c31f7391da7607acc
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue,  2 Jun 2026 04:09:15 -0700

cg: re-enable SV_ARITH delayed-arith -O0 peephole (Track 6.3)

Diffstat:
Mdoc/CODEGEN.md | 12++++++++----
Msrc/cg/fold.c | 17++++++++---------
Msrc/cg/fold.h | 10+++++-----
3 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/doc/CODEGEN.md b/doc/CODEGEN.md @@ -90,10 +90,14 @@ one of an operand (immediate / constant / semantic local / lvalue address), a branch can fuse a compare instead of materializing a 0/1, or so a small immediate can flow straight into a `binop`. These delayed forms and the constant folding around them are the `-O0` peephole; it lives in `fold.c` -(contract in `fold.h`), kept isolated from the stack discipline. The delayed -*compare* is live; the delayed *arith* machinery is present but currently gated -off (`api_can_delay_int_arith` returns 0) pending the place/value rework that -removes the load/store addressing rider which forced it off. The stack does +(contract in `fold.h`), kept isolated from the stack discipline. Both delayed +forms are live: the delayed *compare* fuses into a following branch, and the +delayed *arith* (admitted by `api_can_delay_int_arith` for an unflagged foldable +integer op) flows an unmaterialized binop/unop into a following op so an +immediate chain folds or an identity collapses, materializing only when a +consumer needs a value. (The delayed *arith* was gated off while the load/store +addressing rider existed; the strict place/value rework removed the rider and +re-enabled it.) The stack does **not** own registers, frame slots, spill policy, or caller-saved preservation; those moved down into the target realizations. When an operation needs a value emitted, the stack calls the corresponding `g->target->op(...)` semantic hook diff --git a/src/cg/fold.c b/src/cg/fold.c @@ -285,11 +285,12 @@ void api_materialize_cmp_to(CfreeCg* g, ApiSValue* sv, Operand dst) { /* ============================================================ * 2b. Delayed arith (SV_ARITH) lifecycle * - * Currently gated off: api_can_delay_int_arith returns 0, so nothing builds an - * SV_ARITH today. The machinery is kept here (rather than deleted) because - * Track 6.3 re-enables it once Track 7 removes the load/store EA rider that - * forced it off. Re-enabling is then a gate flip in api_can_delay_int_arith, - * not a code move. + * Live: api_can_delay_int_arith admits a non-flagged foldable integer op, so an + * unflagged int binop/unop is held un-emitted as an SV_ARITH. A following op can + * then fuse it (fold an imm chain, collapse an identity) and a consumer that + * needs a value materializes it via api_materialize_arith_to. This was gated off + * while the load/store EA rider existed (Track 7 removed it); Track 6.3 flipped + * the gate back on. * ============================================================ */ ApiSValue api_make_arith_unop(UnOp op, Operand a, CfreeCgTypeId ty, @@ -383,10 +384,8 @@ int api_arith_rhs_reusable(const ApiSValue* sv) { } int api_can_delay_int_arith(CfreeCg* g, CfreeCgTypeId ty, u32 flags) { - (void)g; - (void)ty; - (void)flags; - return 0; + u32 width; + return g && !flags && api_foldable_int_type(g->c, ty, &width); } int api_op_is_int_identity(CfreeCg* g, BinOp op, CfreeCgTypeId ty, i64 imm) { diff --git a/src/cg/fold.h b/src/cg/fold.h @@ -26,10 +26,10 @@ * consumer is api_branch_if (control.c); api_ensure_local * materializes it to a 0/1 when used as a value. LIVE. * - SV_ARITH — a small immediate/local arith held so it can flow into a - * following binop or collapse via identities. Currently - * gated off (api_can_delay_int_arith returns 0); re-enabled - * by Track 6.3 once Track 7 removes the EA rider. The code - * lives here so 6.3 is a gate flip, not a move. + * following binop or collapse via identities. LIVE: admitted + * by api_can_delay_int_arith for an unflagged foldable int + * op. It was gated off while the load/store EA rider existed; + * Track 7 removed the rider and Track 6.3 re-enabled it. * Each delayed form has make / release / materialize-to-dst entry points, * plus the fold-chain and identity-collapse helpers for SV_ARITH. * @@ -66,7 +66,7 @@ void api_release_cmp(CfreeCg* g, ApiSValue* sv); void api_materialize_cmp_to(CfreeCg* g, ApiSValue* sv, Operand dst); CmpOp api_invert_cmp(CmpOp op); -/* ---- 2b. delayed arith (SV_ARITH) lifecycle — gated off pending 6.3 ---- */ +/* ---- 2b. delayed arith (SV_ARITH) lifecycle — live (Track 6.3) ---- */ ApiSValue api_make_arith_unop(UnOp op, Operand a, CfreeCgTypeId ty, int a_owned); ApiSValue api_make_arith_binop(BinOp op, Operand a, Operand b, CfreeCgTypeId ty,