6.3 KiB
§27 — Giant matching recipe (Phase 21 cont.7b — validated on func_80176D94, 152 ins)
Giants (reach-134 >150 ins) are the byte-weight lever. Validated approach (func_80176D94 → structurally matched, calls/constants/GPU-packet all byte-correct, residual = pure regalloc):
- Start from the cached Ghidra-C (
.run/ghidra_c/<fn>.c) — giants are often CLEAN (straight-line + many calls, no deep control flow), so the body structure comes nearly free. (cont.2's "stale+incomplete drafts" were the OLD m2c drafts vs the grown header; the fresh Ghidra-C + canonical context is the fix.) - Arg-arity is the #1 giant blocker (the manifest's
MCOMPILE_arg-aritybucket). Giants call many helpers; m2c/Ghidra miscount args. Declare each callee to match the ACTUAL call site — count the$a0–$a3(+ stack) set before eachjal, NOT the canonical sig. e.g.func_80177784canonical is 4-arg but called 3-arg here ($a3untouched) → declarefunc_80177784(void*, s32, s32). (The shared-header canonical conflict is the gate's job —cast_call_sites; it may bank ×1 if irreducible, §24.) - Sibling templates. Giants cluster in families (GPU-packet builders, coord transforms). Find an
already-matched sibling
DEFINE_func_*inengine_core.hwith the same idiom and mirror its PROVEN C form — e.g. the GPU-coord strength-reduce((s32)(D * 10355) << 1) >> 16(sibling func_80176FF4) and the GPU linked-list pointer((u32)addr & 0xFFFFFF) | 0x3000000. - §17 register pins for the regalloc-SHIFT. Giants use 5–7 callee regs; gcc's mapping often shifts whole-hog
(param→$s0 where target uses $s2, etc.). Pin the long-lived vars to their target regs
(
register T v __asm__("$NN")). CAVEAT (cont.7b, byte-proven): do NOT pin a var whose register the target REUSES for a later spill — pinning reserves the reg for that var's whole scope → blocks the reuse → gcc grabs a FRESH callee reg (+1 reg, +2 prologue ins). (func_80176D94: pinning uVar5→$s0 blocked the accumulator from reusing dead $s0.) - The giant residual class — accumulator-spill coalescing. A value chained through
$v0→$a0across calls, then needing to survive a LATER call, must spill to a callee reg. The target reuses a now-DEAD callee reg; gcc from natural C grabs a FRESH one (+1 reg). Hard to force from C (it's gcc's coalescing graph) → permuter fuel (the grinder randomizes allocation and may find the reuse). func_80176D94's saved draft (.run/backlog_drafts/) is exactly this — structurally done, 1–2 callee regs from byte-perfect. Net: giants reach STRUCTURALLY-MATCHED fast (steps 1-3); the last mile is regalloc-coalescing (step 5) — so giants are ISOLATED-AGENT + permuter work (perbreadth-isolated-agents-not-serial), not main-loop serial grind.
WAVE RESULT (cont.7d — the honest yield, R14/P9): a 6-giant worker_wave banked 0. The agents reached the SHAPE (the §27 recipe works — bodies/calls/constants/control-flow right) but the whole-binary byte-gate rejected all 6: 1 was close=0 match_one-MATCH yet gate-REJECTED (func_8014F74C — no callee/data conflict, so match_one OVER-predicted: the masked standalone match hid a real residual, §25), 1 wouldn't compile whole-binary (func_80144090, agent-claimed "154/154" but a decl the gate couldn't reconcile), and 4 were genuinely far (close 53–164 — the agents' "structural match" self-claims were match_one-optimistic). This confirms cont.2 / Phase-20 / Phase-16 (~3% wall): giants do NOT auto-bank — even with the §27 recipe + isolated agents, the whole-binary gate (masked-residual + plumbing + large regalloc) blocks them. Giants are HAND-FINISH / backlog fuel (the wave's deliverable is 6 RANKED near-miss drafts for human sessions, NOT banks). Do not scale giant auto-waves expecting %; the automated reach-134 harvest is COMPLETE at this fleet level (every automated lever — cheap recovery, permuter, giant auto-wave — banks ~0). Forward % = hand-finishing (Drew) or closing the phase.
Frame-pressure-locked residuals are PERMUTER-ONLY (cont.7d, byte-proven on func_8014EA4C, close=6). When a
giant's matched body needs a frame-forcing HACK to hit the right stack size — e.g. a DEAD u8 buf[16]; memcpy(buf+16, src, 8) (an out-of-bounds copy whose only job is to force frame 0x60) — its remaining schedule/regalloc residuals
become PRESSURE-LOCKED: any C edit that would steer them (materialize a temp to reorder a store/load; a ternary or
s32 retype of an abs; a register pin) shifts register pressure → gcc DROPS the dead buffer → frame shrinks
(0x60→0x58) → whole-function offset cascade (close 6 → 23–123). Two hand attempts both cascaded exactly as the
drafter predicted. The fix is NOT C-steering — it's the decomp-permuter (the grinder): it randomizes
regalloc/scheduling via semantics-preserving C perturbations the byte-gate scores, exploring the frame-PRESERVING
space the hand-edits can't. Re-log such giants with their true closeness + raw draft (source=giant-raw) so the
grinder (close≤30) picks them up; do NOT hand-grind them.
Deep frame-RE does NOT crack a scheduler-walled giant (cont.7d, byte-proven on func_8014EA4C). Drew chose
"deep re-RE the real frame so regalloc resolves." The RE finding: the frame is a dead aggregate copy — 8 bytes
of a param unaligned-copied (lwl/lwr→swl/swr, char-aligned dest) to a stack local at sp+0x20 that's NEVER read
(gcc-2.7.2 keeps it — no DSE for aggregates). The drafter's u8 buf[16]; memcpy(buf+16, a2, 8) (copy PAST the
array) is a PRECISE reproduction of the exact gcc stack layout — local[0x38] or any "robust" remodel produces a
DIFFERENT frame (0x88, copy at 0x30). So the frame is already correct at close=6; the residuals are NOT
frame-caused — they're loop-body scheduler (a global store vs a call-arg load order) + regalloc (abs in $v1 vs
in-place $v0), the irreducible §20/§25 wall. Lesson: when a giant's residual is loop-body schedule/regalloc,
deep frame-RE is a dead end — only the permuter explores that space. Net for Phase 21: 5 levers
(cheap-recovery, permuter, giant-wave, hand-finish, deep-RE) are byte-proven exhausted at fleet 63.17% for the
reach-134 tail; the residual is the gcc-2.7.2 scheduler/regalloc wall, addressable only by the (low-yield) permuter
or by accepting it as the matching ceiling at this fleet level.