commit bee661f4e7b2b2b9fb0da3c8947dea48402a8e39
parent 0b33acede42ae594f52d5ee544446332bc8aa772
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Sat, 13 Jun 2026 09:52:05 -0700
doc(perf): PERF-IDEAL.md measured WAVE 1-2 results — -11.88% Ir (3.08x->2.71x tcc)
Diffstat:
1 file changed, 41 insertions(+), 0 deletions(-)
diff --git a/doc/plan/PERF-IDEAL.md b/doc/plan/PERF-IDEAL.md
@@ -394,6 +394,47 @@ constant factors. Those are the rewrites-to-the-ideal; WAVE 2–3 compound. Re-p
after each landing — the frontier moves, and several WAVE-2 items shrink once their
WAVE-1 neighbor lands.
+## Measured results — WAVE 1–2 landing (2026-06-13, 9 commits `325a68b5`..`bcdbeba3`)
+
+All of WAVE 1 plus most of WAVE 2 landed as 9 byte-identical commits (5 parallel
+in-tree agents on disjoint file sets). **Cumulative, Linux callgrind, sqlite3.c
+`-c`:**
+
+| | Ir | vs tcc (0.663 B) |
+|---|--:|--:|
+| baseline (`de8c3b62`) | 2,038,845,542 | 3.08× |
+| **after WAVE 1–2 (`bcdbeba3`)** | **1,796,553,239** | **2.71×** |
+| **delta** | **−242,292,303 (−11.88%)** | |
+
+Gate: the full 60-category byte-identity gate PASSes and the sqlite `-O0` object is
+bit-for-bit identical to golden (2,216,680 B) — i.e. **−11.88% instructions for
+zero output change**. Green: toy / parse / pp / cg-api / opt / smoke-x64 /
+smoke-rv64.
+
+**Per-change, measured vs. estimated** (estimates ran high, as the docs warned —
+trust measured):
+
+| change | est. | measured (self-Ir move) |
+|---|--:|---|
+| §A.1 memchr splice sweep | 215M→20–40M | `lex_open_mem` **215.0M → 78.9M** (−136M; residual is the per-open `memset`) |
+| §D.1 memoize `c_abi_record_layout` | −40…80M | `kit_cg_type_record_field` **48.0M → out of top**, `kit_cg_type_size` 35.7M→13.2M |
+| §B.1 intern cache | −30…45M | `pool_intern_slice` **84.7M → 71.6M** (−13M; under estimate) |
+| §E.1 typed-store byte sink | −5…6M | `mc_emit_bytes` **16.3M → below threshold** |
+| §C.3a newline drop | −5…12M | old relay → `pp_pull_into` (consolidated) |
+| §D.2/§D.3a descriptor + hoist | −15…30M | predicates collapsed into `api_type_pred` |
+| §A.2 / §E.2 | −20…30M / −4…6M | folded into the cumulative total |
+
+**The re-profile surfaced the next frontier** (re-rank after every wave — the
+discipline holds):
+- `api_type_pred` is a **new 66.8M hub** — §D.2 made predicates O(1) but the
+ per-call `id → entry` segvec decode is now the cost → **§D.3b** (carry `CgId` on
+ the value stack) or inline `api_type_pred`.
+- `lex_open_mem` residual **78.9M is the per-open `memset`** → **§A.3** (hoist the
+ ~1184 B `punct_sym[]` to a per-compile table) now has clear payoff.
+- `pool_intern_slice` 71.6M — the cache took the hash side; the probe side remains.
+- `pp_pull_into` 73.8M — **§C.3b** (don't materialize non-directive newlines) is
+ the structural follow-up.
+
## Appendix — claims verified against source (not docs)
- §A scalar splice loop + no NEON: `lex.c:156-157`, disasm of the profiled binary. ✓