Commit b91a043d authored by Ken Thompson's avatar Ken Thompson

static initialization of slices

R=r
OCL=29016
CL=29016
parent 760b7784
......@@ -701,8 +701,6 @@ clearfat(Node *nl)
int
getlit(Node *lit)
{
int l;
if(smallintconst(lit))
return mpgetfix(lit->val.u.xval);
return -1;
......@@ -748,7 +746,7 @@ no:
int
gen_as_init(Node *nr, Node *nl)
{
Node nam;
Node nam, nod1;
Prog *p;
if(!initflag)
......@@ -762,6 +760,32 @@ gen_as_init(Node *nr, Node *nl)
return 1;
}
if(nr->op == OCOMPSLICE) {
// create a slice pointing to an array
if(!stataddr(&nam, nl)) {
dump("stataddr", nl);
goto no;
}
p = gins(ADATA, &nam, nr->left);
p->from.scale = types[tptr]->width;
p->to.index = p->to.type;
p->to.type = D_ADDR;
//print("%P\n", p);
nodconst(&nod1, types[TINT32], nr->left->type->bound);
p = gins(ADATA, &nam, &nod1);
p->from.scale = types[TINT32]->width;
p->from.offset += types[tptr]->width;
//print("%P\n", p);
p = gins(ADATA, &nam, &nod1);
p->from.scale = types[TINT32]->width;
p->from.offset += types[tptr]->width+types[TINT32]->width;
goto yes;
}
if(nr->type == T ||
!eqtype(nl->type, nr->type))
goto no;
......
......@@ -1360,7 +1360,7 @@ initlin(Node* n)
n->right->right->op != OLIST ||
n->right->right->left->op != OAS ||
n->right->right->right->op != OAS ||
memcmp(n->left->sym->name, "mapassign1", 10) != 0)
strcmp(n->left->sym->name, "mapassign1") != 0)
dump("o=call", n);
n->ninit = N;
xxx = list(xxx, n);
......@@ -1385,7 +1385,7 @@ inittmp(Node *n)
if(n->op == ONAME)
if(n->sym != S)
if(n->class == PAUTO)
if(memcmp(n->sym->name, "!tmpname", 8) == 0)
if(strcmp(n->sym->name, "!tmpname!") == 0)
return 1;
return 0;
}
......@@ -1409,12 +1409,59 @@ indsametmp(Node *n1, Node *n2)
return 0;
}
Node*
slicerewrite(Node *n)
{
Iter param;
Node *a, *wid, *nel;
Type *t;
int b;
if(n == N || n->op != OCALL || !isslice(n->type) ||
n->left == N || n->left->sym == S ||
strcmp(n->left->sym->name, "newarray") != 0)
goto no;
// call to newarray - find width and nel
wid = N;
nel = N;
a = listfirst(&param, &n->right);
while(a != N) {
if(a->op == OAS &&
a->left != N && a->right != N &&
a->left->op == OINDREG && a->right->op == OLITERAL &&
a->left->sym != S) {
if(strcmp(a->left->sym->name, "nel") == 0)
nel = a->right;
if(strcmp(a->left->sym->name, "width") == 0)
wid = a->right;
}
a = listnext(&param);
}
if(wid == N || nel == N)
goto no;
b = mpgetfix(nel->val.u.xval);
if(b == 0)
goto no;
t = shallow(n->type);
t->bound = b;
a = staticname(t);
a = nod(OCOMPSLICE, a, N);
a->type = n->type;
return a;
no:
return N;
}
int
initsub(Node *n, Node *nam)
{
Iter iter;
Node *r;
int any, i;
Iter iter, param;
Node *r, *w;
int any;
any = 0;
r = listfirst(&iter, &xxx);
......@@ -1427,7 +1474,13 @@ initsub(Node *n, Node *nam)
case ONAME:
if(sametmp(r->left, nam)) {
any = 1;
w = slicerewrite(r->right);
r->left = n;
if(w != N) {
n = w->left; // from now on use fixed array
r->right = w;
break;
}
}
break;
case ODOT:
......@@ -1454,27 +1507,18 @@ initsub(Node *n, Node *nam)
break;
case OCALL:
// call to mapassign1
// look through all three parameters
for(i=0; i<2; i++) {
r = r->right;
if(r == N || r->op != OLIST)
break;
if(sametmp(r->left->right, nam)) {
any = 1;
r->left->right = n;
}
if(indsametmp(r->left->right, nam)) {
any = 1;
r->left->left->right = n;
}
if(sametmp(r->right->right, nam)) {
// look through the parameters
w = listfirst(&param, &r->right);
while(w != N) {
if(sametmp(w->right, nam)) {
any = 1;
r->right->right = n;
w->right = n;
}
if(indsametmp(r->right->right, nam)) {
if(indsametmp(w->right, nam)) {
any = 1;
r->right->left->right = n;
w->right->left = n;
}
w = listnext(&param);
}
break;
}
......
......@@ -325,7 +325,7 @@ enum
ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV,
OLITERAL, OREGISTER, OINDREG,
OKEY, OPARAM,
OCOMPOS,
OCOMPOS, OCOMPSLICE, OCOMPMAP,
OCONV,
ODOTTYPE, OTYPESW,
OBAD,
......@@ -565,10 +565,11 @@ EXTERN Dcl* externdcl;
EXTERN Dcl* exportlist;
EXTERN Dcl* signatlist;
EXTERN Dcl* typelist;
EXTERN int dclcontext; // PEXTERN/PAUTO
EXTERN int dclcontext; // PEXTERN/PAUTO
EXTERN int importflag;
EXTERN int inimportsys;
EXTERN int initflag; // compiling the init fn
EXTERN int statuniqgen; // name generator for static temps
EXTERN uint32 iota;
EXTERN Node* lastconst;
......@@ -748,6 +749,7 @@ Node* syslook(char*, int);
Node* treecopy(Node*);
int isselect(Node*);
void tempname(Node*, Type*);
Node* staticname(Type*);
int iscomposite(Type*);
Node* callnew(Type*);
......
......@@ -666,6 +666,8 @@ opnames[] =
[OCMP] = "CMP",
[OFALL] = "FALL",
[OCOMPOS] = "COMPOS",
[OCOMPSLICE] = "COMPSLICE",
[OCOMPMAP] = "COMPMAP",
[ODOTTYPE] = "DOTTYPE",
[OCONV] = "CONV",
[OCOM] = "COM",
......@@ -2389,6 +2391,18 @@ tempname(Node *n, Type *t)
n->xoffset = -stksize;
}
Node*
staticname(Type *t)
{
Node *n;
snprint(namebuf, sizeof(namebuf), "statictmp_%.4d·%s", statuniqgen, filename);
statuniqgen++;
n = newname(lookup(namebuf));
addvar(n, t, PEXTERN);
return n;
}
void
setmaxarg(Type *t)
{
......
......@@ -581,6 +581,10 @@ loop:
walkconv(n);
goto ret;
case OCOMPMAP:
case OCOMPSLICE:
goto ret;
case OCOMPOS:
t = n->type;
if(t == T)
......
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