kit

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

commit fc5dd99294051d4ccc87d9e0e0b43fbf33ab5f6f
parent fd17c4663d0fc98b08b76ea62c6810e5e8470cb6
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Fri, 12 Jun 2026 15:02:27 -0700

build(perf): add perf-golden/perf-gate A/B harness + fix support/rt pattern rule

`make perf-golden` snapshots the current RELEASE build as a self-contained
golden at build/release/golden/kit (with its own support/rt symlink beside
it).  `make perf-gate` then drives the identity gate against the candidate
at build/release/kit.

The key enabler is changing the Makefile's support/rt recipe from a
specific-path target to a `%/support/rt` pattern rule: any directory that
ends in /support/rt — including the golden snapshot dir — gets the symlink
automatically, so both the golden and the candidate resolve their runtime
from any cwd without needing to live in the checkout's build dir.  The old
"support dir not found" failure when measuring from tmp/projects/sqlite-amalg
is gone.

doc/plan/PERF.md gains a concise A/B workflow block under the Gate section.

Diffstat:
MMakefile | 10++++++++--
Mdoc/plan/PERF.md | 7+++++++
Mmk/maint.mk | 21++++++++++++++++++++-
3 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile @@ -39,8 +39,14 @@ lib: $(LIB_AR) bin: $(BIN) $(BUILD_DIR)/support/rt -$(BUILD_DIR)/support/rt: - @mkdir -p $(dir $@) +# A kit binary resolves its runtime support from <bindir>/support/rt (an +# `rt` symlink in a `support` dir beside the executable). This pattern rule +# installs that symlink for ANY directory ending in /support/rt, so an +# alternative build dir — or a snapshot binary copied next to its own +# support/ (see `perf-golden` in mk/maint.mk) — is self-contained and finds +# its runtime from any cwd, no in-checkout requirement. +%/support/rt: + @mkdir -p $(@D) ln -sfn $(abspath rt) $@ # Rebuild the archive from scratch (rm first): `ar rcs` only adds/updates, so diff --git a/doc/plan/PERF.md b/doc/plan/PERF.md @@ -261,6 +261,13 @@ all of them; that guarantee is the floor this benchmark defends. For lexer changes the diff must include a line-splice battery (mid-token / mid-string / leading / trailing / consecutive continuations) plus a diagnostic whose line number falls across a splice. + - **A/B flow:** `make perf-golden` (snapshot the pre-change RELEASE build as a + self-contained golden at `build/release/golden/kit`) → edit → `make bin + RELEASE=1` (the candidate at `build/release/kit`) → `make perf-gate` (runs + the gate golden-vs-candidate). The golden carries its own `support/rt` + sibling (via the `%/support/rt` Makefile pattern rule), so both binaries + resolve their runtime from any cwd — no copy into the checkout needed, and + no "support dir not found" when measuring from `tmp/projects/sqlite-amalg`. ## Dead ends (measured — don't retry) diff --git a/mk/maint.mk b/mk/maint.mk @@ -3,7 +3,7 @@ # Developer maintenance targets: source formatting, the clangd compilation # database, optimizer benchmarking, and clean. -.PHONY: format compile-commands bench-opt bench-cc code-size clean +.PHONY: format compile-commands bench-opt bench-cc perf-golden perf-gate code-size clean # Format only the .c/.h files changed in the working tree (staged, unstaged, or # new/untracked), restricted to the formatted roots and excluding test/pp. When @@ -40,6 +40,25 @@ bench-cc: $(MAKE) RELEASE=1 PROFILE=1 CC=clang BUILD_DIR=build/bench bin @KIT='$(abspath build/bench/kit)' bash scripts/cc_bench.sh +# Perf A/B harness. `perf-golden` builds the current source as RELEASE and +# snapshots it as a SELF-CONTAINED golden under build/release/golden/: the +# copied binary sits next to its own support/rt symlink (the `%/support/rt` +# pattern rule in Makefile), so it resolves its runtime from any cwd without +# living in the checkout's build dir — the old "support dir not found" gotcha +# when a golden was copied to /tmp. Workflow (see doc/plan/PERF.md): +# make perf-golden # snapshot the pre-change build as golden +# <edit>; make bin RELEASE=1 # rebuild build/release/kit as the candidate +# make perf-gate # byte-identity gate: golden vs candidate +PERF_GOLDEN_DIR = build/release/golden +perf-golden: $(PERF_GOLDEN_DIR)/support/rt + $(MAKE) RELEASE=1 bin + cp build/release/kit $(PERF_GOLDEN_DIR)/kit + @echo "perf golden snapshot: $(PERF_GOLDEN_DIR)/kit (self-contained; runs from any cwd)" + +perf-gate: + @GOLDEN='$(abspath $(PERF_GOLDEN_DIR)/kit)' CAND='$(abspath build/release/kit)' \ + bash scripts/perf_identity_gate.sh + # Regenerate doc/CODE_SIZE.md: per-component cloc line counts plus a binary # code-size section attributed from the release linker map. Requires cloc. # The map step relinks the release objects explicitly (not via libkit.a) so the