selfhost/cmd/wcc: inline N_INDEX elem tinfo at 3 tagged push/index sites (#60)
pushargsrev and cgindex re-derived an index element's type via
indexvaluetnode (a base->TPTR/SLICE/ARRAY .lhs AST walk). The checker
stamps the element type on the N_INDEX node itself (indexresult,
check.ww:1710; N_INDEX is in the asserttyped gate), so read n.type_
directly at the 3 sites that only need tagged-ness + element size/sign:
cgenutil pushargsrev L178/490: pass the N_INDEX arg to istaggedtype/
slotsize (arg.type_ is the element tinfo).
cgenexpr cgindex L726: esz = n.type_.size, signed = typeissigned(n.type_).
Polarity DOWN per rule 10: cstage has no indexvaluetnode -- it reads
base->type->sub->size directly (cmd/w6c/cgen.c:2070-2071, :3518). The new
path reads element natural size (tinfo.size == primsize: rune=4, u8=1,
str=16, slice=24), matching cstage; it also retires two latent elemsizeofc
divergences (elemsizeofc returned slotsize N*8 for *[N]i64 / 2D-array
elements where cstage uses sub->size=8) -- those shapes are absent from
self-compile, so byte-id stays green.
indexvaluetnode is NOT deleted: its remaining callers at cgenexpr
L3720/3729 feed cgwidentaggedstore -> resolvetagged -> resolvetype, still
node-keyed (nil for non-N_TNAME). Deleting it waits on the resolvetagged
-> tinfo migration (#11).
make test 133/133 (byte-id 990-997 green, independently re-confirmed on
quiescent tree).
This commit is contained in:
@@ -10615,13 +10615,15 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = {
|
||||
// Without this gate the widening scalar branch
|
||||
// hardcodes the param's first-variant tag and
|
||||
// the callee reads a fixed arm on garbage.
|
||||
// #60: arg.type_ is the checker-stamped element
|
||||
// tinfo (check.ww indexresult); istaggedtype/
|
||||
// slotsize read .type_, so feed the N_INDEX node
|
||||
// directly. cstage reads the element via
|
||||
// base->type->sub (cmd/w6c/cgen.c:3518).
|
||||
if (arg.kind == nkind.N_INDEX) {
|
||||
let etn: *node = indexvaluetnode(c, arg);
|
||||
if (etn != nil) {
|
||||
if (istaggedtype(c, etn)) {
|
||||
if (slotsize(c, etn) == slotsize(c, ptype)) {
|
||||
aistagged = true;
|
||||
};
|
||||
if (istaggedtype(c, arg)) {
|
||||
if (slotsize(c, arg) == slotsize(c, ptype)) {
|
||||
aistagged = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -10926,18 +10928,18 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = {
|
||||
};
|
||||
// #12: N_INDEX of a sum-typed slice element. cgindex above left
|
||||
// the tagged-CALL ABI in AX/DX/CX/R8; the bare PUSHQ AX below
|
||||
// would only carry the tag word and drop the payload.
|
||||
// would only carry the tag word and drop the payload. #60:
|
||||
// arg.type_ is the element tinfo (istaggedtype/slotsize read
|
||||
// .type_) — feed the N_INDEX node directly, dropping the
|
||||
// indexvaluetnode walk.
|
||||
if (arg.kind == nkind.N_INDEX) {
|
||||
let etn: *node = indexvaluetnode(c, arg);
|
||||
if (etn != nil) {
|
||||
if (istaggedtype(c, etn)) {
|
||||
let isz: i32 = slotsize(c, etn);
|
||||
if (isz > 24) { emitline("\tPUSHQ\tR8\n"); };
|
||||
if (isz > 16) { emitline("\tPUSHQ\tCX\n"); };
|
||||
if (isz > 8) { emitline("\tPUSHQ\tDX\n"); };
|
||||
emitline("\tPUSHQ\tAX\n");
|
||||
return rest + isz / 8;
|
||||
};
|
||||
if (istaggedtype(c, arg)) {
|
||||
let isz: i32 = slotsize(c, arg);
|
||||
if (isz > 24) { emitline("\tPUSHQ\tR8\n"); };
|
||||
if (isz > 16) { emitline("\tPUSHQ\tCX\n"); };
|
||||
if (isz > 8) { emitline("\tPUSHQ\tDX\n"); };
|
||||
emitline("\tPUSHQ\tAX\n");
|
||||
return rest + isz / 8;
|
||||
};
|
||||
};
|
||||
emitline("\tPUSHQ\tAX\n");
|
||||
@@ -14608,10 +14610,15 @@ fn cgindex(c: *cgen, n: *node) void = {
|
||||
} else { if (base.kind == nkind.N_DOT) {
|
||||
esz = indexbaseesz(c, base);
|
||||
} else { if (base.kind == nkind.N_INDEX) {
|
||||
let bt: *node = indexvaluetnode(c, base);
|
||||
if (bt != nil) {
|
||||
esz = elemsizeofc(c, bt);
|
||||
signed_elem = elemissignedc(c, bt);
|
||||
// #60: chained `names[i][k]` — n.type_ is the checker-
|
||||
// stamped outer element tinfo (indexresult over the inner
|
||||
// index's value type). cstage reads base->type->sub->size
|
||||
// for esz (cmd/w6c/cgen.c:2070-2071). Drops the
|
||||
// indexvaluetnode walk.
|
||||
let et: *tinfo = n.type_: *tinfo;
|
||||
if (et != nil) {
|
||||
esz = et.size: i32;
|
||||
signed_elem = typeissigned(et);
|
||||
};
|
||||
};};};
|
||||
};
|
||||
|
||||
@@ -723,10 +723,15 @@ fn cgindex(c: *cgen, n: *node) void = {
|
||||
} else { if (base.kind == nkind.N_DOT) {
|
||||
esz = indexbaseesz(c, base);
|
||||
} else { if (base.kind == nkind.N_INDEX) {
|
||||
let bt: *node = indexvaluetnode(c, base);
|
||||
if (bt != nil) {
|
||||
esz = elemsizeofc(c, bt);
|
||||
signed_elem = elemissignedc(c, bt);
|
||||
// #60: chained `names[i][k]` — n.type_ is the checker-
|
||||
// stamped outer element tinfo (indexresult over the inner
|
||||
// index's value type). cstage reads base->type->sub->size
|
||||
// for esz (cmd/w6c/cgen.c:2070-2071). Drops the
|
||||
// indexvaluetnode walk.
|
||||
let et: *tinfo = n.type_: *tinfo;
|
||||
if (et != nil) {
|
||||
esz = et.size: i32;
|
||||
signed_elem = typeissigned(et);
|
||||
};
|
||||
};};};
|
||||
};
|
||||
|
||||
@@ -174,13 +174,15 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = {
|
||||
// Without this gate the widening scalar branch
|
||||
// hardcodes the param's first-variant tag and
|
||||
// the callee reads a fixed arm on garbage.
|
||||
// #60: arg.type_ is the checker-stamped element
|
||||
// tinfo (check.ww indexresult); istaggedtype/
|
||||
// slotsize read .type_, so feed the N_INDEX node
|
||||
// directly. cstage reads the element via
|
||||
// base->type->sub (cmd/w6c/cgen.c:3518).
|
||||
if (arg.kind == nkind.N_INDEX) {
|
||||
let etn: *node = indexvaluetnode(c, arg);
|
||||
if (etn != nil) {
|
||||
if (istaggedtype(c, etn)) {
|
||||
if (slotsize(c, etn) == slotsize(c, ptype)) {
|
||||
aistagged = true;
|
||||
};
|
||||
if (istaggedtype(c, arg)) {
|
||||
if (slotsize(c, arg) == slotsize(c, ptype)) {
|
||||
aistagged = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -485,18 +487,18 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = {
|
||||
};
|
||||
// #12: N_INDEX of a sum-typed slice element. cgindex above left
|
||||
// the tagged-CALL ABI in AX/DX/CX/R8; the bare PUSHQ AX below
|
||||
// would only carry the tag word and drop the payload.
|
||||
// would only carry the tag word and drop the payload. #60:
|
||||
// arg.type_ is the element tinfo (istaggedtype/slotsize read
|
||||
// .type_) — feed the N_INDEX node directly, dropping the
|
||||
// indexvaluetnode walk.
|
||||
if (arg.kind == nkind.N_INDEX) {
|
||||
let etn: *node = indexvaluetnode(c, arg);
|
||||
if (etn != nil) {
|
||||
if (istaggedtype(c, etn)) {
|
||||
let isz: i32 = slotsize(c, etn);
|
||||
if (isz > 24) { emitline("\tPUSHQ\tR8\n"); };
|
||||
if (isz > 16) { emitline("\tPUSHQ\tCX\n"); };
|
||||
if (isz > 8) { emitline("\tPUSHQ\tDX\n"); };
|
||||
emitline("\tPUSHQ\tAX\n");
|
||||
return rest + isz / 8;
|
||||
};
|
||||
if (istaggedtype(c, arg)) {
|
||||
let isz: i32 = slotsize(c, arg);
|
||||
if (isz > 24) { emitline("\tPUSHQ\tR8\n"); };
|
||||
if (isz > 16) { emitline("\tPUSHQ\tCX\n"); };
|
||||
if (isz > 8) { emitline("\tPUSHQ\tDX\n"); };
|
||||
emitline("\tPUSHQ\tAX\n");
|
||||
return rest + isz / 8;
|
||||
};
|
||||
};
|
||||
emitline("\tPUSHQ\tAX\n");
|
||||
|
||||
@@ -10615,13 +10615,15 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = {
|
||||
// Without this gate the widening scalar branch
|
||||
// hardcodes the param's first-variant tag and
|
||||
// the callee reads a fixed arm on garbage.
|
||||
// #60: arg.type_ is the checker-stamped element
|
||||
// tinfo (check.ww indexresult); istaggedtype/
|
||||
// slotsize read .type_, so feed the N_INDEX node
|
||||
// directly. cstage reads the element via
|
||||
// base->type->sub (cmd/w6c/cgen.c:3518).
|
||||
if (arg.kind == nkind.N_INDEX) {
|
||||
let etn: *node = indexvaluetnode(c, arg);
|
||||
if (etn != nil) {
|
||||
if (istaggedtype(c, etn)) {
|
||||
if (slotsize(c, etn) == slotsize(c, ptype)) {
|
||||
aistagged = true;
|
||||
};
|
||||
if (istaggedtype(c, arg)) {
|
||||
if (slotsize(c, arg) == slotsize(c, ptype)) {
|
||||
aistagged = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -10926,18 +10928,18 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = {
|
||||
};
|
||||
// #12: N_INDEX of a sum-typed slice element. cgindex above left
|
||||
// the tagged-CALL ABI in AX/DX/CX/R8; the bare PUSHQ AX below
|
||||
// would only carry the tag word and drop the payload.
|
||||
// would only carry the tag word and drop the payload. #60:
|
||||
// arg.type_ is the element tinfo (istaggedtype/slotsize read
|
||||
// .type_) — feed the N_INDEX node directly, dropping the
|
||||
// indexvaluetnode walk.
|
||||
if (arg.kind == nkind.N_INDEX) {
|
||||
let etn: *node = indexvaluetnode(c, arg);
|
||||
if (etn != nil) {
|
||||
if (istaggedtype(c, etn)) {
|
||||
let isz: i32 = slotsize(c, etn);
|
||||
if (isz > 24) { emitline("\tPUSHQ\tR8\n"); };
|
||||
if (isz > 16) { emitline("\tPUSHQ\tCX\n"); };
|
||||
if (isz > 8) { emitline("\tPUSHQ\tDX\n"); };
|
||||
emitline("\tPUSHQ\tAX\n");
|
||||
return rest + isz / 8;
|
||||
};
|
||||
if (istaggedtype(c, arg)) {
|
||||
let isz: i32 = slotsize(c, arg);
|
||||
if (isz > 24) { emitline("\tPUSHQ\tR8\n"); };
|
||||
if (isz > 16) { emitline("\tPUSHQ\tCX\n"); };
|
||||
if (isz > 8) { emitline("\tPUSHQ\tDX\n"); };
|
||||
emitline("\tPUSHQ\tAX\n");
|
||||
return rest + isz / 8;
|
||||
};
|
||||
};
|
||||
emitline("\tPUSHQ\tAX\n");
|
||||
@@ -14608,10 +14610,15 @@ fn cgindex(c: *cgen, n: *node) void = {
|
||||
} else { if (base.kind == nkind.N_DOT) {
|
||||
esz = indexbaseesz(c, base);
|
||||
} else { if (base.kind == nkind.N_INDEX) {
|
||||
let bt: *node = indexvaluetnode(c, base);
|
||||
if (bt != nil) {
|
||||
esz = elemsizeofc(c, bt);
|
||||
signed_elem = elemissignedc(c, bt);
|
||||
// #60: chained `names[i][k]` — n.type_ is the checker-
|
||||
// stamped outer element tinfo (indexresult over the inner
|
||||
// index's value type). cstage reads base->type->sub->size
|
||||
// for esz (cmd/w6c/cgen.c:2070-2071). Drops the
|
||||
// indexvaluetnode walk.
|
||||
let et: *tinfo = n.type_: *tinfo;
|
||||
if (et != nil) {
|
||||
esz = et.size: i32;
|
||||
signed_elem = typeissigned(et);
|
||||
};
|
||||
};};};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user