Files
BFM-decomp/cookbook/C0429.md
T

1.8 KiB
Raw Blame History

§388 ★★★ — THE -O0 COLOURING ORACLE: simulate stupid.c instead of grinding spellings (P31 S69; main/func_80011380 proved a C-level WALL at 6)

At -O0 gcc-2.7.2 allocates with stupid.c, not local/global-alloc. It is simple enough to simulate exactly, so predict the colours instead of guessing at spellings:

  • every insn including NOTES gets a sequential suid;
  • a pseudo set at suid s dies at max(last_use, s+2) and occupies [born, dead-1];
  • pseudos are allocated longest-first, then fewer-refs-first, then lowest regno, first-fit $v0,$v1,$a0,$a1,…;
  • a register declaration emits a zero-byte head-(use) insn making that var ONE convex interval.

Two consequences you can diagnose by inspection. (1) An -O0 copy;sll multiply chain 2-colours ping-pong because the +2 rule makes each link conflict with the next — so a NOTE inside the chain (any statement-expression's BLOCK_BEG/BLOCK_END) lapses the slack, one copy becomes a same-register move, and final.c deletes it: a length −1 next to a ({...}) is THIS, not scheduling. (2) A register decl recolours the whole chain via its head-use interval, so exact-length REGALLOC rotations in -O0 code are decl-lifetime artifacts. cc1 -dr suid arithmetic predicts the colours before you compile.

Also from the same run — the SYMBOL-ADDEND SHIELD. In a pointer index, (s32)(idx + K): the same-mode cast hides the PLUS from pointer_int_sum's distributive rewrite, yet EXPAND_SUM still absorbs K into the relocation, emitting la SYM+K*size with the scale applied to idx alone. Use it when the target shows a symbol+constant base feeding a scaled index — no plain spelling reproduces it, because the frontend otherwise distributes K into the pointer before scaling.