Commit 5ddf6255 authored by Russ Cox's avatar Russ Cox

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
parent 37f390aa
......@@ -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)
......
......@@ -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; i<nvar; i++) {
v = var+i;
if(v->sym == 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; i<NREGVAR; i++)
var[i].sym = lookup(regname[i]);
var[i].node = newname(lookup(regname[i]));
regbits = RtoB(REGSP)|RtoB(REGLINK)|RtoB(REGPC);
for(z=0; z<BITS; z++) {
......@@ -752,9 +752,9 @@ addmove(Reg *r, int bn, int rn, int f)
v = var + bn;
a = &p1->to;
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; i<nvar; i++) {
v = var+i;
if(v->sym == 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)
......
......@@ -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)
......
......@@ -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; i<nvar; i++) {
v = var+i;
if(v->sym == 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; i<NREGVAR; i++)
var[i].sym = lookup(regname[i]);
var[i].node = newname(lookup(regname[i]));
regbits = RtoB(D_SP);
for(z=0; z<BITS; z++) {
......@@ -831,12 +831,12 @@ addmove(Reg *r, int bn, int rn, int f)
v = var + bn;
a = &p1->to;
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; i<nvar; i++) {
v = var+i;
if(v->sym == 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);
......
......@@ -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)
......
......@@ -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; i<nvar; i++) {
v = var+i;
if(v->sym == 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; i<NREGVAR; i++)
var[i].sym = lookup(regname[i]);
var[i].node = newname(lookup(regname[i]));
regbits = RtoB(D_SP);
for(z=0; z<BITS; z++) {
......@@ -725,12 +725,12 @@ addmove(Reg *r, int bn, int rn, int f)
v = var + bn;
a = &p1->to;
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; i<nvar; i++) {
v = var+i;
if(v->sym == 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);
......
......@@ -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);
}
......
......@@ -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");
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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");
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment