phase11: merge 60 + cookbook 181-182 — 601 bodies / 610 regions
Worker F's 0x8002622C (44 B) — A RECORDED NEGATIVE OVERTURNED, with a new class. The old record said 'cc1 folds it, unreachable' and tried FOUR ALGEBRAIC re-spellings. All four were doomed: the fold is at RTL combine, not in the front end, so no re-spelling can avoid it. Only LIVENESS can. Same body with 'return 0' is 32 B LENGTH-MISMATCH; with 'return n' (the difference live past the addition) it is 44/0/MATCH. Diagnostic that proves the pass: cc1 -da shows the minus present in the .flow dump and gone in the .combine dump, while cse/cse2/jump/ loop/sched/sched2 all still contain it. 181: when an original keeps an arithmetically-cancelling pair (subu+addu, x-c+c), the intermediate is LIVE PAST the second operation — find the later reader. 182: a negative with a NAMED mechanism is overturnable; one without is not. 'cc1 folds it' is not a classification; 'RTL combine cancels it, and algebraic re-spelling cannot reach combine' is, and it immediately implies the liveness lever.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* func_8002622C — 44 bytes at 0x8002622C..0x80026258
|
||||
*
|
||||
* Initialises the four `gp`-relative arena globals from the arena base passed in
|
||||
* `a0`, and returns the arena's distance from the fixed data address D_8015E978.
|
||||
*
|
||||
* The observed instructions are:
|
||||
* move v0,a0 n = a0 (n cannot coalesce with a0)
|
||||
* lui v1,0x8016 \
|
||||
* addiu v1,v1,-5768 / v1 = D_8015E978 (a SYMBOL: `la`, not `li`)
|
||||
* sw v0,488(gp) D_80121B20 = n
|
||||
* subu v0,v0,v1 n = n - D_8015E978
|
||||
* sw v1,476(gp) D_80121B14 = D_8015E978
|
||||
* addu v1,v0,v1 x = n + D_8015E978
|
||||
* sw v1,480(gp) D_80121B18 = x
|
||||
* sw v1,484(gp) D_80121B1C = x
|
||||
* jr ra return n;
|
||||
*
|
||||
* THE `subu`/`addu` PAIR IS KEPT ONLY BECAUSE THE DIFFERENCE IS RETURNED.
|
||||
* `(a0 - K) + K` is cancelled by combine's dead-register substitution, and this
|
||||
* row is on the recorded-negative list (`config/near_match_negatives.tsv` line
|
||||
* 47) for exactly that reason. The lever that was missing is LIVENESS, not
|
||||
* algebra: if the difference's live range ends at the addition, combine
|
||||
* substitutes its definition and folds the pair away (probe H3, `return 0;`,
|
||||
* 32 B), while keeping it alive past the addition — here by returning it —
|
||||
* blocks the substitution and reproduces the original 44 B. Diagnostic: with
|
||||
* cc1 `-da` the `minus` is present in the `.flow` dump and gone in `.combine`.
|
||||
* The fold is at the RTL level (combine), NOT in the front end, so no
|
||||
* algebraic re-spelling of the source can avoid it — only liveness can.
|
||||
*
|
||||
* The `move v0,a0` is the source's `n = a0`: `a0` stays live (it is stored to
|
||||
* D_80121B20), so the copy cannot coalesce, and `n`'s home is the return
|
||||
* register v0.
|
||||
*
|
||||
* D_8015E978 MUST be a symbol reference: written as a literal the address
|
||||
* materialises as `lui`+`ori` instead of `lui`+`addiu`. The four globals are
|
||||
* registered `gp` in `config/symbols.tsv`, giving the `%gp_rel` stores.
|
||||
*
|
||||
* LIMITS: the name, the return type, the widths of the four globals and the
|
||||
* meaning of the difference are hypotheses reconstructed from the disassembly;
|
||||
* only the compiled bytes are evidence.
|
||||
*/
|
||||
|
||||
extern int D_80121B14;
|
||||
extern int D_80121B18;
|
||||
extern int D_80121B1C;
|
||||
extern int D_80121B20;
|
||||
extern char D_8015E978[];
|
||||
|
||||
int func_8002622C(int a0) {
|
||||
int n = a0;
|
||||
|
||||
D_80121B20 = n;
|
||||
D_80121B14 = (int)D_8015E978;
|
||||
n = n - (int)D_8015E978;
|
||||
D_80121B18 = n + (int)D_8015E978;
|
||||
D_80121B1C = n + (int)D_8015E978;
|
||||
return n;
|
||||
}
|
||||
Reference in New Issue
Block a user