Files
BFM-decomp/docs
Drew T 7b970653ff docs(phase-26): cookbook §46 — func_80178D40 MATCH (890 ins ×134): four loop-structure levers
The heaviest core in the game (890 ins, reach 134 = 477 KB) closed from close=39 to MATCH 890/890,
PIN-FREE, by cheap-Opus reading loop.c/jump.c/cse.c. All 39 residuals were in ONE case body and every
one was STRUCTURAL — the permuter could not have reached any of them. Four new general levers:

- L1 PEEL: a loop's `break` must not land on the loop's own fall-through label — that leaves
  NOTE_INSN_LOOP_BEG + an unconditional jump, firing duplicate_loop_exit_test (jump.c:2131), which
  rotates the loop and peels iteration 1 (const-folding `i++` and dragging an extra address
  re-materialization block). Write `goto <label>;` — same destination, different construct.
- L2 SURVIVING COPY: a source-level `fp = q;` ALWAYS dies (cse canon_reg + qty_first_reg, then flow).
  To make it survive, split def and uses across extended basic blocks — cse resets its hash table at a
  label with >1 predecessor. Test the memory, assign inside the guard branch.
- L3 MERGED STORE: write the store INSIDE the branch that reaches the shared tail, so jump2 tail-merges
  it and reorg steals the `li` into the delay slot. An unconditional store before the `if` blocks it.
- L4 UN-COALESCED LOOP COPY = a non-replaceable giv, needing all three of: an index giv `&A[i]`; a use
  OUTSIDE the loop (record_giv, loop.c:4437 -> emit_insn_after at loop.c:3945); and the biv increment
  LAST, so the reduced giv's addiu lands in the loop-back delay slot (i++ at the top costs +1 insn).
- L5 KEEP TAILS APART: two structurally identical loops must differ in a REGISTER or cross_jump merges
  their tails — give each its own pointer pseudo. (§8's cross-jump lever, inverted.)

Confirms the tier doctrine: cheap-Opus applying the documented §31 map cracked the game's heaviest core;
Fable5 was not needed. R17 held — "wrong BYTES" -> read the real gcc-2.7.2 passes.
2026-07-13 21:16:36 -06:00
..