From e7e1ce9d30547d045c60bfa6bbacdf8f4b65df83 Mon Sep 17 00:00:00 2001 From: Christopher Williams Date: Thu, 24 Sep 2026 09:43:12 -0400 Subject: [PATCH] =?UTF-8?q?phase11:=20merge=2018=20+=20cookbook=2087-88=20?= =?UTF-8?q?=E2=80=94=20530=20bodies=20/=20539=20regions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Worker A's 0x8009C904: 548 bytes, matched on the FIRST spelling. Cumulative evidence for the redundancy ranker is now 548B/1st, 248B/3 spellings, 1232B/2, 700B/3 -- against 176B/9 failures for a tie-break-dense row. Cookbook 87 is the important negative: cc1 does NOT unroll a constant-trip-count loop (the for-loop form is 212 B against the original's 780 B), so whenever an original is unrolled the SOURCE is unrolled too. That explains why the >800 B band is full of cheap rows -- those bodies are unrolled in the source, and an unrolled repetitive body is exactly what the ranker scores highest. --- config/regions.tsv | 1 + docs/MATCHING_COOKBOOK.md | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/config/regions.tsv b/config/regions.tsv index e04062d..50ec66b 100644 --- a/config/regions.tsv +++ b/config/regions.tsv @@ -358,6 +358,7 @@ 0x80099E14 0x80099E34 src/func_80099E14.c 0x8009AC08 0x8009AC28 src/func_8009AC08.c 0x8009B464 0x8009B4A0 src/func_8009B464.c +0x8009C904 0x8009CB28 src/func_8009C904.c 0x8009D8A0 0x8009D8E0 src/func_8009D8A0.c 0x8009E8D0 0x8009E95C src/func_8009E8D0.c 0x8009F0E8 0x8009F120 src/func_8009F0E8.c diff --git a/docs/MATCHING_COOKBOOK.md b/docs/MATCHING_COOKBOOK.md index bd8c5bc..87e1d55 100644 --- a/docs/MATCHING_COOKBOOK.md +++ b/docs/MATCHING_COOKBOOK.md @@ -1387,3 +1387,28 @@ return block reached with a `j` (+8 bytes), whereas the original branches each g to the shared epilogue with `move v0,zero` in each delay slot. A named-result-local spelling gets to 92 bytes but puts the local in v1 instead of v0. Named untried lever: a `goto` to a shared return label (finding 43, trigger 3) to defeat the cross-jump. + +### 87. cc1 does NOT unroll a constant-trip-count loop (worker A) + +Worker A's `0x800BFF20` (780 B): the `for (i = 0; i < 6; i++)` form is **212 B** against the +original's 780 B. So **whenever an original is unrolled, the SOURCE is unrolled too** — do not +write a loop and hope cc1 unrolls it. This is the single most useful negative in the phase for +large bodies, because it explains at a stroke why the >800 B band is full of cheap rows: those +bodies are unrolled *in the source*, and an unrolled repetitive body is exactly what the +redundancy ranker scores highest. + +Same row, second negative: an explicit two-base spelling (`p = q + 12532` for the last 8 checks) +is 784 B — one instruction extra, same allocation mismatch. + +### 88. Redundancy-rank evidence, cumulative + +| row | size | rep-density | outcome | +|---|---|---|---| +| `0x8009C904` | **548 B** | 2.26 | **FIRST spelling → MATCH** | +| `0x8009F798` | 248 B | 2.10 | 3 spellings → MATCH | +| `0x8010AF50` | **1232 B** | repetitive | 2 spellings → MATCH (worker D) | +| `0x8006BC74` | 700 B | repetitive | 3 spellings → MATCH (worker D) | +| `0x80017C6C` | 176 B | tie-break-dense | **9 spellings, 42 bytes, classified** | + +Worker A, on adopting the ranker: *"I have not attempted a tie-break-dense row since adopting the +ranker and I do not intend to."* That is the correct use of the measurement.