]> Cypherpunks repositories - gostls13.git/commitdiff
static initialization of slices
authorKen Thompson <ken@golang.org>
Tue, 19 May 2009 05:11:22 +0000 (22:11 -0700)
committerKen Thompson <ken@golang.org>
Tue, 19 May 2009 05:11:22 +0000 (22:11 -0700)
R=r
OCL=29016
CL=29016

src/cmd/6g/gen.c
src/cmd/gc/dcl.c
src/cmd/gc/go.h
src/cmd/gc/subr.c
src/cmd/gc/walk.c

index 598128f2e66c9e31bad3451252a31b500666bd3f..55eb43a618d9e2ddabcfb19689d1eec09c07214a 100644 (file)
@@ -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;
index f680a9c8580c716d456196f593b54af8c974f873..6025b425df0f2a6383ca399d0d487e8bdb335012 100644 (file)
@@ -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;
                }
index cf597644d2499d0819b7d81f2c8f47d9493a816b..267d12aa8e8e64405b08d010fc24d89d1560bbbd 100644 (file)
@@ -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*);
 
index 6a5ee5dc7388aff7f452813baa20eac376de5bf5..295a062ba620c1ced0e4c05a88ca3dc662be2407 100644 (file)
@@ -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)
 {
index 4892c669ff4eeb5c191099d34447786565ff83b2..34d29e0a11c65ca8124e6d1422ccfacb385ad21d 100644 (file)
@@ -581,6 +581,10 @@ loop:
                walkconv(n);
                goto ret;
 
+       case OCOMPMAP:
+       case OCOMPSLICE:
+               goto ret;
+
        case OCOMPOS:
                t = n->type;
                if(t == T)