]> Cypherpunks repositories - gostls13.git/commitdiff
gc: introduce explicit alignments
authorRuss Cox <rsc@golang.org>
Mon, 13 Dec 2010 16:57:41 +0000 (11:57 -0500)
committerRuss Cox <rsc@golang.org>
Mon, 13 Dec 2010 16:57:41 +0000 (11:57 -0500)
No semantic changes here, but working
toward being able to align structs based
on the maximum alignment of the fields
inside instead of having a fixed alignment
for all structs (issue 482).

R=ken2
CC=golang-dev
https://golang.org/cl/3617041

12 files changed:
src/cmd/5g/galign.c
src/cmd/5g/ggen.c
src/cmd/6g/galign.c
src/cmd/6g/ggen.c
src/cmd/8g/galign.c
src/cmd/8g/ggen.c
src/cmd/gc/align.c
src/cmd/gc/gen.c
src/cmd/gc/go.h
src/cmd/gc/lex.c
src/cmd/gc/reflect.c
src/cmd/gc/subr.c

index 76affbf00858cbc294daa7eeb8598f2924da6a90..9c8760aea7c541d3f6d89a7ddac96460e3ad1705 100644 (file)
@@ -25,7 +25,6 @@ Typedef       typedefs[] =
 void
 betypeinit(void)
 {
-       maxround = 4;
        widthptr = 4;
 
        zprog.link = P;
index db1837b110e0a975cb9e8dd83bd115d58a70fccf..42a89415d36d55948ca9e380f47b08fe3b8ca961 100644 (file)
@@ -111,12 +111,12 @@ compile(Node *fn)
        // fill in argument size
        ptxt->to.type = D_CONST2;
        ptxt->reg = 0; // flags
-       ptxt->to.offset2 = rnd(curfn->type->argwid, maxround);
+       ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr);
 
        // fill in final stack size
        if(stksize > maxstksize)
                maxstksize = stksize;
-       ptxt->to.offset = rnd(maxstksize+maxarg, maxround);
+       ptxt->to.offset = rnd(maxstksize+maxarg, widthptr);
        maxstksize = 0;
 
        if(debug['f'])
index 68647e21b4b3d183028575de619fb734fd425576..bdfc9947e8145231a7eda863a0bbe7f7aeb21722 100644 (file)
@@ -25,7 +25,6 @@ Typedef       typedefs[] =
 void
 betypeinit(void)
 {
-       maxround = 8;
        widthptr = 8;
 
        zprog.link = P;
index ebee6f81038a52a5968d41fe0189f1b1d227c094..d9fa1793c6a72cd8109dc82f44d0f94c90c8a698 100644 (file)
@@ -109,11 +109,11 @@ compile(Node *fn)
        }
 
        // fill in argument size
-       ptxt->to.offset = rnd(curfn->type->argwid, maxround);
+       ptxt->to.offset = rnd(curfn->type->argwid, widthptr);
 
        // fill in final stack size
        ptxt->to.offset <<= 32;
-       ptxt->to.offset |= rnd(stksize+maxarg, maxround);
+       ptxt->to.offset |= rnd(stksize+maxarg, widthptr);
 
        if(debug['f'])
                frame(0);
index 346647205af93f70714593c599b7127b2be435a4..1c14dfe471a6bc545e3b3726edeaaf4b1cc887ce 100644 (file)
@@ -25,7 +25,6 @@ Typedef       typedefs[] =
 void
 betypeinit(void)
 {
-       maxround = 4;
        widthptr = 4;
 
        zprog.link = P;
index 0c3a8260c2bc001f332899d49d86a6ac388c6911..f1461adbebf3b0ada923713689358f5d93fafa38 100644 (file)
@@ -118,12 +118,12 @@ compile(Node *fn)
                regopt(ptxt);
        }
        // fill in argument size
-       ptxt->to.offset2 = rnd(curfn->type->argwid, maxround);
+       ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr);
 
        // fill in final stack size
        if(stksize > maxstksize)
                maxstksize = stksize;
-       ptxt->to.offset = rnd(maxstksize+maxarg, maxround);
+       ptxt->to.offset = rnd(maxstksize+maxarg, widthptr);
        maxstksize = 0;
 
        if(debug['f'])
index 57dd3071beb9bc8a46a6ac655ba3f667367ad869..4b6d92e786aeadb67feec230ca9527fa371cca82 100644 (file)
@@ -16,15 +16,9 @@ static int defercalc;
 uint32
 rnd(uint32 o, uint32 r)
 {
-       if(maxround == 0)
+       if(r < 1 || r > 8 || (r&(r-1)) != 0)
                fatal("rnd");
-
-       if(r > maxround)
-               r = maxround;
-       if(r != 0)
-               while(o%r != 0)
-                       o++;
-       return o;
+       return (o+r-1)&~(r-1);
 }
 
 static void
