mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-05 17:03:23 -04:00
phase-36: cookbook §456 — the S104 lever-removal move catalog (R16)
This commit is contained in:
+11
-4
@@ -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 / 1172 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 / 1174 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.
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
- **§396g** — ★★ — A GUARD LADDER'S RUNGS MUST STAY SYMMETRIC OR `reorg.c` LOSES ITS BRANCH REDIRECT (P31 S69; byte-proven ov_SC03_028/func_80184C90, 92 ins) <sub>L32822</sub>
|
||||
- **§428** — ★★★ — A ZERO-BYTE CROSS-JUMP BARRIER: ADVANCE THE POINTER INSIDE EACH SWITCH ARM (P31 S72; `main/func_80026D64`, 218 ins, MATCH in 2 compiles) <sub>L33958</sub>
|
||||
|
||||
### instruction scheduling (99)
|
||||
### instruction scheduling (100)
|
||||
|
||||
- **§3-T2** — Source statement order drives instruction scheduling <sub>L78</sub>
|
||||
- **§3** — When a diff is pure scheduling → decomp-permuter (harness built, Phase 6) <sub>L107</sub>
|
||||
@@ -204,8 +204,9 @@
|
||||
- **§475** — THE `"memory"` FENCE AS A *CSE INVALIDATOR*, AND `(b*3)<<3` INSTEAD OF `b*24` <sub>L35585</sub>
|
||||
- **§476** — 🔴 A HARD-REGISTER PIN DESTROYS TWO THINGS COMBINE AND SCHED1 NEED (`func_800226C0`, 670 ins → MATCH) <sub>L35616</sub>
|
||||
- **§482** — ★★★ — TWO INDEPENDENT RE-TIES, ORDERED: WHEN ONE BARRIER FIXES ONE RESIDUAL AND CREATES THE OTHER (P31 S77, `main:func_8006252C`, 30 ins → MATCH) <sub>L35936</sub>
|
||||
- **§456** — The lever-removal move catalog: what the S104 agents found under ~205 pins, barriers and launders (Phase 36 T7) <sub>L37759</sub>
|
||||
|
||||
### register allocation & pins (139)
|
||||
### register allocation & pins (140)
|
||||
|
||||
- **§10** — Closing the regalloc/scheduling hard tail by hand (LZSS, Phase 7 session F — the full close) <sub>L854</sub>
|
||||
- **Residual** — A — commutative `|`/`&`/`+` result lands in the wrong source-operand register <sub>L875</sub>
|
||||
@@ -346,6 +347,7 @@
|
||||
- **§478** — 🔴 — A VERBATIM DRAFT IS THE STRONGEST *FALSE* SIGNAL YOUR SCOPING TOOL CAN EMIT <sub>L35791</sub>
|
||||
- **§499** — ★★★ — A NEVER-ONBOARDED PAYLOAD PINS ITS OWN BASE STATICALLY, AND THE FIRST BUILD CANNOT (P32 T2a/T2b: the parked five onboarded, 213 → 218 binaries, 0 UNCLAIMED) <sub>L36752</sub>
|
||||
- **§501** — ★★★ — A LEVER THAT MEASURES WORSE MAY BE A CASCADE: READ THE `.loop` DUMP FOR THE DESIRABILITY FLIP BEFORE DISCARDING IT (P32 T4b, `main:func_800391D4`, a pinned wall banked by a Fable agent) <sub>L37151</sub>
|
||||
- **§456** — The lever-removal move catalog: what the S104 agents found under ~205 pins, barriers and launders (Phase 36 T7) <sub>L37759</sub>
|
||||
|
||||
### CSE / redundancy / rematerialization (50)
|
||||
|
||||
@@ -1095,7 +1097,7 @@
|
||||
- **§496** — ★★ — A CARRIED-TYPE TEST THAT ASSUMES THE OVERLAY INCLUDE SET SILENTLY DROPS A RESIDENT TYPEDEF (P32 T1a; byte-proven, resident `func_800D128C` isolation) <sub>L36665</sub>
|
||||
- **§453** — ★★★ — ONE SOURCE PER UNIQUE FUNCTION: THE INCLUDE-AT-SITE SHARE, ITS GATE, AND THE FOUR DEFECTS THAT SHAPED IT (P35 S94–S96) <sub>L37555</sub>
|
||||
|
||||
### build graph, splat & the harness (218)
|
||||
### build graph, splat & the harness (219)
|
||||
|
||||
- **§4** — Flag/toolchain gotchas <sub>L190</sub>
|
||||
- **Build** — mechanism — per-file opt override (splat resegmentation) <sub>L307</sub>
|
||||
@@ -1315,6 +1317,7 @@
|
||||
- **§499** — ★★★ — A NEVER-ONBOARDED PAYLOAD PINS ITS OWN BASE STATICALLY, AND THE FIRST BUILD CANNOT (P32 T2a/T2b: the parked five onboarded, 213 → 218 binaries, 0 UNCLAIMED) <sub>L36752</sub>
|
||||
- **§500** — ★★★ — THE T3 WAVE HARVEST (P32 T3, 2026-09-05): 31 one-agent-per-function drafters → 20 MATCH / 9 NEAR / 2 FAIL, every closer, two NEW named gcc mechanisms, and the wave-process defects <sub>L36793</sub>
|
||||
- **§453** — ★★★ — ONE SOURCE PER UNIQUE FUNCTION: THE INCLUDE-AT-SITE SHARE, ITS GATE, AND THE FOUR DEFECTS THAT SHAPED IT (P35 S94–S96) <sub>L37555</sub>
|
||||
- **§455** — Rung G, the guided search: score the object, classify the residual, compose the moves (Phase 36 S101) <sub>L37686</sub>
|
||||
|
||||
### process, measurement & doctrine (143)
|
||||
|
||||
@@ -2978,6 +2981,8 @@
|
||||
- **§453** — ★★★ — ONE SOURCE PER UNIQUE FUNCTION: THE INCLUDE-AT-SITE SHARE, ITS GATE, AND THE FOUR DEFECTS THAT SHAPED IT (P35 S94–S96) <sub>L37555</sub>
|
||||
- **§454** — Rung D and rung R: taking a lever off a body that still has to compile to the same bytes (Phase 36 T6) <sub>L37604</sub>
|
||||
- **§454a** — the recipe rung's real shape: replication, not discovery (S99, measured) <sub>L37671</sub>
|
||||
- **§455** — Rung G, the guided search: score the object, classify the residual, compose the moves (Phase 36 S101) <sub>L37686</sub>
|
||||
- **§456** — The lever-removal move catalog: what the S104 agents found under ~205 pins, barriers and launders (Phase 36 T7) <sub>L37759</sub>
|
||||
|
||||
|
||||
---
|
||||
@@ -4162,3 +4167,5 @@ Notes routinely quote that as a section id. This table resolves it. Grep bait: `
|
||||
| L37555 | §453 | ★★★ — ONE SOURCE PER UNIQUE FUNCTION: THE INCLUDE-AT-SITE SHARE, ITS GATE, AND THE FOUR DE |
|
||||
| L37604 | §454 | Rung D and rung R: taking a lever off a body that still has to compile to the same bytes ( |
|
||||
| L37671 | §454a | the recipe rung's real shape: replication, not discovery (S99, measured) |
|
||||
| L37686 | §455 | Rung G, the guided search: score the object, classify the residual, compose the moves (Pha |
|
||||
| L37759 | §456 | The lever-removal move catalog: what the S104 agents found under ~205 pins, barriers and l |
|
||||
|
||||
@@ -37755,3 +37755,52 @@ register is busy in the original and free in mine, which is a liveness the sourc
|
||||
draws it nor strips those sites from its seed; it had been searching for a reload that the cast it removed produces. And the
|
||||
head is where the number is: after four runs the next 64 classes by copies carry 498 bodies, while the ~65 head classes that did not
|
||||
close hold ~8,000 — each is worth a reading (`--explain --path` on its best moves) and a generator, not a wider tail pass.
|
||||
|
||||
## §456 — The lever-removal move catalog: what the S104 agents found under ~205 pins, barriers and launders (Phase 36 T7)
|
||||
|
||||
Every entry below was byte-proven on at least one banked body in S104 (the agent, the pass and the `file:line` are in that
|
||||
pack's `mechanism.md` under `.run/P36/agents/<alias>__<fn>/`; METHOD_S103.md steps 12–16 carry the same list with the ids).
|
||||
The pattern across the session: a decompiler-shaped body forces a lever because of ONE spelling decision; the original's
|
||||
natural C removes it. Try these in order on a residual before any register lever.
|
||||
|
||||
**Register residuals (local-alloc / global.c).**
|
||||
- One value per temp: a local that dies in several places is refused by local-alloc (`local-alloc.c:472`) and goes global —
|
||||
substitute in place, split, or declare per block / per switch case (generators R23, R29). The INVERSE also closes: two locals
|
||||
the tree pins to one register are one variable (R28), a late local reusing an earlier-dead one lands in its register (R34).
|
||||
- Call-result temps of one type across cases → one function-scope variable (many refs, short live length outrank the self pointer).
|
||||
- A block with exactly THREE quantities is allocated in BIRTH order, not sorted (`local-alloc.c:1486-1507`; `tools/localalloc_sim.py`
|
||||
models it): add or remove a quantity (a compound assignment, an inlined re-read) to flip it (R32).
|
||||
- An integer-truncated `allocno_compare` TIE (`global.c:594-607`, ties by allocno number; `tools/alloc_table.py` flags `TIE`):
|
||||
duplicate the statement after an if/else join into both arms — one insn of live length splits it and cross-jump re-merges (R39).
|
||||
- A parameter copy `T x = argN;` deleted (R35) or moved to a later plain statement; `return ++i;` for a counter's refs (R40);
|
||||
a call passed at its REAL arity (the extra arg costs 0 bytes — jump2 deletes the no-op copy, `jump.c:425-462`) (R19).
|
||||
- Widths: an `s16`/`u16`/`u8` local for a value used narrow keeps a SUBREG copy cse cannot fold (`cse.c:7440-7474`); a cast at
|
||||
ONE shift, `(s16)t >> N` (R31); joint widths on several locals at once.
|
||||
- A walked pointer stepped alongside another → indexed by the counter (`record_giv` `loop.c:4341`, `combine_givs` `:5494`);
|
||||
a load split from its update `T = LOAD; … P = T + X;`; a twice-set pointer `p = &D; p += x;` as one expression (R36 — the
|
||||
frame-only residual: combine leaves the ref count, reload gives a slot, `combine.c:2305-2337`, `reload1.c:2327-2352`).
|
||||
- A named derived pointer `q = p - k` that cse keeps as a REGISTER address (`find_best_addr`, `cse.c:2656-2721`) — the `la` lever.
|
||||
|
||||
**Order / count residuals (cse, sched, jump, reorg).**
|
||||
- A goto chain → structured C (if/else, `||`, `switch`, `for` with `break`/`continue`, a shared tail written out per site): a
|
||||
label between a store and its tail blocks jump1's if-conversion (`jump.c:805`/`:1019`), cross-jump re-merges duplicated tails
|
||||
(`jump.c:2371`) at zero bytes, a rotated loop's `NOTE_INSN_LOOP_VTOP` flips reorg's `mostly_true_jump` (`reorg.c:1364-1372`).
|
||||
The reverse exists too: a do-while as a backward goto loop when the target shows NO loop optimisation (`loop.c:352-361`).
|
||||
- `x = a; if (c) x = f(a);` → if/else with the non-simple value in the ELSE arm (jump1 re-merges a reg/const else, `jump.c:739-741`) (R33).
|
||||
- A result local `r = 0; if (A) r = (B); return r;` → `if (A && B) return 1; return 0;` (jump1's store-flag on the hard `$v0`) (R37).
|
||||
- A store in EACH arm when the target reloads a global after it (cse forwards only within a block, `cse.c:7358-7369`, `:8039`)
|
||||
or when sched1 treats two symbols as non-aliasing; each arm's store BEFORE its counter; the if/else arms swapped for reorg's
|
||||
delay-slot steal (R41); a statement moved several positions down its block (R42).
|
||||
- A sign test whose arms set/clear bit 31 → `& 0x80000000` (the mask's `lui` fills the slot, `reorg.c:2799`; the dead AND's slot
|
||||
is what a pad faked) (R43). A hand-expanded `if (v < 0) v += 2^k-1; v >>= k;` is `v / 2^k` (R38); `(b << k) - b` is `b * (2^k-1)`.
|
||||
- Set counts steer three passes: a second identical assignment demotes sched1's birthing boost (`sched.c:2469-2545`), keeps a
|
||||
constant off REG_EQUIV's doubled live length (`local-alloc.c:1016-1064`), and keeps loop.c from hoisting (`loop.c:705`).
|
||||
- Struct/array spelling decides sched's alias test (`expr.c:4568-4577` → `sched.c:817-861`): a cast byte-offset store is
|
||||
scalar, an indexed/field access is aggregate — pick per access group; GTE scratch words gathered into one local struct; a
|
||||
16-byte copy loop as ONE struct assignment (`expand_block_move`, `mips.c:2330ff`).
|
||||
- Sony's GTE macros replace hand-flattened GTE asm blocks; parameters straight into the macros (reload's spill register).
|
||||
|
||||
**Signals that a close is NOT plain C (park it, structs phase):** a `(void)` function whose first act reads a pinned `$a0`–`$a3`
|
||||
takes a parameter; a `void` function whose final keepalive reads `v0` returns it; a narrow parameter the bytes use as s32 is
|
||||
s32; a store through another symbol of the same address is identical only after LINKING. Refused as closes: an invented
|
||||
always-false condition, a dead store kept only to steer a pass, a pointer alias invented only to dodge cse.
|
||||
|
||||
Reference in New Issue
Block a user