Files
BFM-decomp/cookbook/C0180.md
T

4.1 KiB
Raw Blame History

§172 — THE ORPHAN-SLOT MECHANISM v2 (P30 S50-Max): the complete frame-residue model for gcc-2.7.2 MIPS

(v2 supersedes the S50 original in place: the Max-effort source reading corrected the producer list, the alignment math, and the strength of the impossibility claim. The instrument and the orphan rule are unchanged and re-verified.)

The instrument (tools/cc1_dumps.sh <draft.c> <tag>): run the pinned cc1 with -dr -ds -dj -dc -dl -dg, then count standalone (insn N P X (use (reg:M R))) insns in the .combine dump — count them across ALL modes, not just SImode. Each is one never-referenced reload slot. On func_8017CE58: draft 12, target frame demands the equivalent of 16.

Slot producers in the spill region (complete list, from the compiler source):

  1. alter_reg pseudo slots (reload1.c): every slotted pseudo gets assign_stack_local(mode, size, -1) — align −1 means BIGGEST_ALIGNMENT = 8 bytes, size rounded up to 8. This is why every orphan costs 8 bytes even in SImode. Slots are assigned in REGNO order: the a1-param pseudo (lowest) lands first, loop-opt-created pseudos (highest) last — the two ends of the spill region are position-pinned; everything between is order-free.
  2. combine USE-orphans (combine.c:10835): the ashift intermediate of a short-mem→int promotion triple, orphaned when the death-note walk (backward over plain insns only) hits a CODE_LABEL or JUMP_INSN. Orphan rule, byte-verified both directions: the HImode load's reg carries an extra HImode use (a ?: arm copy) → the load survives (or is REWRITTEN as (set (reg:HI) (subreg (reg:SI))) — combine does this rewrite, which is why an orphaning site can still show a single lh) → the promotion folds separately → orphan. Single-use load → 3-way merge consumes everything → no orphan. Sites before the first label/jump (the function head) can NEVER orphan — the walk reaches insn 0.
  3. caller-save areas (caller-save.c setup_save_areas; -fcaller-saves is ON at -O2): allocated eagerly — one assign_stack_local(SImode, 4, 0) = 4-byte slot per call-clobbered hard reg that carries a call-crossing pseudo at ANY reload iteration, whether or not a save/restore insn is ever emitted. Transient iteration-1 allocations that later respill leave never-referenced 4-byte areas.
  4. spill_stack_slot (reload1.c): one reused 8-byte slot per hard reg that pseudos are spilled FROM ("Spilling reg N" in the .greg dump).

The three-layer canonicalization wall (measured, ~120 probe forms + a 200-variant sweep): manufacturing an extra orphan with zero code drift requires an expression NOVEL to cse yet PROVABLY sign-extended to combine. Three layers jointly close every reachable spelling: fold-const normalizes the trees ((x<<16)>>16 arrives in RTL as the same subreg-promotion — verified in the expand dump), cse1/cse2 canonicalize through REG_EQUAL/quantity classes, and opacity that defeats cse (asm-laundered values/pointers) equally blinds num_sign_bit_copies (the survivor emits real shifts or loads: the opaque-pointer probe reproduces the exact 16-orphan target frame at +7 insns). Scalar declaration order (20 permutations) and TU context (both drafts run through the real whole-binary gate — first time ever for this class) are also byte-refuted as levers. The wall statement, honest form: the residual is not reachable by re-spelling the same computation; what remains is structurally different source with coincidentally identical bytes.

Transferable diagnostics: (1) frame-off-by-8k residual → count combine-dump USEs first, all modes; (2) slt-count changes in a probe = the ?: branch structure moved — the form is wrong; (3) which chain operands RE-LOAD in a later pass is pinned by which HI temps the earlier pass clobbered as ?: accumulators (the FIRST operand of each inner ?:), and the bytes pin that — a select-chain's elision pattern is byte-determined end to end; (4) the a1-param spill position pins where stratum-1 (declared locals/temps) ENDS — any dial that grows locals displaces it, which is exactly the dead[8] 2-off signature.