cstage+test: route cgreturn @retscr through fixed-name SSoT (#15)
cgen.c's two ≤24B / tagged-widen return scratch allocations called
mklabel(c, "retscr"), bumping labelseq once per function with a
struct or tagged return. Wwstage's mirror uses the fixed `@retscr`
name through `c.retscroff` SSoT (post-#14 b401cce) and never
touches labelseq for the scratch alloc. Result: cstage's labelseq
runs 1 ahead of wwstage in every fn with a struct/tagged return,
so every subsequent ct_N / ce_N / end_N branch label diverged by
the same offset.
Class A byte-id drift, previously latent. Filed STATUS-3 #15 —
promoted to bootstrap-blocking once lib/strings's time.add-chain
and nested-if shapes compounded the cumulative skew past the
993/995 byte-id threshold. The label name was never emitted (it's
a hidden local-table key); only the labelseq side-effect mattered.
Polarity catalog: cstage OVER — extra mklabel per fn. Convergence
cstage → wwstage's fixed-name SSoT per rule 10 (wwstage's pattern
is the cleanup target; STATUS-3 #14 already enforced single-slot
@retscr on both stages, this commit aligns the *name source* too).
Site 2 (struct/tagged @retscr in cgreturn) is the actively-tripping
site that reproduces in the in-tree corpus (lib/strings's time.add
chain). Site 1 is preventive symmetry per rule 10 — its sentinel
flip is masked by pre-existing pre-existing #20/#21 struct-widen
offset latents, documented inline.
Filed follow-up (NOT in scope here): #26 graduate the other
hidden-name mklabel sites (tagscr, tagbase, argscr, idxscr) to
@-prefix SSoT. Same family but per-site allocations, structurally
bigger; belongs with STATUS-4 task #1 variant-widen consolidation
refactor.
Tests:
- 725_nested_if_labels pins cstage vs wwstage cmp -s byte-id on
a canonical struct-return row mirroring lib/time.add shape
(multi-arm if + struct {sec,nsec: i64} return). This row
actually exercises mklabel site 2; the prior worker draft used
a scalar-widen path that bypassed both mklabel sites.
97/97 ok. 995_self_rebuild stays green (ww2==ww3==ww4 byte-id).
This commit is contained in:
@@ -6531,9 +6531,21 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
||||
if (cg_retscr != 0) {
|
||||
scr = cg_retscr;
|
||||
} else {
|
||||
const char *scrn = mklabel(c, "retscr");
|
||||
scr = local_alloc(c, locals, scrn,
|
||||
sz, cg_frame);
|
||||
/* STATUS-3 #15: use the fixed
|
||||
* "@retscr" SSoT name (mirrors
|
||||
* wwstage's c.retscroff pattern in
|
||||
* selfhost/cmd/wcc/cgen.ww). Pre-
|
||||
* fix mklabel(c, "retscr") consumed
|
||||
* one labelseq counter slot per
|
||||
* function with a tagged return,
|
||||
* pushing every subsequent ct/ce/
|
||||
* else/end label 1 ahead of wwstage.
|
||||
* Site 1 sentinel masked by latent
|
||||
* struct-widen offset divergence
|
||||
* (STATUS-3 #20/#21); fix is
|
||||
* preventive symmetry per rule 10. */
|
||||
scr = local_alloc(c, locals,
|
||||
"@retscr", sz, cg_frame);
|
||||
cg_retscr = scr;
|
||||
}
|
||||
ins2(c, A_XORQ, areg(D_AX), areg(D_AX));
|
||||
@@ -6674,14 +6686,15 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
||||
|| n->lhs->kind == N_STRUCTLIT)) {
|
||||
int sz = (int)rt->size;
|
||||
/* Single-slot @retscr (#14): see tagged arm
|
||||
* above for rationale. */
|
||||
* above for rationale. STATUS-3 #15: fixed
|
||||
* "@retscr" name avoids bumping labelseq;
|
||||
* mirrors wwstage's c.retscroff SSoT. */
|
||||
int scr;
|
||||
if (cg_retscr != 0) {
|
||||
scr = cg_retscr;
|
||||
} else {
|
||||
const char *scrn = mklabel(c, "retscr");
|
||||
scr = local_alloc(c, locals, scrn, 24,
|
||||
cg_frame);
|
||||
scr = local_alloc(c, locals, "@retscr",
|
||||
24, cg_frame);
|
||||
cg_retscr = scr;
|
||||
}
|
||||
ins2(c, A_XORQ, areg(D_AX), areg(D_AX));
|
||||
|
||||
Reference in New Issue
Block a user