mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 13:33:34 -04:00
docs(phase-30 S6): cookbook §146 — re-measure a wall before respecting it; both giants fell to stored drafts
This commit is contained in:
+17
-6
@@ -2,7 +2,7 @@
|
||||
|
||||
> **Generated by `tools/cookbook_index.py` — do not hand-edit** (R33). Regenerate after adding a cookbook section.
|
||||
>
|
||||
> `docs/matching-cookbook.md` is ~716 KB / 407 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses.
|
||||
> `docs/matching-cookbook.md` is ~716 KB / 412 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses.
|
||||
|
||||
**How to use:** name what you SEE in the diff (a stolen delay slot, an extra `la`, a swapped register pair, a `conflicting types` error), find that symptom below, read those sections first. If nothing fits, THEN grind — and add a section when you win.
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
- **§70** — The giv-init base register: walk the PARAMETER, not a copy of it (Phase 29 SESSION-18, `func_801777BC`) <sub>L5612</sub>
|
||||
- **§145** — Three loop/combine levers from the S40 wave-2 drafters (16/16 match_one) <sub>L9917</sub>
|
||||
|
||||
### structs, block moves & memcpy (29)
|
||||
### structs, block moves & memcpy (30)
|
||||
|
||||
- **§3-T2** — Source statement order drives instruction scheduling <sub>L78</sub>
|
||||
- **§5** — Known hard-residual classes (instruction-identical, one byte-exact blocker) <sub>L199</sub>
|
||||
@@ -141,8 +141,9 @@
|
||||
- **§129** — Post-carve, `rtu_match`/`match_one` COUNT THE JUMP TABLE AS INSTRUCTIONS; and a carve must never be committed without its owner (P30 S28, `func_8013BD74`) <sub>L8430</sub>
|
||||
- **§129a** — the target instruction count is INFLATED after a carve <sub>L8434</sub>
|
||||
- **§3-The** — DEFINITION-side alias is the only escape when the fleet canon disagrees on a promoting param <sub>L9463</sub>
|
||||
- **§3-Two** — errors of mine, both instructive <sub>L9999</sub>
|
||||
|
||||
### types, signedness & load/store width (30)
|
||||
### types, signedness & load/store width (31)
|
||||
|
||||
- **§3-I1** — Unsigned range check: `(x - lo) < (hi-lo)` → `addiu`+`sltiu` <sub>L41</sub>
|
||||
- **§3-I2** — Byte mask forces `andi` even after `lbu` <sub>L47</sub>
|
||||
@@ -174,6 +175,7 @@
|
||||
- **§3-Do** — NOT "strip the duplicate typedef" — it breaks the extern that uses it <sub>L8030</sub>
|
||||
- **§3-The** — type-form rules <sub>L8872</sub>
|
||||
- **§143** — `cast_call_sites` read a RETURN STATEMENT as a prototype and deleted it. A 0/39 sweep became 18/39. (P30 S40) <sub>L9824</sub>
|
||||
- **Then** — propagation returned 0/137 TWICE — both times a missing TYPE <sub>L9990</sub>
|
||||
|
||||
### declarations, prototypes & K&R (54)
|
||||
|
||||
@@ -276,7 +278,7 @@
|
||||
- **§127a** — §71 (sibling-first) is the strongest `-O0` lever, and it beats the index <sub>L8370</sub>
|
||||
- **§132** — The `JR-PAIR-IN-ONE-O0-OBJECT` "wall" was TWO instrument defects: a merged-double span the carve could not see, and a truncated object no rule deleted (P30 S29, `func_8013B83C` + `func_8013BD74`) <sub>L8563</sub>
|
||||
|
||||
### family propagation & sweeps (70)
|
||||
### family propagation & sweeps (71)
|
||||
|
||||
- **§8d** — Templating a body INTO a TU must not CHANGE its declaration environment — demote the carried data externs (Phase 26 session 8, byte-proven on `func_8015AE2C` ×133) <sub>L483</sub>
|
||||
- **§11** — Cross-binary dedup & code-sharing (Phase 11 — "one match unlocks many") <sub>L908</sub>
|
||||
@@ -348,6 +350,7 @@
|
||||
- **§138** — The propagation lanes: a gate refusal is a DECLARATION, and which lever you owe depends on blast radius <sub>L9405</sub>
|
||||
- **§142** — An open stub whose `h_exact` class is MATCHED elsewhere is FREE. Propagate the body; do not gate a draft. (P30 S39, +7,710 ins in two commands) <sub>L9768</sub>
|
||||
- **§143** — `cast_call_sites` read a RETURN STATEMENT as a prototype and deleted it. A 0/39 sweep became 18/39. (P30 S40) <sub>L9824</sub>
|
||||
- **Then** — propagation returned 0/137 TWICE — both times a missing TYPE <sub>L9990</sub>
|
||||
|
||||
### integration / TU plumbing (36)
|
||||
|
||||
@@ -490,7 +493,7 @@
|
||||
- **§142** — An open stub whose `h_exact` class is MATCHED elsewhere is FREE. Propagate the body; do not gate a draft. (P30 S39, +7,710 ins in two commands) <sub>L9768</sub>
|
||||
- **§3-The** — measurement (do this before any wave; it is ~20 lines and needs no builds) <sub>L9780</sub>
|
||||
|
||||
### process, measurement & doctrine (56)
|
||||
### process, measurement & doctrine (57)
|
||||
|
||||
- **§8e** — The jtbl ALIGNMENT LAW + the pad-spec filter — multi-table .rodata spans (Phase 29, byte-proven; `.run/probe_jtbl/verdict.md`) <sub>L530</sub>
|
||||
- **§3-The** — mechanism: game-code dedup is SOURCE-LEVEL, not an object swap (R-D1, the key lesson) <sub>L926</sub>
|
||||
@@ -548,8 +551,9 @@
|
||||
- **§140** — A METRIC IS NOT A MEASUREMENT UNTIL IT IS REPRODUCIBLE FROM THE COMMITTED TREE (P30 S1e: a phantom regression that gated the session's best lever) <sub>L9650</sub>
|
||||
- **§3-The** — measurement (do this before any wave; it is ~20 lines and needs no builds) <sub>L9780</sub>
|
||||
- **§3-And** — the report-vs-bytes lesson attached to it <sub>L9812</sub>
|
||||
- **§146** — RE-MEASURE A WALL BEFORE YOU RESPECT IT. Both "permanent" giants fell to drafts already on disk. (P30 S6, +50,094 ins) <sub>L9967</sub>
|
||||
|
||||
### (unbucketed — title matched no symptom vocabulary) (118)
|
||||
### (unbucketed — title matched no symptom vocabulary) (120)
|
||||
|
||||
- **§3-How** — to use this <sub>L30</sub>
|
||||
- **§1** — Idiom catalog (asm pattern → C that produces it) <sub>L39</sub>
|
||||
@@ -669,6 +673,8 @@
|
||||
- **§3-The** — trap that hid it — SAME FUNCTION, TWO ROUTES, ONLY ONE IS FREE <sub>L9795</sub>
|
||||
- **Route** — selection (why `--addr` sometimes says "nothing changed") <sub>L9804</sub>
|
||||
- **§144** — THE LITERAL'S SPELLING PICKS THE IMMEDIATE ENCODING (P30 S40 wave 1, `func_801822E0`) <sub>L9878</sub>
|
||||
- **§3-Why** — a correct draft can read as an intrinsic wall <sub>L9978</sub>
|
||||
- **§3-The** — rule <sub>L10013</sub>
|
||||
|
||||
|
||||
## All sections, in order
|
||||
@@ -1080,3 +1086,8 @@
|
||||
- **§143** — `cast_call_sites` read a RETURN STATEMENT as a prototype and deleted it. A 0/39 sweep became 18/39. (P30 S40) <sub>L9824</sub>
|
||||
- **§144** — THE LITERAL'S SPELLING PICKS THE IMMEDIATE ENCODING (P30 S40 wave 1, `func_801822E0`) <sub>L9878</sub>
|
||||
- **§145** — Three loop/combine levers from the S40 wave-2 drafters (16/16 match_one) <sub>L9917</sub>
|
||||
- **§146** — RE-MEASURE A WALL BEFORE YOU RESPECT IT. Both "permanent" giants fell to drafts already on disk. (P30 S6, +50,094 ins) <sub>L9967</sub>
|
||||
- **§3-Why** — a correct draft can read as an intrinsic wall <sub>L9978</sub>
|
||||
- **Then** — propagation returned 0/137 TWICE — both times a missing TYPE <sub>L9990</sub>
|
||||
- **§3-Two** — errors of mine, both instructive <sub>L9999</sub>
|
||||
- **§3-The** — rule <sub>L10013</sub>
|
||||
|
||||
@@ -9961,3 +9961,62 @@ IVs. Same family of decisions: *how many named pointers exist in the C* is a cod
|
||||
|
||||
**Symptom lines for the index:** **"one extra induction register"** · **"a pointer bump addiu
|
||||
disappeared"** · **"stores are in the wrong order"** · **"one instruction too many in a loop"**.
|
||||
|
||||
---
|
||||
|
||||
## §146 — RE-MEASURE A WALL BEFORE YOU RESPECT IT. Both "permanent" giants fell to drafts already on disk. (P30 S6, +50,094 ins)
|
||||
|
||||
The roadmap carried two functions as **permanent walls** since Phase 24. Between them they were
|
||||
50,094 instructions — the largest single item on the board — and they had deterred a Fable5-scale
|
||||
attempt. Both were matched **from stored drafts, in minutes.**
|
||||
|
||||
| wall | recorded verdict | what it actually took |
|
||||
|---|---|---|
|
||||
| `func_80178004` (165×138) | Phase 26: Fable5, **~477k tokens**, "intrinsic 3-integer regalloc wall" | a stored draft, gated as-is |
|
||||
| `func_801412A8` (198×138) | close=29/110 since Phase 24 | 1 of **31** stored drafts + the §37/§124 alias |
|
||||
|
||||
### Why a correct draft can read as an intrinsic wall
|
||||
|
||||
`func_801412A8`'s TU declares `extern int func_801412A8(int,int,int,int,int,int)` and its callers
|
||||
**use the return value**, while the byte-true definition is
|
||||
`Prim_1412A8 *(Prim_1412A8 *, int, int, int, u16, u16)`. Narrow params cannot agree with an `int`
|
||||
prototype, and the `()` no-prototype escape is illegal precisely when a param promotes — so neither
|
||||
side can move. **The resulting byte difference is in the CALLERS, and `match_one` only ever compiles
|
||||
the target function.** The measuring instrument was structurally blind to where the difference lived,
|
||||
so the residual was attributed to codegen. The §37/§124 def-side alias decouples them: the TU's
|
||||
declaration keeps governing the call sites (their codegen untouched), the definition keeps its
|
||||
byte-true signature.
|
||||
|
||||
### Then propagation returned 0/137 TWICE — both times a missing TYPE
|
||||
|
||||
`family_remap._carry_macros` carries file-scope `#define`s, but **(a) it does not carry typedefs at
|
||||
all, and (b) it is not transitive** — it brought `addPrim_1412A8` and stopped, though that macro
|
||||
calls `setaddr`/`getaddr`, and `getaddr` casts to `PTag_1412A8`. Lifting
|
||||
`Env_1412A8 / PTag_1412A8 / Prim_1412A8` + `OT/getaddr/setaddr` into `engine_types.h` took it to
|
||||
**137/137**. A total-zero sweep on a PURE family with a *matched* exemplar is a tooling signal, not a
|
||||
codegen one (§53) — here it fired twice in a row for two different missing symbols.
|
||||
|
||||
### Two errors of mine, both instructive
|
||||
|
||||
**Lift without strip.** I added the typedefs to `engine_types.h` and left the originals in
|
||||
`ov_SC01_077.c`. gcc-2.7.2 rejects a repeated typedef even when identical — the lesson already
|
||||
recorded at the foot of `engine_types.h` — so R22 came back **139/140, `[FAIL] ov_SC01_077`**, the
|
||||
exemplar's own overlay. **A proper lift strips the source; `build_engine_types --strip` does both.**
|
||||
The clean-fleet gate caught it before commit, which is exactly why fleet-shared edits are R22-gated.
|
||||
|
||||
**Sampling instead of scanning.** My first pass over the stored drafts used `head -8` of 31 and
|
||||
reported "best closeness 40" — the MATCH was in the 9th. And I checked whether a draft defined
|
||||
`Prim_1412A8` with a plain `grep -c`, which matches inside `addPrim_1412A8`, and briefly concluded
|
||||
the carry worked. Same shape as reading a `return` as a declaration (§143): a pattern that is a
|
||||
substring of the thing you are actually asking about.
|
||||
|
||||
### The rule
|
||||
|
||||
**A wall verdict is only as current as the instrument that produced it.** Before spending
|
||||
frontier-model tokens on a documented wall: re-run every stored draft through `match_one` (ALL of
|
||||
them, not a sample), and check whether the tools that produced the verdict have changed since. Here
|
||||
that cost four minutes and was worth 50,094 instructions. The corollary for the ledger: when a tool
|
||||
is repaired, the verdicts it produced become **hypotheses again**, not facts.
|
||||
|
||||
**Symptom lines for the index:** **"a documented wall"** · **"an old close= verdict"** ·
|
||||
**"match_one MATCH but the whole binary differs"** · **"a sweep returns 0 of N twice"**.
|
||||
|
||||
Reference in New Issue
Block a user