From 5ddf6255a13c5a23663ca49db2d038c6530cb7a1 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 6 Sep 2011 10:24:21 -0400 Subject: [PATCH] gc: unify stack frame layout allocparams + tempname + compactframe all knew about how to place stack variables. Now only compactframe, renamed to allocauto, does the work. Until the last minute, each PAUTO variable is in its own space and has xoffset == 0. This might break 5g. I get failures in concurrent code running under qemu and I can't tell whether it's 5g's fault or qemu's. We'll see what the real ARM builders say. R=ken2 CC=golang-dev https://golang.org/cl/4973057 --- src/cmd/5g/gsubr.c | 1 - src/cmd/5g/reg.c | 28 ++++++++--------- src/cmd/6g/gsubr.c | 1 - src/cmd/6g/reg.c | 35 +++++++++------------ src/cmd/8g/gsubr.c | 1 - src/cmd/8g/reg.c | 30 +++++++++--------- src/cmd/gc/bits.c | 4 +-- src/cmd/gc/dcl.c | 2 +- src/cmd/gc/gen.c | 78 ++++++---------------------------------------- src/cmd/gc/go.h | 3 -- src/cmd/gc/pgen.c | 13 ++++---- src/cmd/gc/subr.c | 3 -- 12 files changed, 62 insertions(+), 137 deletions(-) diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c index dc49e90cabd..f8920df87bb 100644 --- a/src/cmd/5g/gsubr.c +++ b/src/cmd/5g/gsubr.c @@ -1273,7 +1273,6 @@ naddr(Node *n, Addr *a, int canemitcode) a->etype = simtype[n->type->etype]; a->width = n->type->width; } - a->pun = n->pun; a->offset = n->xoffset; a->sym = n->sym; if(a->sym == S) diff --git a/src/cmd/5g/reg.c b/src/cmd/5g/reg.c index edec5933353..9dd3f07f17f 100644 --- a/src/cmd/5g/reg.c +++ b/src/cmd/5g/reg.c @@ -114,19 +114,19 @@ setaddrs(Bits bit) { int i, n; Var *v; - Sym *s; + Node *node; while(bany(&bit)) { // convert each bit to a variable i = bnum(bit); - s = var[i].sym; + node = var[i].node; n = var[i].name; bit.b[i/32] &= ~(1L<<(i%32)); // disable all pieces of that variable for(i=0; isym == s && v->name == n) + if(v->node == node && v->name == n) v->addr = 2; } } @@ -204,7 +204,7 @@ regopt(Prog *firstp) nvar = NREGVAR; memset(var, 0, NREGVAR*sizeof var[0]); for(i=0; ito; - a->sym = v->sym; a->name = v->name; a->node = v->node; + a->sym = v->node->sym; a->offset = v->offset; a->etype = v->etype; a->type = D_OREG; @@ -840,7 +840,7 @@ mkvar(Reg *r, Adr *a) int i, t, n, et, z, w, flag; int32 o; Bits bit; - Sym *s; + Node *node; // mark registers used t = a->type; @@ -910,10 +910,11 @@ mkvar(Reg *r, Adr *a) break; } - s = a->sym; - if(s == S) + node = a->node; + if(node == N || node->op != ONAME || node->orig != N) goto none; - if(s->name[0] == '.') + node = node->orig; + if(node->sym->name[0] == '.') goto none; et = a->etype; o = a->offset; @@ -921,7 +922,7 @@ mkvar(Reg *r, Adr *a) for(i=0; isym == s && v->name == n) { + if(v->node == node && v->name == n) { if(v->offset == o) if(v->etype == et) if(v->width == w) @@ -945,7 +946,7 @@ mkvar(Reg *r, Adr *a) } if(nvar >= NVAR) { - if(debug['w'] > 1 && s) + if(debug['w'] > 1 && node) fatal("variable not optimized: %D", a); goto none; } @@ -954,17 +955,16 @@ mkvar(Reg *r, Adr *a) nvar++; //print("var %d %E %D %S\n", i, et, a, s); v = var+i; - v->sym = s; v->offset = o; v->name = n; // v->gotype = a->gotype; v->etype = et; v->width = w; v->addr = flag; // funny punning - v->node = a->node; + v->node = node; if(debug['R']) - print("bit=%2d et=%2d w=%d+%d %S %D flag=%d\n", i, et, o, w, s, a, v->addr); + print("bit=%2d et=%2d w=%d+%d %#N %D flag=%d\n", i, et, o, w, node, a, v->addr); bit = blsh(i); if(n == D_EXTERN || n == D_STATIC) diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c index 7b7fa12a866..92b15ef00f7 100644 --- a/src/cmd/6g/gsubr.c +++ b/src/cmd/6g/gsubr.c @@ -1129,7 +1129,6 @@ naddr(Node *n, Addr *a, int canemitcode) a->width = n->type->width; a->gotype = ngotype(n); } - a->pun = n->pun; a->offset = n->xoffset; a->sym = n->sym; if(a->sym == S) diff --git a/src/cmd/6g/reg.c b/src/cmd/6g/reg.c index 72c4b387364..f380ced8cb4 100644 --- a/src/cmd/6g/reg.c +++ b/src/cmd/6g/reg.c @@ -98,19 +98,19 @@ setaddrs(Bits bit) { int i, n; Var *v; - Sym *s; + Node *node; while(bany(&bit)) { // convert each bit to a variable i = bnum(bit); - s = var[i].sym; + node = var[i].node; n = var[i].name; bit.b[i/32] &= ~(1L<<(i%32)); // disable all pieces of that variable for(i=0; isym == s && v->name == n) + if(v->node == node && v->name == n) v->addr = 2; } } @@ -188,7 +188,7 @@ regopt(Prog *firstp) nvar = NREGVAR; memset(var, 0, NREGVAR*sizeof var[0]); for(i=0; ito; - a->sym = v->sym; a->offset = v->offset; a->etype = v->etype; a->type = v->name; a->gotype = v->gotype; a->node = v->node; + a->sym = v->node->sym; // need to clean this up with wptr and // some of the defaults @@ -932,7 +932,7 @@ mkvar(Reg *r, Adr *a) uint32 regu; int32 o; Bits bit; - Sym *s; + Node *node; /* * mark registers used @@ -968,10 +968,11 @@ mkvar(Reg *r, Adr *a) n = t; break; } - s = a->sym; - if(s == S) + node = a->node; + if(node == N || node->op != ONAME || node->orig != N) goto none; - if(s->name[0] == '.') + node = node->orig; + if(node->sym->name[0] == '.') goto none; et = a->etype; o = a->offset; @@ -980,7 +981,7 @@ mkvar(Reg *r, Adr *a) flag = 0; for(i=0; isym == s && v->name == n) { + if(v->node == node && v->name == n) { if(v->offset == o) if(v->etype == et) if(v->width == w) @@ -994,11 +995,6 @@ mkvar(Reg *r, Adr *a) } } } - if(a->pun) { -// print("disable pun %s\n", s->name); - flag = 1; - - } switch(et) { case 0: case TFUNC: @@ -1006,25 +1002,24 @@ mkvar(Reg *r, Adr *a) } if(nvar >= NVAR) { - if(debug['w'] > 1 && s) - fatal("variable not optimized: %D", a); + if(debug['w'] > 1 && node != N) + fatal("variable not optimized: %#N", node); goto none; } i = nvar; nvar++; v = var+i; - v->sym = s; v->offset = o; v->name = n; v->gotype = a->gotype; v->etype = et; v->width = w; v->addr = flag; // funny punning - v->node = a->node; + v->node = node; if(debug['R']) - print("bit=%2d et=%2d w=%d %S %D\n", i, et, w, s, a); + print("bit=%2d et=%2d w=%d %#N %D\n", i, et, w, node, a); ostats.nvar++; bit = blsh(i); diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c index c44bd684d59..1aae34e3583 100644 --- a/src/cmd/8g/gsubr.c +++ b/src/cmd/8g/gsubr.c @@ -1838,7 +1838,6 @@ naddr(Node *n, Addr *a, int canemitcode) a->width = n->type->width; a->gotype = ngotype(n); } - a->pun = n->pun; a->offset = n->xoffset; a->sym = n->sym; if(a->sym == S) diff --git a/src/cmd/8g/reg.c b/src/cmd/8g/reg.c index 70640ab04b8..de5fd87ac8f 100644 --- a/src/cmd/8g/reg.c +++ b/src/cmd/8g/reg.c @@ -98,19 +98,19 @@ setaddrs(Bits bit) { int i, n; Var *v; - Sym *s; + Node *node; while(bany(&bit)) { // convert each bit to a variable i = bnum(bit); - s = var[i].sym; + node = var[i].node; n = var[i].name; bit.b[i/32] &= ~(1L<<(i%32)); // disable all pieces of that variable for(i=0; isym == s && v->name == n) + if(v->node == node && v->name == n) v->addr = 2; } } @@ -155,7 +155,7 @@ regopt(Prog *firstp) nvar = NREGVAR; memset(var, 0, NREGVAR*sizeof var[0]); for(i=0; ito; - a->sym = v->sym; a->offset = v->offset; a->etype = v->etype; a->type = v->name; a->gotype = v->gotype; a->node = v->node; + a->sym = v->node->sym; // need to clean this up with wptr and // some of the defaults @@ -810,7 +810,7 @@ mkvar(Reg *r, Adr *a) int i, t, n, et, z, w, flag, regu; int32 o; Bits bit; - Sym *s; + Node *node; /* * mark registers used @@ -847,10 +847,11 @@ mkvar(Reg *r, Adr *a) break; } - s = a->sym; - if(s == S) + node = a->node; + if(node == N || node->op != ONAME || node->orig != N) goto none; - if(s->name[0] == '.') + node = node->orig; + if(node->sym->name[0] == '.') goto none; et = a->etype; o = a->offset; @@ -859,7 +860,7 @@ mkvar(Reg *r, Adr *a) flag = 0; for(i=0; isym == s && v->name == n) { + if(v->node == node && v->name == n) { if(v->offset == o) if(v->etype == et) if(v->width == w) @@ -868,7 +869,7 @@ mkvar(Reg *r, Adr *a) // if they overlap, disable both if(overlap(v->offset, v->width, o, w)) { if(debug['R']) - print("disable %s\n", v->sym->name); + print("disable %s\n", node->sym->name); v->addr = 1; flag = 1; } @@ -882,7 +883,7 @@ mkvar(Reg *r, Adr *a) } if(nvar >= NVAR) { - if(debug['w'] > 1 && s) + if(debug['w'] > 1 && node != N) fatal("variable not optimized: %D", a); goto none; } @@ -890,17 +891,16 @@ mkvar(Reg *r, Adr *a) i = nvar; nvar++; v = var+i; - v->sym = s; v->offset = o; v->name = n; v->gotype = a->gotype; v->etype = et; v->width = w; v->addr = flag; // funny punning - v->node = a->node; + v->node = node; if(debug['R']) - print("bit=%2d et=%2d w=%d+%d %S %D flag=%d\n", i, et, o, w, s, a, v->addr); + print("bit=%2d et=%2d w=%d+%d %#N %D flag=%d\n", i, et, o, w, node, a, v->addr); ostats.nvar++; bit = blsh(i); diff --git a/src/cmd/gc/bits.c b/src/cmd/gc/bits.c index 2d102adbfc3..f3b031cc3ed 100644 --- a/src/cmd/gc/bits.c +++ b/src/cmd/gc/bits.c @@ -150,10 +150,10 @@ Qconv(Fmt *fp) first = 0; else fmtprint(fp, " "); - if(var[i].sym == S) + if(var[i].node == N || var[i].node->sym == S) fmtprint(fp, "$%lld", var[i].offset); else { - fmtprint(fp, var[i].sym->name); + fmtprint(fp, var[i].node->sym->name); if(var[i].offset != 0) fmtprint(fp, "%+lld", (vlong)var[i].offset); } diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 0ad696f46bb..d8b89b4f383 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -192,7 +192,7 @@ declare(Node *n, int ctxt) n->curfn = curfn; } if(ctxt == PAUTO) - n->xoffset = BADWIDTH; + n->xoffset = 0; if(s->block == block) redeclare(s, "in this block"); diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c index fa084235030..a818dbc195f 100644 --- a/src/cmd/gc/gen.c +++ b/src/cmd/gc/gen.c @@ -28,52 +28,6 @@ sysfunc(char *name) return n; } -void -allocparams(void) -{ - NodeList *l; - Node *n; - uint32 w; - Sym *s; - int lno; - - if(stksize < 0) - fatal("allocparams not during code generation"); - - /* - * allocate (set xoffset) the stack - * slots for all automatics. - * allocated starting at -w down. - */ - lno = lineno; - for(l=curfn->dcl; l; l=l->next) { - n = l->n; - if(n->op == ONAME && n->class == PHEAP-1) { - // heap address variable; finish the job - // started in addrescapes. - s = n->sym; - tempname(n, n->type); - n->sym = s; - } - if(n->op != ONAME || n->class != PAUTO) - continue; - if(n->xoffset != BADWIDTH) - continue; - if(n->type == T) - continue; - dowidth(n->type); - w = n->type->width; - if(w >= MAXWIDTH) - fatal("bad width"); - stksize += w; - stksize = rnd(stksize, n->type->align); - if(thechar == '5') - stksize = rnd(stksize, widthptr); - n->xoffset = -stksize; - } - lineno = lno; -} - /* * the address of n has been taken and might be used after * the current function returns. mark any local vars @@ -83,6 +37,8 @@ void addrescapes(Node *n) { char buf[100]; + Node *oldfn; + switch(n->op) { default: // probably a type error already. @@ -129,18 +85,17 @@ addrescapes(Node *n) n->xoffset = 0; // create stack variable to hold pointer to heap - n->heapaddr = nod(ONAME, N, N); - n->heapaddr->type = ptrto(n->type); + oldfn = curfn; + curfn = n->curfn; + n->heapaddr = temp(ptrto(n->type)); snprint(buf, sizeof buf, "&%S", n->sym); n->heapaddr->sym = lookup(buf); - n->heapaddr->class = PHEAP-1; // defer tempname to allocparams - n->heapaddr->ullman = 1; - n->curfn->dcl = list(n->curfn->dcl, n->heapaddr); + n->heapaddr->orig->sym = n->heapaddr->sym; if(!debug['s']) n->esc = EscHeap; if(debug['m']) print("%L: moved to heap: %hN\n", n->lineno, n); - + curfn = oldfn; break; } break; @@ -687,15 +642,12 @@ cgen_as(Node *nl, Node *nr) Type *tl; int iszer; - if(nl == N) - return; - if(debug['g']) { dump("cgen_as", nl); dump("cgen_as = ", nr); } - if(isblank(nl)) { + if(nl == N || isblank(nl)) { cgen_discard(nr); return; } @@ -837,10 +789,6 @@ tempname(Node *nn, Type *t) { Node *n; Sym *s; - uint32 w; - - if(stksize < 0) - fatal("tempname not during code generation"); if(curfn == N) fatal("no curfn for tempname"); @@ -866,15 +814,7 @@ tempname(Node *nn, Type *t) curfn->dcl = list(curfn->dcl, n); dowidth(t); - w = t->width; - stksize += w; - stksize = rnd(stksize, t->align); - if(thechar == '5') - stksize = rnd(stksize, widthptr); - n->xoffset = -stksize; - - // print("\ttmpname (%d): %N\n", stksize, n); - + n->xoffset = 0; *nn = *n; } diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 19c3b578418..4c543fc3955 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -264,7 +264,6 @@ struct Node uchar initorder; uchar used; uchar isddd; - uchar pun; // don't registerize variable ONAME uchar readonly; uchar implicit; // don't show in printout @@ -608,7 +607,6 @@ typedef struct Var Var; struct Var { vlong offset; - Sym* sym; Sym* gotype; Node* node; int width; @@ -981,7 +979,6 @@ Type* pkgtype(Sym *s); * gen.c */ void addrescapes(Node *n); -void allocparams(void); void cgen_as(Node *nl, Node *nr); void cgen_callmeth(Node *n, int proc); void clearlabels(void); diff --git a/src/cmd/gc/pgen.c b/src/cmd/gc/pgen.c index 53aa83b149c..d16481b6664 100644 --- a/src/cmd/gc/pgen.c +++ b/src/cmd/gc/pgen.c @@ -7,7 +7,7 @@ #include "gg.h" #include "opt.h" -static void compactframe(Prog* p); +static void allocauto(Prog* p); void compile(Node *fn) @@ -60,8 +60,6 @@ compile(Node *fn) if(nerrors != 0) goto ret; - allocparams(); - continpc = P; breakpc = P; @@ -115,9 +113,9 @@ compile(Node *fn) } oldstksize = stksize; - compactframe(ptxt); + allocauto(ptxt); if(0) - print("compactframe: %lld to %lld\n", oldstksize, (vlong)stksize); + print("allocauto: %lld to %lld\n", oldstksize, (vlong)stksize); defframe(ptxt); @@ -147,13 +145,13 @@ cmpstackvar(Node *a, Node *b) // TODO(lvd) find out where the PAUTO/OLITERAL nodes come from. static void -compactframe(Prog* ptxt) +allocauto(Prog* ptxt) { NodeList *ll; Node* n; vlong w; - if (stksize == 0) + if(curfn->dcl == nil) return; // Mark the PAUTO's unused. @@ -190,6 +188,7 @@ compactframe(Prog* ptxt) if (n->class != PAUTO || n->op != ONAME) continue; + dowidth(n->type); w = n->type->width; if(w >= MAXWIDTH || w < 0) fatal("bad width"); diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index a33dd2d1145..ae163b29a65 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -1156,9 +1156,6 @@ Jconv(Fmt *fp) if(n->implicit != 0) fmtprint(fp, " implicit(%d)", n->implicit); - if(!c && n->pun != 0) - fmtprint(fp, " pun(%d)", n->pun); - if(!c && n->used != 0) fmtprint(fp, " used(%d)", n->used); return 0;