mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-27 05:56:00 -04:00
docs(cookbook): §398b — naming a sub-expression changes which pseudo survives; inline it at both use sites
This commit is contained in:
@@ -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 / 1059 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 / 1060 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.
|
||||
|
||||
@@ -1323,7 +1323,7 @@
|
||||
- **§378b** — ★★★ — THE FOUR VARIANTS OF THE DECL BLOCKER, AND THE TWO PLACES §378 DOES **NOT** APPLY (P31 S69, all four measured the same day) <sub>L32572</sub>
|
||||
- **§398** — ★★★ — `family_remap` CARRIES THE **SOURCE** TU's DECL ENVIRONMENT INTO A DESTINATION THAT ALREADY OWNS THOSE NAMES (P31 S69; measured 3 banked of 22) <sub>L32835</sub>
|
||||
|
||||
### (unbucketed — title matched no symptom vocabulary) (312)
|
||||
### (unbucketed — title matched no symptom vocabulary) (313)
|
||||
|
||||
- **§3-How** — to use this <sub>L30</sub>
|
||||
- **§1** — Idiom catalog (asm pattern → C that produces it) <sub>L39</sub>
|
||||
@@ -1637,6 +1637,7 @@
|
||||
- **§394** — ★★ — TWO ALIGN-1 ACCESSES IN ONE FUNCTION RESERVE A PHANTOM STACK SLOT (P31 S69; ov_SC02_005/func_80180610) <sub>L32560</sub>
|
||||
- **§314b** — ★★ — TWO ABS-RANGE GUARDS IN ONE FUNCTION NEED **DIFFERENT SPELLINGS** (P31 S69; byte-proven ov_SC04_002/func_8018691C, 111 ins) <sub>L32645</sub>
|
||||
- **§397** — ★★★ — RE-RUN THE TWIN SCAN AFTER EVERY EXEMPLAR BANK; A CLUSTER SIBLING IS FREE THE MOMENT ITS EXEMPLAR LANDS (P31 S69; ~250k tokens spent proving it the expensive way) <sub>L32785</sub>
|
||||
- **§398b** — ★★ — NAMING A SUB-EXPRESSION IN A LOCAL CHANGES WHICH PSEUDO SURVIVES; INLINE IT AT BOTH USE SITES (P31 S69; byte-proven ov_SC03_028/func_80183264, 93 ins) <sub>L32865</sub>
|
||||
|
||||
|
||||
## All sections, in order
|
||||
@@ -2700,6 +2701,7 @@
|
||||
- **§397** — ★★★ — RE-RUN THE TWIN SCAN AFTER EVERY EXEMPLAR BANK; A CLUSTER SIBLING IS FREE THE MOMENT ITS EXEMPLAR LANDS (P31 S69; ~250k tokens spent proving it the expensive way) <sub>L32785</sub>
|
||||
- **§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>L32818</sub>
|
||||
- **§398** — ★★★ — `family_remap` CARRIES THE **SOURCE** TU's DECL ENVIRONMENT INTO A DESTINATION THAT ALREADY OWNS THOSE NAMES (P31 S69; measured 3 banked of 22) <sub>L32835</sub>
|
||||
- **§398b** — ★★ — NAMING A SUB-EXPRESSION IN A LOCAL CHANGES WHICH PSEUDO SURVIVES; INLINE IT AT BOTH USE SITES (P31 S69; byte-proven ov_SC03_028/func_80183264, 93 ins) <sub>L32865</sub>
|
||||
|
||||
|
||||
---
|
||||
@@ -3771,3 +3773,4 @@ Notes routinely quote that as a section id. This table resolves it. Grep bait: `
|
||||
| L32785 | §397 | ★★★ — RE-RUN THE TWIN SCAN AFTER EVERY EXEMPLAR BANK; A CLUSTER SIBLING IS FREE THE MOMENT |
|
||||
| L32818 | §396g | ★★ — A GUARD LADDER'S RUNGS MUST STAY SYMMETRIC OR `reorg.c` LOSES ITS BRANCH REDIRECT (P3 |
|
||||
| L32835 | §398 | ★★★ — `family_remap` CARRIES THE **SOURCE** TU's DECL ENVIRONMENT INTO A DESTINATION THAT |
|
||||
| L32865 | §398b | ★★ — NAMING A SUB-EXPRESSION IN A LOCAL CHANGES WHICH PSEUDO SURVIVES; INLINE IT AT BOTH U |
|
||||
|
||||
@@ -32861,3 +32861,30 @@ environment — the information exists (`decl_prior` already computes it for car
|
||||
`cast_self_callers`/`fix_arity_callers` already edit it). Until it does, the remap lane's realistic
|
||||
yield is ~15% straight-through and ~50% after integration, not the 76–88% the PURE-class rate
|
||||
suggests. **Quote the straight-through number when planning, not the class rate.**
|
||||
|
||||
## §398b ★★ — NAMING A SUB-EXPRESSION IN A LOCAL CHANGES WHICH PSEUDO SURVIVES; INLINE IT AT BOTH USE SITES (P31 S69; byte-proven ov_SC03_028/func_80183264, 93 ins)
|
||||
|
||||
Writing a repeated computation **inline at both use sites** and writing it **once into a named local**
|
||||
are not equivalent, and the difference is visible in the register file:
|
||||
|
||||
```c
|
||||
f( (v1 * 104) / 1024, ... ); /* inline at BOTH sites — cse builds the CSE itself */
|
||||
s32 t = (v1 * 104) / 1024; /* named — expmed.c:2986 copy_to_mode_reg's temp */
|
||||
```
|
||||
|
||||
Naming it lets `expmed.c`'s `copy_to_mode_reg` temp **coalesce with the product** (an in-place
|
||||
`addiu`/`sra`) and moves the surviving divide-copy onto the `/16`. Letting cse construct the common
|
||||
subexpression itself keeps the temp a **separate pseudo** — which is what the target shows.
|
||||
|
||||
**Two companions from the same crack:**
|
||||
* **An `s16` local's cse quantity differs from an `s32` one**, and that difference alone is why an
|
||||
`addu $s3,$s2,$zero` copy survives. Rewriting as `s32 t` + an `(s16)` cast lets `t.i.cse` fold
|
||||
three regs into one and the function loses two saved registers and two copies. **The declared width
|
||||
is a cse-quantity dial, not just a codegen one** (compare §392b).
|
||||
* **The §136d-1 `zr` trick needs to be applied to BOTH copies, not one.** `arg = ang;` alone is
|
||||
`canon_reg`'d away; `arg = ang + zr;` on both copies lets cse merge the two identical `ang+$0`
|
||||
expressions into one, reproducing the target's pair.
|
||||
|
||||
**Banking caveat:** a `register … __asm__("$0")` pin fails `dedup_propagate.compiles_standalone`
|
||||
(§37), so a function cracked this way banks ×1 and never propagates to siblings. Prefer a
|
||||
width/inlining lever over a `$0` pin when the function has cousins.
|
||||
|
||||
Reference in New Issue
Block a user