From b91a043d024ae027397abc1bca3fb7f7bb206861 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Mon, 18 May 2009 22:11:22 -0700 Subject: [PATCH] static initialization of slices R=r OCL=29016 CL=29016 --- src/cmd/6g/gen.c | 30 ++++++++++++++-- src/cmd/gc/dcl.c | 88 +++++++++++++++++++++++++++++++++++------------ src/cmd/gc/go.h | 6 ++-- src/cmd/gc/subr.c | 14 ++++++++ src/cmd/gc/walk.c | 4 +++ 5 files changed, 115 insertions(+), 27 deletions(-) diff --git a/src/cmd/6g/gen.c b/src/cmd/6g/gen.c index 598128f2e6..55eb43a618 100644 --- a/src/cmd/6g/gen.c +++ b/src/cmd/6g/gen.c @@ -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; diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index f680a9c858..6025b425df 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -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(¶m, &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(¶m); + } + 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(¶m, &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(¶m); } break; } diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index cf597644d2..267d12aa8e 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -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*); diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 6a5ee5dc73..295a062ba6 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -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) { diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 4892c669ff..34d29e0a11 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -581,6 +581,10 @@ loop: walkconv(n); goto ret; + case OCOMPMAP: + case OCOMPSLICE: + goto ret; + case OCOMPOS: t = n->type; if(t == T) -- 2.48.1