@@ -42,30 +36,25 @@ offmod(Type *t)
        }
 }
 
-static uint32
-arrayelemwidth(Type *t)
-{
-
-       while(t->etype == TARRAY && t->bound >= 0)
-               t = t->type;
-       return t->width;
-}
-
 static uint32
 widstruct(Type *t, uint32 o, int flag)
 {
        Type *f;
-       int32 w, m;
-
+       int32 w, maxalign;
+       
+       maxalign = flag;
+       if(maxalign < 1)
+               maxalign = 1;
        for(f=t->type; f!=T; f=f->down) {
                if(f->etype != TFIELD)
                        fatal("widstruct: not TFIELD: %lT", f);
                dowidth(f->type);
+               if(f->align > maxalign)
+                       maxalign = f->align;
                if(f->type->width < 0)
                        fatal("invalid width %lld", f->type->width);
                w = f->type->width;
-               m = arrayelemwidth(f->type);
-               o = rnd(o, m);
+               o = rnd(o, f->type->align);
                f->width = o;   // really offset for TFIELD
                if(f->nname != N) {
                        // this same stackparam logic is in addrescapes
@@ -82,7 +71,8 @@ widstruct(Type *t, uint32 o, int flag)
        }
        // final width is rounded
        if(flag)
-               o = rnd(o, maxround);
+               o = rnd(o, maxalign);
+       t->align = maxalign;
 
        // type width only includes back to first field's offset
        if(t->type == T)
@@ -100,7 +90,7 @@ dowidth(Type *t)
        int lno;
        Type *t1;
 
-       if(maxround == 0 || widthptr == 0)
+       if(widthptr == 0)
                fatal("dowidth without betypeinit");
 
        if(t == T)
@@ -124,6 +114,7 @@ dowidth(Type *t)
        lno = lineno;
        lineno = t->lineno;
        t->width = -2;
+       t->align = 0;
 
        et = t->etype;
        switch(et) {
@@ -166,9 +157,11 @@ dowidth(Type *t)
        case TFLOAT64:
        case TCOMPLEX64:
                w = 8;
+               t->align = widthptr;
                break;
        case TCOMPLEX128:
                w = 16;
+               t->align = widthptr;
                break;
        case TPTR32:
                w = 4;
@@ -180,6 +173,7 @@ dowidth(Type *t)
                break;
        case TINTER:            // implemented as 2 pointers
                w = 2*widthptr;
+               t->align = widthptr;
                offmod(t);
                break;
        case TCHAN:             // implemented as pointer
@@ -197,6 +191,7 @@ dowidth(Type *t)
                dowidth(t->type);       // just in case
                if(t1->type->width >= (1<<16))
                        yyerror("channel element type too large (>64kB)");
+               t->width = 1;
                break;
        case TMAP:              // implemented as pointer
                w = widthptr;
@@ -217,6 +212,7 @@ dowidth(Type *t)
                if(sizeof_String == 0)
                        fatal("early dowidth string");
                w = sizeof_String;
+               t->align = widthptr;
                break;
        case TARRAY:
                if(t->type == T)
@@ -235,11 +231,13 @@ dowidth(Type *t)
                                yyerror("type %lT larger than address space", t);
                        w = t->bound * t->type->width;
                        if(w == 0)
-                               w = maxround;
+                               w = 1;
+                       t->align = t->type->align;
                }
                else if(t->bound == -1) {
                        w = sizeof_Array;
                        checkwidth(t->type);
+                       t->align = widthptr;
                }
                else if(t->bound == -100)
                        yyerror("use of [...] array outside of array literal");
@@ -250,9 +248,9 @@ dowidth(Type *t)
        case TSTRUCT:
                if(t->funarg)
                        fatal("dowidth fn struct %T", t);
-               w = widstruct(t, 0, 1);
+               w = widstruct(t, 0, widthptr);
                if(w == 0)
-                       w = maxround;
+                       w = 1;
                break;
 
        case TFUNC:
@@ -271,16 +269,22 @@ dowidth(Type *t)
                // compute their widths as side-effect.
                t1 = t->type;
                w = widstruct(*getthis(t1), 0, 0);
-               w = widstruct(*getinarg(t1), w, 1);
-               w = widstruct(*getoutarg(t1), w, 1);
+               w = widstruct(*getinarg(t1), w, widthptr);
+               w = widstruct(*getoutarg(t1), w, widthptr);
                t1->argwid = w;
+               t->align = 1;
                break;
        }
 
        // catch all for error cases; avoid divide by zero later
        if(w == 0)
-               w = maxround;
+               w = 1;
        t->width = w;
+       if(t->align == 0) {
+               if(w > 8 || (w&(w-1)) != 0)
+                       fatal("invalid alignment for %T", t);
+               t->align = w;
+       }
        lineno = lno;
 
        if(defercalc == 1)
@@ -596,10 +600,10 @@ typeinit(void)
        Array_array = rnd(0, widthptr);
        Array_nel = rnd(Array_array+widthptr, types[TUINT32]->width);
        Array_cap = rnd(Array_nel+types[TUINT32]->width, types[TUINT32]->width);
-       sizeof_Array = rnd(Array_cap+types[TUINT32]->width, maxround);
+       sizeof_Array = rnd(Array_cap+types[TUINT32]->width, widthptr);
 
        // string is same as slice wo the cap
-       sizeof_String = rnd(Array_nel+types[TUINT32]->width, maxround);
+       sizeof_String = rnd(Array_nel+types[TUINT32]->width, widthptr);
 
        dowidth(types[TSTRING]);
        dowidth(idealstring);
index 65861c7635bfbf4d4a07169a31718e75f97797c4..8144fabaa8cc98f7d5b1e065612d984e3fb01ea6 100644 (file)
@@ -58,7 +58,7 @@ allocparams(void)
                if(w >= MAXWIDTH)
                        fatal("bad width");
                stksize += w;
-               stksize = rnd(stksize, w);
+               stksize = rnd(stksize, n->type->align);
                n->xoffset = -stksize;
        }
        lineno = lno;
