diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index 1d1cd2116f..80e2b184ba 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -37253,3 +37253,24 @@ copy emits a `move` (101 ins) — launder the destination variable. **Law:** whe permutation that every pin-set fails to move, the pin may be the wall: pins forbid their register to every retried allocno. Remove the pin, read `-dl` for the local quantities' priorities, and steer with launders (birth/death dials) instead. Corollary for the map (regalloc.md): `retry_global_alloc` + `bad_spill_regs`; `qty_compare` = `floor_log2(n_refs)·n_refs·size/(death−birth)`. + +**§501-F — WHEN loop.c PROVES THE HOIST SPLIT UNREACHABLE, SPLIT THE CSE QUANTITY INSTEAD: a hard-register copy of the dividend +makes the divide's multiply non-movable while the divide's own sign correction is CSE'd into a hoisted variable (P32 T4b, +`ov_SC03_105:func_801834A4`, the "hoist only the sra" wall banked by a Fable agent — 106/106).** The S71 proof stands and is now +dump-confirmed: `expand_divmod` (expmed.c:3034–3057) emits K=const, B=`smulsi3_highpart`, C=`op0 >> 31`, D=`B − C` adjacently from ONE +`op0`, so loop.c gives B and C the same `invariant_p` verdict; if B is movable, `force_movables` (loop.c:1193–1228) links K to B +and DOUBLES its savings (`174 >= 37` → everything hoists, the 75 baseline), and a hard-register dividend kills B, C and D +alike. From one division of one register the target's split (sra hoisted, K/B/D inline) is unreachable — **so the lever is in +cse, not loop.c.** `canon_reg` never rewrites a hard register, but `canon_hash`/`exp_equiv_p` compare by `reg_qty`: write +`sign = half >> 31;` at the TOP of the loop body (a movable by criterion (1), `maybe_never == 0`), copy the dividend into a +hard register `register s32 hh __asm__("$2"); hh = half;`, and divide THAT: `pos[0] -= hh / 3;`. B reads `(reg 2)` (call-used +hard reg → `invariant_p == 0` → not movable → K unlinked, life 1 → inline; D not movable), while C = `(ashiftrt (reg 2) 31)` +hashes into `sign`'s quantity → replaced by `(reg sign)` → D becomes `B − sign`; `sign`'s store hoists (life 71); combine folds +the `hh = half` copy into the mult (`can_combine_p` allows a hard i2dest with REG_DEAD in i3) → zero extra insns. Two traps, +both measured: (1) pin `hh` to `$2`, not a callee-saved reg — a callee-saved pin enters `regs_ever_live` before combine deletes +the copy and global.c pass 0 hands the already-live reg to the first callee-saved allocno (closeness 7); (2) jump.c:548–556 +deletes an UNREAD pseudo store (`regno_first_uid == regno_last_note_uid`) before cse sees it — keeping `sign` alive with an +`__asm__("" :: "r"(sign))` feed adds +2 loop-weighted refs and swaps `half`/`sign` in `allocno_compare` (closeness 4); a dead +initializer `s32 sign = 0;` gives the store a second reference that jump/cse respect and flow deletes, uncounted → the target's +`$s1..$s7` order. Law: **a division by a constant is four insns from one rtx; to hoist a subset, give the subset a different +QUANTITY (a hard-reg copy for the part that must stay, a named variable for the part that must move).** diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index 99cf39bd12..9c43ab8e9e 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -99,7 +99,7 @@ Scale estimate: 3–5 sessions. `func_80011380` → `.run/m3/opus/func_80011380.c`; `func_801834A4` → `.run/S71_gate14/ov_SC03_105*/`), `exclude_audit --write`, `backlog.py render`; a T3 idiom naming a wall's mechanism re-opens that row (bounded: one attempt, permuter first). Wall table into this file; cookbook §496+; decision log; accelerators. -- [ ] **T4b — crack and bank the final 15 (ADDED 2026-09-05 by Drew's directive, supersedes the kill gate: "anything that isn't the original hand-written asm or the PsyQ libs needs to be cracked and banked before we finish"; "before you spawn Fable agents, hand crack each and figure out the blocker to fix it")** (xHigh→Max recommended; Fable agents authorised AFTER the hand pass): for each of the 15 rows (8 NEAR + 7 walls) the coordinator hand-cracks — read the diff + the recorded mechanism, read the compiler (dumps + source), find the lever the record did not try, measure, bank through the verified chain (rtu in the real TU → bank.sh / gate_main) — and only then hands the leftovers to one Fable agent each (brief `.run/P32/t5x/BRIEF.md`). Plumbing landed first: `src/800_c.c` decl/extern edits byte-neutral (this commit). Work dirs `.run/P32/t4b//`. **Hand pass DONE 2026-09-05 (S83): all 15 rows read against their diffs and the compiler; 22 spellings measured (all regressions), 0 banks; every row's blocker refined to a named mechanism with the untried lever written in `.run/P32/t4b//NOTES.md` (func_80032A74: the transient caller-save area — reload1.c order proven; func_8017DF28: the block-move pseudo reuse vs reorg's branch-target hoist; func_80011380: the target's assignment shape; func_801834A4: sign-hoist vs const-hoist thresholds; …). TU plumbing for func_80039DEC/func_800391D4 committed byte-neutral (`commit:3953`). 15 Fable agents launched ~13:05 MDT (two usage-limit outages, resumed each time via SendMessage). **T4b (1): `main:func_800391D4` BANKED 143dbb89 (`commit:3956`) — a pinned wall: explicit promotion + insn_count pads 7→9 (§501); pin dropped. **T4b (2): `main:func_80039DEC` BANKED 143dbb89 (`commit:3959`) — a pinned wall: the natural switch with duplicated tails, so a2's raw copy keeps 4 refs and wins $a3 (§501-B); pins 7 → 5. **T4b (3): `md_MAIN_009:func_800CD674` BANKED d270f695 (`commit:3964`) — the $a3↔$t1 plateau: a 2-death pseudo is excluded from local_alloc; a fresh single-death pseudo for prim 4 + a zero-byte asm set on prim 3's copy against sched1's birthing boost (§501-C). **T4b (4): `ov_SC06_022:func_8017DF28` BANKED 2a7d7d4e (`commit:3966`) — a pinned wall: one value-returning call made the call a sched1 "birthing" insn (reg_n_sets[$v0]==1); a second $v0 set via RotMatrixY's real pointer-returning type (§501-D); pins 5 → 4. **T4b (5): `main:func_80020DA4` BANKED 143dbb89 (`commit:3969`) — a pinned wall: the $6 pin forbade $a2 at reload's retry (regs_ever_live → bad_spill_regs); unpinned + two zero-byte launders (§501-E); pins 4 → 3; main 3 open.** Agents resumed 3 at a time (Drew) from `.run/P32/t5x/resume_queue.txt`; 10 rows remain (3 running).** +- [ ] **T4b — crack and bank the final 15 (ADDED 2026-09-05 by Drew's directive, supersedes the kill gate: "anything that isn't the original hand-written asm or the PsyQ libs needs to be cracked and banked before we finish"; "before you spawn Fable agents, hand crack each and figure out the blocker to fix it")** (xHigh→Max recommended; Fable agents authorised AFTER the hand pass): for each of the 15 rows (8 NEAR + 7 walls) the coordinator hand-cracks — read the diff + the recorded mechanism, read the compiler (dumps + source), find the lever the record did not try, measure, bank through the verified chain (rtu in the real TU → bank.sh / gate_main) — and only then hands the leftovers to one Fable agent each (brief `.run/P32/t5x/BRIEF.md`). Plumbing landed first: `src/800_c.c` decl/extern edits byte-neutral (this commit). Work dirs `.run/P32/t4b//`. **Hand pass DONE 2026-09-05 (S83): all 15 rows read against their diffs and the compiler; 22 spellings measured (all regressions), 0 banks; every row's blocker refined to a named mechanism with the untried lever written in `.run/P32/t4b//NOTES.md` (func_80032A74: the transient caller-save area — reload1.c order proven; func_8017DF28: the block-move pseudo reuse vs reorg's branch-target hoist; func_80011380: the target's assignment shape; func_801834A4: sign-hoist vs const-hoist thresholds; …). TU plumbing for func_80039DEC/func_800391D4 committed byte-neutral (`commit:3953`). 15 Fable agents launched ~13:05 MDT (two usage-limit outages, resumed each time via SendMessage). **T4b (1): `main:func_800391D4` BANKED 143dbb89 (`commit:3956`) — a pinned wall: explicit promotion + insn_count pads 7→9 (§501); pin dropped. **T4b (2): `main:func_80039DEC` BANKED 143dbb89 (`commit:3959`) — a pinned wall: the natural switch with duplicated tails, so a2's raw copy keeps 4 refs and wins $a3 (§501-B); pins 7 → 5. **T4b (3): `md_MAIN_009:func_800CD674` BANKED d270f695 (`commit:3964`) — the $a3↔$t1 plateau: a 2-death pseudo is excluded from local_alloc; a fresh single-death pseudo for prim 4 + a zero-byte asm set on prim 3's copy against sched1's birthing boost (§501-C). **T4b (4): `ov_SC06_022:func_8017DF28` BANKED 2a7d7d4e (`commit:3966`) — a pinned wall: one value-returning call made the call a sched1 "birthing" insn (reg_n_sets[$v0]==1); a second $v0 set via RotMatrixY's real pointer-returning type (§501-D); pins 5 → 4. **T4b (5): `main:func_80020DA4` BANKED 143dbb89 (`commit:3969`) — a pinned wall: the $6 pin forbade $a2 at reload's retry (regs_ever_live → bad_spill_regs); unpinned + two zero-byte launders (§501-E); pins 4 → 3; main 3 open. **T4b (6): `ov_SC03_105:func_801834A4` BANKED d305ff6d (`commit:3972`) — a pinned wall: the S71 loop.c proof holds, the lever is cse — a hard-reg copy of the dividend + `sign = half >> 31` at the loop top splits the quantity (§501-F); pins 3 → 2.** Agents resumed 3 at a time (Drew) from `.run/P32/t5x/resume_queue.txt`; 9 rows remain (3 running).** - [ ] **T5 — PhaseEnd** (Max, Tier 1 — prompt R27): P7 checkbox walk; milestone demo (R22 fleet N/N, tools-health, `verbatim_check --strict`, final census, wall ledger, parked-5 dispositions via `make audit-disc`, `make report` all three metrics + main `143dbb89…` with/without SDK dirs, corrected denominators); **WAIT