mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-08 01:34:14 -04:00
fix(phase-29): dedup_propagate — the "overlay-local TYPE (the real cap)" skip was a MISLABEL
compiles_standalone() returned a bare False and the caller attributed EVERY failure to the overlay-local type cap. The dominant real cause is undeclared FILE-SCOPE EXTERNS: the body references extern decls living outside the extracted def block (func_80174CB0: 22 of them; carrying them makes it compile cc1 rc=0). - compiles_standalone now returns (ok, stderr); the skip is classified by actual cause: "missing file-scope extern (CARRY-FIXABLE): <names>" vs "overlay-local TYPE (the real cap)". - FLEET SIZING (--auto-from ov_SC01_077 --check-only): 7 skipped, ALL 7 carry-fixable, 0 genuine type-cap. Three of them (0x80142B2C/0x801535F4/0x80155800) are on the Phase-21 backlog list whose note ALREADY said "macro-extern-injection frees them x134 (~+0.3%)" -- never built, because the mislabel told every later session they were the type wall. A wrong label cost ~4 phases. - also: func_80174CB0's local Mtx_/Svec_ typedefs swapped for the canonical shared MATRIX/SVECTOR (byte-identical layouts); ov_SC07_006 still BYTE-IDENTICAL 7ca772be. - value behind the real fix: the 7 (~+0.3pp) + func_80174CB0 x138 (16,974 ins, ~+0.13pp), ~0 tokens. - _carry_externs itself is SPEC'd but NOT built here: it writes 138 overlay files (§63 class) and wants a fresh session with an R22 budget. func_80174CB0 (banked x1) is the test case.
This commit is contained in:
@@ -3386,3 +3386,40 @@ conditional) · main-EXE/B9 + GLM/B6 + resident's 14 walls (P30) · behemoths B7
|
||||
**Test: revert the 4 decl lines, re-gate. If it still banks, `recover_integration` should probe
|
||||
whether a stage is NEEDED before applying it** — an unrequested tier escalation is exactly the class
|
||||
R32–R35 exist to catch.
|
||||
|
||||
- **🚨 2026-07-24 (SESSION-18) — THE PROPAGATION "TYPE CAP" IS A MISLABEL. Measured 7/7 CARRY-FIXABLE,
|
||||
0/7 actual type problems. This is why a fix Phase 21 already specified was never built.**
|
||||
`dedup_propagate.compiles_standalone()` returned a bare `False` and the caller filed EVERY failure
|
||||
under `"overlay-local TYPE (the real cap)"`. Reproducing the compile by hand shows the real cc1
|
||||
errors are **undeclared file-scope externs** — the body references `extern` decls that live OUTSIDE
|
||||
the extracted def block. For `func_80174CB0`: 22 carried externs make it compile **clean** (verified:
|
||||
cc1 rc=0). It is not a type problem at all; it is the exact gap Phase-27's
|
||||
`family_remap._carry_macros` closed for file-scope `#define`s, one level over — **extern decls**.
|
||||
**FIXED (safe, read-only classification):** `compiles_standalone` now returns `(ok, stderr)` and the
|
||||
skip is classified by ACTUAL cause — `missing file-scope extern (CARRY-FIXABLE): <names>` vs
|
||||
`overlay-local TYPE (the real cap)`. R32/R33/R34: a skip that discards its own diagnosis is invisible
|
||||
work; one that ASSERTS the wrong cause is worse — it redirects every later session.
|
||||
**FLEET SIZING (`--auto-from ov_SC01_077 --check-only`, touches nothing): 7 skipped, ALL 7
|
||||
CARRY-FIXABLE, ZERO genuine type-cap.**
|
||||
| addr | missing externs |
|
||||
|---|---|
|
||||
| 0x8016A73C | ApplyMatrixSV, D_800AE620, RotMatrixYXZ, func_80048EAC |
|
||||
| 0x80155800 | D_8011F730, func_8001382C, func_80146DB8, func_80146E98 |
|
||||
| 0x80167540 | func_80146A6C, func_80146C3C, func_801670E4, rand |
|
||||
| 0x801535F4 | func_8014CC28, func_8014ED28, func_8014FA04 |
|
||||
| 0x8016F0AC | D_80126B58, func_80165770 |
|
||||
| 0x80142B2C | func_80142C84, func_80143994 |
|
||||
| 0x8014FE60 | D_801152A8 |
|
||||
**⚠️ THE HISTORY MATTERS:** `0x80142B2C`, `0x801535F4`, `0x80155800` are on the **Phase-21 backlog's
|
||||
"7 callee/data-plumbing capped fns"** list, whose note already read *"a macro-extern-injection (or
|
||||
canonical-callee-sig embed) frees them ×134 (~+0.3%)"*. **Phase 21 diagnosed it correctly and it was
|
||||
never built** — and in the meantime the mislabel told every subsequent session these were the type
|
||||
wall. A wrong diagnostic label cost this project ~4 phases of a known, mechanical win.
|
||||
**VALUE LOCKED BEHIND THE CARRY FIX:** these 7 (Phase-21 estimated ~+0.3pp) **plus `func_80174CB0`
|
||||
itself** (123 ins × 138 = 16,974 ins ≈ **+0.13pp**), so ≈ **+0.4pp mechanical, ~0 agent tokens**.
|
||||
**NEXT (spec, deliberately NOT built in this long session — it writes 138 overlay files, the §63
|
||||
disaster class):** add `_carry_externs` to `dedup_propagate` mirroring `family_remap._carry_macros` —
|
||||
collect the file-scope `extern` lines matching the identifiers the body references, emit them INSIDE
|
||||
the lifted `DEFINE_func_*` body (existing macros already carry externs, e.g. `DEFINE_func_80174C60`,
|
||||
so the shape is established), dedupe against decls the target TU already has, then `--check-only` →
|
||||
one gate → **R22 mandatory**. `func_80174CB0` is banked ×1 today and is the ready-made test case.
|
||||
|
||||
@@ -8728,7 +8728,7 @@ DEFINE_func_80174C80() /* dedup: shared engine-core @0x80174c80 (src/shared) */
|
||||
// `((s16 (*)(s32,s32,s32))f)(...)` func-ptr cast idiom already used by func_801749C8,
|
||||
// so the canonical s32 prototypes are kept and NEVER redeclared.
|
||||
// * D_80126940/42/44 are already `extern s16` at TU:160-162 — drop the three externs below.
|
||||
// * Mtx_80174CB0 / Svec_80174CB0 are locally-unique names (== MATRIX / SVECTOR layouts) so
|
||||
// * MATRIX / SVECTOR are locally-unique names (== MATRIX / SVECTOR layouts) so
|
||||
// they cannot collide with engine_types.h; they may be kept as-is or swapped for
|
||||
// MATRIX / SVECTOR when banking.
|
||||
// * THE OWN-SIGNATURE BLOCKER (the layer under the func_80012ABC one): the TU expands
|
||||
@@ -8745,8 +8745,6 @@ DEFINE_func_80174C80() /* dedup: shared engine-core @0x80174c80 (src/shared) */
|
||||
#include "common.h"
|
||||
|
||||
/* --- standalone-only scaffolding (bank-safe: names are unique to this function) --- */
|
||||
typedef struct { short m[3][3]; long t[3]; } Mtx_80174CB0; /* == MATRIX, 0x20 bytes */
|
||||
typedef struct { short vx, vy, vz, pad; } Svec_80174CB0; /* == SVECTOR, 0x08 bytes */
|
||||
|
||||
extern s16 D_80126940;
|
||||
extern s16 D_80126942;
|
||||
@@ -8764,9 +8762,9 @@ extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||||
s32 func_80174CB0(s32 param_1, s32 param_2)
|
||||
{
|
||||
s16 *pv = &D_80126940;
|
||||
Mtx_80174CB0 mtx;
|
||||
Svec_80174CB0 vec;
|
||||
Svec_80174CB0 out;
|
||||
MATRIX mtx;
|
||||
SVECTOR vec;
|
||||
SVECTOR out;
|
||||
|
||||
*(s32 *)(param_1 + 8) = (s16)((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 8), (s32)*(s16 *)(param_1 + 0xc), 4);
|
||||
*(s32 *)(param_1 + 0x10) = (s16)((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x10), (s32)*(s16 *)(param_1 + 0x14), 4);
|
||||
|
||||
@@ -345,11 +345,11 @@ def compiles_standalone(body_lines):
|
||||
"-fno-builtin", "-Dmips", "-D__GNUC__=2", "-D__OPTIMIZE__", "-Dpsx",
|
||||
"-D_PSYQ", "-D_MIPSEL", "-D_LANGUAGE_C", str(f)], capture_output=True, text=True)
|
||||
if cpp.returncode != 0:
|
||||
return False
|
||||
return False, (cpp.stderr or "cpp failed")
|
||||
cc1 = subprocess.run([str(CC1), "-quiet", "-O2", "-G0", "-mips1", "-mcpu=3000", "-mgas",
|
||||
"-msoft-float", "-fgnu-linker", "-o", "/dev/null"],
|
||||
input=cpp.stdout, capture_output=True, text=True)
|
||||
return cc1.returncode == 0
|
||||
return cc1.returncode == 0, (cc1.stderr or "")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- main
|
||||
@@ -462,8 +462,20 @@ def main():
|
||||
# then rejects any body using an overlay-local type NOT yet promoted to the header.
|
||||
if re.search(r'(\b(struct|union)\s+\w+\s*\{)|(\btypedef\b)', "\n".join(body)):
|
||||
n_local += 1; skipped["inline type def in body"].append(addr); continue
|
||||
if not compiles_standalone(body): # uses overlay-local types -> can't lift mechanically
|
||||
n_local += 1; skipped["overlay-local TYPE (the real cap)"].append(addr); continue
|
||||
ok, why = compiles_standalone(body)
|
||||
if not ok:
|
||||
# SESSION-18: this bucket asserted "overlay-local TYPE" for EVERY failure, which is a
|
||||
# mislabel — the dominant real cause is that the body references file-scope `extern`
|
||||
# decls that live OUTSIDE the extracted block (func_80174CB0: 22 of them), exactly the
|
||||
# gap Phase-27's family_remap._carry_macros closed for file-scope #defines. Name the
|
||||
# causes apart so the queue can be sized honestly (R32/R33).
|
||||
undecl = sorted(set(re.findall(r"`([A-Za-z_]\w*)' undeclared", why)))
|
||||
if undecl:
|
||||
n_local += 1
|
||||
skipped["missing file-scope extern (CARRY-FIXABLE): " + ",".join(undecl[:4])].append(addr)
|
||||
else:
|
||||
n_local += 1; skipped["overlay-local TYPE (the real cap)"].append(addr)
|
||||
continue
|
||||
plan.append(dict(addr=addr, src=src, hash=h, body=body, members=members))
|
||||
|
||||
if n_local or n_nondef or n_lowreach:
|
||||
|
||||
Reference in New Issue
Block a user