@@ -664,7 +664,7 @@ tempname(Node *n, Type *t)
        dowidth(t);
        w = t->width;
        stksize += w;
-       stksize = rnd(stksize, w);
+       stksize = rnd(stksize, t->align);
        n->xoffset = -stksize;
        n->pun = anyregalloc();
 }
index 5b7e316fe067336fb4f02467eb6b2b0e602a4ee3..4b48ad55eac8a9709477271aed7f16ceab245115 100644 (file)
@@ -154,6 +154,7 @@ struct      Type
        uchar   deferwidth;
        uchar   broke;
        uchar   isddd;  // TFIELD is ... argument
+       uchar   align;
 
        Node*   nod;            // canonical OTYPE node
        Type*   orig;           // original type (type literal or predefined type)
@@ -751,7 +752,6 @@ EXTERN      int     hasdefer;               // flag that curfn has defer statetment
 
 EXTERN Node*   curfn;
 
-EXTERN int     maxround;
 EXTERN int     widthptr;
 
 EXTERN Node*   typesw;
index 9dded356d4701e71f8fa9c4c0a9ce84eb404e578..0f1acd2fcdab7a61b1958eea216d974e0a903819 100644 (file)
@@ -194,7 +194,7 @@ main(int argc, char *argv[])
        fmtinstall('F', Fconv);         // big float numbers
 
        betypeinit();
-       if(maxround == 0 || widthptr == 0)
+       if(widthptr == 0)
                fatal("betypeinit failed");
 
        lexinit();
index 04ff3f0ec8aa8c0dd1f9ca91e0f2481ed8f8eb2b..b31eb51549283da363254f66730da2487f5be86e 100644 (file)
@@ -577,7 +577,6 @@ dcommontype(Sym *s, int ot, Type *t)
 {
        int i;
        Sym *s1;
-       Type *elem;
        char *p;
 
        dowidth(t);
@@ -605,14 +604,8 @@ dcommontype(Sym *s, int ot, Type *t)
        ot = duintptr(s, ot, t->width);
        ot = duint32(s, ot, typehash(t));
        ot = duint8(s, ot, algtype(t));
-       elem = t;
-       while(elem->etype == TARRAY && elem->bound >= 0)
-               elem = elem->type;
-       i = elem->width;
-       if(i > maxround)
-               i = maxround;
-       ot = duint8(s, ot, i);  // align
-       ot = duint8(s, ot, i);  // fieldAlign
+       ot = duint8(s, ot, t->align);   // align
+       ot = duint8(s, ot, t->align);   // fieldAlign
        i = kinds[t->etype];
        if(t->etype == TARRAY && t->bound < 0)
                i = KindSlice;
index 8acf1cdfec39ff4814fa057f389758864b2f67e9..9b6c79d8665be83f3b90c9e5ab97930e643fadfa 100644 (file)
@@ -2309,7 +2309,8 @@ ptrto(Type *t)
                fatal("ptrto: nil");
        t1 = typ(tptr);
        t1->type = t;
-       t1->width = types[tptr]->width;
+       t1->width = widthptr;
+       t1->align = widthptr;
        return t1;
 }