kit

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

commit ba542bfde60e045ffc887bfdcb11f8006a406eef
parent 21fc76d188106a6891e6a316b6daffbba380f03f
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Sat, 13 Jun 2026 17:47:50 -0700

perf(cg): -O0 fp args into xmm0..3 (Lever 1, x64)

Front the fp ARG/RET registers xmm0..xmm3 at the head of x64_fp_allocable[]
so the -O0 NDT value-cache pool (scanned in order by nd_cache_alloc) makes
fp-arg producers materialize directly into the ABI arg registers, removing
the post-materialize shuffle into the call slots. xmm0/xmm1 are also the fp
ret regs but ndt_result_reg_stable is OFF for x64, so the fp result still
moves out of xmm0 via the post-call path (often a no-op). The INT pool is
unchanged (RAX/RDX div-mul, RCX shift-count, R8/R9 driver scratch stay out);
xmm4/xmm5 (driver scratch) and xmm14/xmm15 (emit scratch) stay out of the pool.

Gate (codesize track: run-correctness + determinism, not byte-identity):
- make bin RELEASE=1: clean, no warnings (-Werror).
- make test-smoke-x64: 3 pass, 0 fail.
- make test-toy: 1392 pass, 0 fail, 35 skip (pre-existing structural skips).
- Functional x86_64-macos run (fp(d,d,i,d,i), mixed int/fp args, fp-result-
  as-next-arg, shared fp temp, nested fp calls): output byte-identical to
  clang -target x86_64-apple-macos.
- Determinism: two compiles of the same .c are byte-identical objects.

Measured on a fp/call-heavy source (x86_64-macos -O0):
  total insns 220 -> 202 (-8.2%), movsd 128 -> 110 (-14.1%),
  .text 390 -> 336 B (-13.8%), object 1459 -> 1371 B (-6.0%).
The entire delta is movsd elimination; all other mnemonics unchanged.

Diffstat:
Msrc/arch/x64/native.c | 11++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/arch/x64/native.c b/src/arch/x64/native.c @@ -294,10 +294,15 @@ static const NativePhysRegInfo x64_int_phys[] = { .spill_cost = 0u, \ .copy_cost = 0u} -/* Allocable FP pool: xmm6..xmm11 (keep arg/ret xmm0..5 clear). xmm4/xmm5 are - * driver scratch; xmm14/xmm15 are emit scratch. */ +/* Allocable FP pool: arg/ret xmm0..xmm3 lead so -O0 fp-arg producers + * materialize directly into the ABI arg registers (Lever 1), then xmm6..xmm11. + * xmm0/xmm1 are also the fp ret regs but ndt_result_reg_stable is OFF, so the + * fp result still moves out of xmm0 via the post-call path (often a no-op). + * xmm4/xmm5 stay driver scratch; xmm14/xmm15 are emit scratch. */ static const Reg x64_fp_allocable[] = { - X64_XMM6, X64_XMM7, X64_XMM8, X64_XMM0 + 9, X64_XMM0 + 10, X64_XMM0 + 11}; + X64_XMM0, X64_XMM1, X64_XMM2, X64_XMM3, + X64_XMM6, X64_XMM7, X64_XMM8, X64_XMM0 + 9, + X64_XMM0 + 10, X64_XMM0 + 11}; static const Reg x64_fp_scratch[] = {X64_XMM4, X64_XMM5}; static const NativePhysRegInfo x64_fp_phys[] = {