1.8 KiB
§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
sdies atmax(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
registerdeclaration 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.