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) ...@@ -701,8 +701,6 @@ clearfat(Node *nl)
int int
getlit(Node *lit) getlit(Node *lit)
{ {
int l;
if(smallintconst(lit)) if(smallintconst(lit))
return mpgetfix(lit->val.u.xval); return mpgetfix(lit->val.u.xval);
return -1; return -1;
...@@ -748,7 +746,7 @@ no: ...@@ -748,7 +746,7 @@ no:
int int
gen_as_init(Node *nr, Node *nl) gen_as_init(Node *nr, Node *nl)
{ {
Node nam; Node nam, nod1;
Prog *p; Prog *p;
if(!initflag) if(!initflag)
...@@ -762,6 +760,32 @@ gen_as_init(Node *nr, Node *nl) ...@@ -762,6 +760,32 @@ gen_as_init(Node *nr, Node *nl)
return 1; 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 || if(nr->type == T ||
!eqtype(nl->type, nr->type)) !eqtype(nl->type, nr->type))
goto no; goto no;
......
...@@ -1360,7 +1360,7 @@ initlin(Node* n) ...@@ -1360,7 +1360,7 @@ initlin(Node* n)
n->right->right->op != OLIST || n->right->right->op != OLIST ||
n->right->right->left->op != OAS || n->right->right->left->op != OAS ||
n->right->right->right->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); dump("o=call", n);
n->ninit = N; n->ninit = N;
xxx = list(xxx, n); xxx = list(xxx, n);
...@@ -1385,7 +1385,7 @@ inittmp(Node *n) ...@@ -1385,7 +1385,7 @@ inittmp(Node *n)
if(n->op == ONAME) if(n->op == ONAME)
if(n->sym != S) if(n->sym != S)
if(n->class == PAUTO) if(n->class == PAUTO)
if(memcmp(n->sym->name, "!tmpname", 8) == 0) if(strcmp(n->sym->name, "!tmpname!") == 0)
return 1; return 1;
return 0; return 0;
} }
...@@ -1409,12 +1409,59 @@ indsametmp(Node *n1, Node *n2) ...@@ -1409,12 +1409,59 @@ indsametmp(Node *n1, Node *n2)
return 0; 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 int
initsub(Node *n, Node *nam) initsub(Node *n, Node *nam)
{ {
Iter iter; Iter iter, param;
Node *r; Node *r, *w;
int any, i; int any;
any = 0; any = 0;
r = listfirst(&iter, &xxx); r = listfirst(&iter, &xxx);
...@@ -1427,7 +1474,13 @@ initsub(Node *n, Node *nam) ...@@ -1427,7 +1474,13 @@ initsub(Node *n, Node *nam)
case ONAME: case ONAME:
if(sametmp(r->left, nam)) { if(sametmp(r->left, nam)) {
any = 1; any = 1;
w = slicerewrite(r->right);
r->left = n; r->left = n;
if(w != N) {
n = w->left; // from now on use fixed array
r->right = w;
break;
}
} }
break; break;
case ODOT: case ODOT:
...@@ -1454,27 +1507,18 @@ initsub(Node *n, Node *nam) ...@@ -1454,27 +1507,18 @@ initsub(Node *n, Node *nam)
break; break;
case OCALL: case OCALL:
// call to mapassign1 // call to mapassign1
// look through all three parameters // look through the parameters
for(i=0; i<2; i++) { w = listfirst(&param, &r->right);
r = r->right; while(w != N) {
if(r == N || r->op != OLIST) if(sametmp(w->right, nam)) {
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)) {
any = 1; any = 1;
r->right->right = n; w->right = n;
} }
if(indsametmp(r->right->right, nam)) { if(indsametmp(w->right, nam)) {
any = 1; any = 1;
r->right->left->right = n; w->right->left = n;
} }
w = listnext(&param);
} }
break; break;
} }
......
...@@ -325,7 +325,7 @@ enum ...@@ -325,7 +325,7 @@ enum
ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV, ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV,
OLITERAL, OREGISTER, OINDREG, OLITERAL, OREGISTER, OINDREG,
OKEY, OPARAM, OKEY, OPARAM,
OCOMPOS, OCOMPOS, OCOMPSLICE, OCOMPMAP,
OCONV, OCONV,
ODOTTYPE, OTYPESW, ODOTTYPE, OTYPESW,
OBAD, OBAD,
...@@ -569,6 +569,7 @@ EXTERN int dclcontext; // PEXTERN/PAUTO ...@@ -569,6 +569,7 @@ EXTERN int dclcontext; // PEXTERN/PAUTO
EXTERN int importflag; EXTERN int importflag;
EXTERN int inimportsys; EXTERN int inimportsys;
EXTERN int initflag; // compiling the init fn EXTERN int initflag; // compiling the init fn
EXTERN int statuniqgen; // name generator for static temps
EXTERN uint32 iota; EXTERN uint32 iota;
EXTERN Node* lastconst; EXTERN Node* lastconst;
...@@ -748,6 +749,7 @@ Node* syslook(char*, int); ...@@ -748,6 +749,7 @@ Node* syslook(char*, int);
Node* treecopy(Node*); Node* treecopy(Node*);
int isselect(Node*); int isselect(Node*);
void tempname(Node*, Type*); void tempname(Node*, Type*);
Node* staticname(Type*);
int iscomposite(Type*); int iscomposite(Type*);
Node* callnew(Type*); Node* callnew(Type*);
......
...@@ -666,6 +666,8 @@ opnames[] = ...@@ -666,6 +666,8 @@ opnames[] =
[OCMP] = "CMP", [OCMP] = "CMP",
[OFALL] = "FALL", [OFALL] = "FALL",
[OCOMPOS] = "COMPOS", [OCOMPOS] = "COMPOS",
[OCOMPSLICE] = "COMPSLICE",
[OCOMPMAP] = "COMPMAP",
[ODOTTYPE] = "DOTTYPE", [ODOTTYPE] = "DOTTYPE",
[OCONV] = "CONV", [OCONV] = "CONV",
[OCOM] = "COM", [OCOM] = "COM",
...@@ -2389,6 +2391,18 @@ tempname(Node *n, Type *t) ...@@ -2389,6 +2391,18 @@ tempname(Node *n, Type *t)
n->xoffset = -stksize; 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 void
setmaxarg(Type *t) setmaxarg(Type *t)
{ {
......
...@@ -581,6 +581,10 @@ loop: ...@@ -581,6 +581,10 @@ loop:
walkconv(n); walkconv(n);
goto ret; goto ret;
case OCOMPMAP:
case OCOMPSLICE:
goto ret;
case OCOMPOS: case OCOMPOS:
t = n->type; t = n->type;
if(t == T) 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