From: Ken Thompson Date: Sun, 30 Aug 2009 21:43:33 +0000 (-0700) Subject: cleanup getting ready for static init X-Git-Tag: weekly.2009-11-06~711 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6fceadbba30ca4b503243794a7461592c029a871;p=gostls13.git cleanup getting ready for static init R=rsc OCL=34090 CL=34090 --- diff --git a/src/cmd/gc/init.c b/src/cmd/gc/init.c index dd641de96b..555f4e8902 100644 --- a/src/cmd/gc/init.c +++ b/src/cmd/gc/init.c @@ -32,19 +32,22 @@ renameinit(Node *n) * hand-craft the following initialization code * var initdone· uint8 (1) * func Init·() (2) - * if initdone· { (3) + * if initdone· != 0 { (3) * if initdone· == 2 (4) * return * throw(); (5) * } - * initdone.++; (6) + * initdone. += 1; (6) * // over all matching imported symbols * .init·() (7) * { } (8) * init·() // if any (9) - * initdone.++; (10) + * initdone. += 1; (10) * return (11) * } + * note that this code cannot have an assignment + * statement or, because of the initflag, it will + * be converted into a data statement. */ int anyinit(NodeList *n) @@ -119,7 +122,6 @@ fninit(NodeList *n) // (2) maxarg = 0; - snprint(namebuf, sizeof(namebuf), "Init·"); // this is a botch since we need a known name to @@ -196,14 +198,9 @@ fninit(NodeList *n) fn->nbody = r; -//dump("b", fn); -//dump("r", fn->nbody); - initflag = 1; // flag for loader static initialization funcbody(fn); typecheck(&fn, Etop); funccompile(fn); initflag = 0; } - - diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c index 84e844c271..da3084341e 100644 --- a/src/cmd/gc/sinit.c +++ b/src/cmd/gc/sinit.c @@ -8,455 +8,6 @@ #include "go.h" -static struct -{ - NodeList* list; - Node* mapname; - Type* type; -} xxx; - -enum -{ - TC_xxx, - - TC_unknown, // class - TC_struct, - TC_array, - TC_slice, - TC_map, - - TS_start, // state - TS_middle, - TS_end, -}; - -/* - * the init code (thru initfix) reformats the - * var = ... - * statements, rewriting the automatic - * variables with the static variables. - * this allows the code generator to - * generate DATA statements instead - * of assignment statements. - * it is quadradic, may need to change. - * it is extremely fragile knowing exactly - * how the code from (struct|array|map)lit - * will look. ideally the lit routines could - * write the code in this form, but ... - */ - -static int -typeclass(Type *t) -{ - if(t != T) - switch(t->etype) { - case TSTRUCT: - return TC_struct; - case TARRAY: - if(t->bound >= 0) - return TC_array; - return TC_slice; - case TMAP: - return TC_map; - } - return TC_unknown; -} - -void -initlin(NodeList *l) -{ - Node *n; - - for(; l; l=l->next) { - n = l->n; - switch(n->op) { - case ODCLFUNC: - case ODCLCONST: - case ODCLTYPE: - continue; - } - initlin(n->ninit); - n->ninit = nil; - xxx.list = list(xxx.list, n); - switch(n->op) { - default: - print("o = %O\n", n->op); - break; - - case OCALL: - // call to mapassign1 - case OAS: - break; - } - } -} - -int -inittmp(Node *n) -{ - if(n != N) - if(n->op == ONAME) - if(n->sym != S) - if(n->class == PAUTO) - if(memcmp(n->sym->name, "autotmp_", 8) == 0) - return 1; - return 0; -} - -int -sametmp(Node *n1, Node *n2) -{ - if(inittmp(n1)) - if(n1->xoffset == n2->xoffset) - return 1; - return 0; -} - -Node* -findarg(Node *n, char *arg, char *fn) -{ - Node *a; - NodeList *l; - - if(n == N || n->op != OCALL || - n->left == N || n->left->sym == S || - strcmp(n->left->sym->name, fn) != 0) - return N; - - for(l=n->list; l; l=l->next) { - a = l->n; - if(a->op == OAS && - a->left != N && a->right != N && - a->left->op == OINDREG && - a->left->sym != S) - if(strcmp(a->left->sym->name, arg) == 0) - return a->right; - } - return N; -} - -Node* -slicerewrite(Node *n) -{ - Node *nel; - Type *t; - int b; - Node *a; - - while(n->op == OCONVNOP) - n = n->left; - - // call to makeslice - find nel argument - nel = findarg(n, "nel", "makeslice"); - if(nel == N || !isslice(n->type)) - goto no; - - b = mpgetfix(nel->val.u.xval); - t = shallow(n->type); - t->bound = b; - - // special hack for zero-size array - // invent an l-value to point at - if(b == 0) - a = staticname(types[TBOOL]); - else - a = staticname(t); - - a = nod(OCOMPSLICE, a, N); - a->type = n->type; - return a; - -no: - return N; -} - -Node* -maprewrite(Node *n) -{ - Node *nel; - Type *ta, *tb; - Node *a; - - // call to makemap - find len argument - nel = findarg(n, "hint", "makemap"); - if(nel == N) - goto no; - ta = n->type; - if(ta->etype != TMAP) - goto no; - - // create a new type from map[index]value - // [0]struct { a index; b value) } - - tb = typ(TFIELD); - tb->type = ta->down; - tb->sym = lookup("key"); - tb->nname = newname(tb->sym); - tb->down = typ(TFIELD); - tb->down->type = ta->type; - tb->down->sym = lookup("val"); - tb->down->nname = newname(tb->down->sym); - - ta = typ(TSTRUCT); - ta->type = tb; - - tb = typ(TARRAY); - tb->type = ta; - tb->bound = 0; - - dowidth(tb); - - a = staticname(tb); - a = nod(OCOMPMAP, a, N); - a->type = n->type; - - // save stuff for this iteration - xxx.mapname = a->left; - xxx.type = tb; - - return a; - -no: - return N; -} - -// convert the call to mapassign1 -// into static[i].key = k, static[i].val = v -Node* -mapindex(Node *n) -{ - Node *index, *val, *key, *a, *b, *r; - - // pull all the primatives - key = findarg(n, "key", "mapassign1"); - if(key == N) - return N; - val = findarg(n, "val", "mapassign1"); - if(val == N) - return N; - index = nodintconst(xxx.type->bound); - xxx.type->bound++; - dowidth(xxx.type); - - // build tree - a = nod(OINDEX, xxx.mapname, index); - a = nod(ODOT, a, newname(lookup("key"))); - a = nod(OAS, a, key); - - b = nod(OINDEX, xxx.mapname, index); - b = nod(ODOT, b, newname(lookup("val"))); - b = nod(OAS, b, val); - - r = liststmt(list(list1(a), b)); - walkstmt(&r); - return r; -} - -// for a copy out reference, A = B, -// look through the whole structure -// and substitute references of B to A. -// some rewrite goes on also. -void -initsub(Node *n, Node *nam) -{ - Node *r, *w, *c; - NodeList *l; - int class, state; - - // we could probably get a little more - // out of this if we allow minimal simple - // expression on the right (eg OADDR-ONAME) - if(n->op != ONAME) - return; - - class = typeclass(nam->type); - state = TS_start; - - switch(class) { - case TC_struct: - goto str; - case TC_array: - goto ary; - case TC_slice: - goto sli; - case TC_map: - goto map; - } - return; - -str: - for(l=xxx.list; l; l=l->next) { - r = l->n; - if(r->op != OAS && r->op != OEMPTY) - continue; - - // optional first usage "nam = N" - if(r->right == N && sametmp(r->left, nam)) { - if(state != TS_start) { - dump("", r); - fatal("initsub: str-first and state=%d", state); - } - state = TS_middle; - r->op = OEMPTY; - continue; - } - - // last usage "n = nam" - if(r->left != N && sametmp(r->right, nam)) { - if(state == TS_end) { - dump("", r); - fatal("initsub: str-last and state=%d", state); - } - state = TS_end; - r->op = OEMPTY; - continue; - } - - // middle usage "(nam DOT name) AS expr" - if(r->left->op != ODOT || !sametmp(r->left->left, nam)) - continue; - if(state == TS_end) { - dump("", r); - fatal("initsub: str-middle and state=%d", state); - } - state = TS_middle; - r->left->left = n; - } - return; - -ary: - for(l=xxx.list; l; l=l->next) { - r = l->n; - if(r->op != OAS && r->op != OEMPTY) - continue; - - // optional first usage "nam = N" - if(r->right == N && sametmp(r->left, nam)) { - if(state != TS_start) { - dump("", r); - fatal("initsub: ary-first and state=%d", state); - } - state = TS_middle; - r->op = OEMPTY; - continue; - } - - // last usage "n = nam" - if(r->left != N && sametmp(r->right, nam)) { - if(state == TS_end) { - dump("", r); - fatal("initsub: ary-last and state=%d", state); - } - state = TS_end; - r->op = OEMPTY; - continue; - } - - // middle usage "(nam INDEX literal) = expr" - if(r->left->op != OINDEX || !sametmp(r->left->left, nam)) - continue; - if(state == TS_end) { - dump("", r); - fatal("initsub: ary-middle and state=%d", state); - } - state = TS_middle; - r->left->left = n; - } - return; - -sli: - w = N; - for(l=xxx.list; l; l=l->next) { - r = l->n; - if(r->op != OAS && r->op != OEMPTY) - continue; - - // first usage "nam = (makeslice CALL args)" - if(r->right != N && sametmp(r->left, nam)) { - w = slicerewrite(r->right); - if(w == N) - continue; - if(state != TS_start) { - dump("", r); - fatal("initsub: sli-first and state=%d", state); - } - state = TS_middle; - r->right = w; - r->left = n; - continue; - } - - // last usage "n = nam" - if(r->left != N && sametmp(r->right, nam)) { - if(state != TS_middle) { - dump("", r); - setlineno(r); - fatal("initsub: sli-last and state=%d", state); - } - state = TS_end; - r->op = OEMPTY; - continue; - } - - // middle usage "(nam INDEX literal) = expr" - if(r->left->op != OINDEX || !sametmp(r->left->left, nam)) - continue; - if(state != TS_middle) { - dump("", r); - fatal("initsub: sli-middle and state=%d", state); - } - state = TS_middle; - r->left->left = w->left; - } - return; - -map: -return; - w = N; - for(l=xxx.list; l; l=l->next) { - r = l->n; - if(r->op == OCALL) { - // middle usage "(CALL mapassign1 key, val, map)" - c = mapindex(r); - if(c == N) - continue; - state = TS_middle; - *r = *c; - continue; - } - if(r->op != OAS && r->op != OEMPTY) - continue; - - // first usage "nam = (makemap CALL args)" - if(r->right != N && sametmp(r->left, nam)) { - w = maprewrite(r->right); - if(w == N) - continue; - if(state != TS_start) { - dump("", r); - fatal("initsub: map-first and state=%d", state); - } - state = TS_middle; - r->right = w; - r->left = n; - continue; - } - - // last usage "n = nam" - if(r->left != N && sametmp(r->right, nam)) { - if(state != TS_middle) { - dump("", r); - fatal("initsub: map-last and state=%d", state); - } - state = TS_end; - r->op = OEMPTY; - continue; - } - } - return; - -} - static void init1(Node *n, NodeList **out) { @@ -489,16 +40,17 @@ init1(Node *n, NodeList **out) n->initorder = 2; if(n->defn != N) { switch(n->defn->op) { + default: + goto bad; + case ODCLFUNC: for(l=n->defn->nbody; l; l=l->next) init1(l->n, out); break; + case OAS: - if(n->defn->left != n) { - default: - dump("defn", n->defn); - fatal("bad defn"); - } + if(n->defn->left != n) + goto bad; init1(n->defn->right, out); if(debug['j']) print("%S\n", n->sym); @@ -508,6 +60,10 @@ init1(Node *n, NodeList **out) } n->initorder = 1; return; + +bad: + dump("defn", n->defn); + fatal("bad defn"); } static void @@ -532,23 +88,9 @@ initreorder(NodeList *l, NodeList **out) NodeList* initfix(NodeList *l) { - Node *r; + NodeList *lout; - xxx.list = nil; - initreorder(l, &xxx.list); - -if(0) -return xxx.list; - - if(nerrors != 0) - return xxx.list; - - // look for the copy-out reference - for(l=xxx.list; l; l=l->next) { - r = l->n; - if(r->op == OAS) - if(inittmp(r->right)) - initsub(r->left, r->right); - } - return xxx.list; + lout = nil; + initreorder(l, &lout); + return lout; } diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 052be2a844..9eb92f0bbd 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -609,7 +609,7 @@ dodump(Node *n, int dep) print("%O-rlist\n", n->op); dodumplist(n->rlist, dep+1); } - if(n->nbody != nil) { + if(n->op != OIF && n->nbody != nil) { indent(dep); print("%O-nbody\n", n->op); dodumplist(n->nbody, dep+1);