]> Cypherpunks repositories - gostls13.git/commitdiff
bug in 6g optimizer
authorKen Thompson <ken@golang.org>
Fri, 11 Dec 2009 23:55:09 +0000 (15:55 -0800)
committerKen Thompson <ken@golang.org>
Fri, 11 Dec 2009 23:55:09 +0000 (15:55 -0800)
8g still needs fixing

R=rsc
https://golang.org/cl/176057

src/cmd/6g/gsubr.c
src/cmd/6g/reg.c
src/cmd/8g/gsubr.c
src/cmd/gc/go.h

index 7461649ad974d30999fadeac690ce96c9a90c976..142d3c245d0a8a02637c1687e188cd43f0754380 100644 (file)
@@ -1049,6 +1049,7 @@ naddr(Node *n, Addr *a, int canemitcode)
        case OLEN:
                // len of string or slice
                naddr(n->left, a, canemitcode);
+               a->etype = TUINT;
                a->offset += Array_nel;
                if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
                        checkoffset(a, canemitcode);
@@ -1057,6 +1058,7 @@ naddr(Node *n, Addr *a, int canemitcode)
        case OCAP:
                // cap of string or slice
                naddr(n->left, a, canemitcode);
+               a->etype = TUINT;
                a->offset += Array_cap;
                if(a->offset >= unmappedzero && a->offset-Array_cap < unmappedzero)
                        checkoffset(a, canemitcode);
index f406335f4e5ed5b34fe1ff950095b76109c9aa6a..4bd888bc33116d699517dfff867bb246d262dc86 100644 (file)
@@ -67,7 +67,7 @@ rcmp(const void *a1, const void *a2)
        return p2->varno - p1->varno;
 }
 
-void
+static void
 setoutvar(void)
 {
        Type *t;
@@ -91,6 +91,13 @@ setoutvar(void)
 //print("ovars = %Q\n", &ovar);
 }
 
+static void
+setaddrs(Bits bit)
+{
+       if(bany(&bit))
+               var[bnum(bit)].addr = 1;
+}
+
 void
 regopt(Prog *firstp)
 {
@@ -181,8 +188,7 @@ regopt(Prog *firstp)
                 */
                case ALEAL:
                case ALEAQ:
-                       for(z=0; z<BITS; z++)
-                               addrs.b[z] |= bit.b[z];
+                       setaddrs(bit);
                        break;
 
                /*
@@ -378,8 +384,7 @@ regopt(Prog *firstp)
                 * funny
                 */
                case ACALL:
-                       for(z=0; z<BITS; z++)
-                               addrs.b[z] |= bit.b[z];
+                       setaddrs(bit);
                        break;
                }
 
@@ -453,6 +458,18 @@ regopt(Prog *firstp)
        if(firstr == R)
                return;
 
+       for(i=0; i<nvar; i++) {
+               Var *v = var+i;
+               if(v->addr) {
+                       bit = blsh(i);
+                       for(z=0; z<BITS; z++)
+                               addrs.b[z] |= bit.b[z];
+               }
+
+//             print("bit=%2d addr=%d et=%-6E w=%-2d s=%S + %lld\n",
+//                     i, v->addr, v->etype, v->width, v->sym, v->offset);
+       }
+
        if(debug['R'] && debug['v'])
                dumpit("pass1", firstr);
 
@@ -768,31 +785,16 @@ doregbits(int r)
 }
 
 static int
-overlap(Var *v, int o2, int w2)
+overlap(int32 o1, int w1, int32 o2, int w2)
 {
-       int o1, w1, t1, t2, z;
-       Bits bit;
+       int32 t1, t2;
 
-       o1 = v->offset;
-       w1 = v->width;
        t1 = o1+w1;
        t2 = o2+w2;
+
        if(!(t1 > o2 && t2 > o1))
                return 0;
 
-       // set to max extent
-       if(o2 < o1)
-               v->offset = o2;
-       if(t1 > t2)
-               v->width = t1-v->offset;
-       else
-               v->width = t2-v->offset;
-
-       // and dont registerize
-       bit = blsh(v-var);
-       for(z=0; z<BITS; z++)
-               addrs.b[z] |= bit.b[z];
-
        return 1;
 }
 
@@ -809,6 +811,9 @@ mkvar(Reg *r, Adr *a)
         * mark registers used
         */
        t = a->type;
+       if(t == D_NONE)
+               goto none;
+
        if(r != R) {
                r->regu |= doregbits(t);
                r->regu |= doregbits(a->index);
@@ -817,14 +822,15 @@ mkvar(Reg *r, Adr *a)
        switch(t) {
        default:
                goto none;
+
        case D_ADDR:
                a->type = a->index;
                bit = mkvar(r, a);
-               for(z=0; z<BITS; z++)
-                       addrs.b[z] |= bit.b[z];
+               setaddrs(bit);
                a->type = t;
                ostats.naddr++;
                goto none;
+
        case D_EXTERN:
        case D_STATIC:
        case D_PARAM:
@@ -840,32 +846,30 @@ mkvar(Reg *r, Adr *a)
        et = a->etype;
        o = a->offset;
        w = a->width;
-       v = var;
 
        flag = 0;
        for(i=0; i<nvar; i++) {
-               if(s == v->sym)
-               if(n == v->name) {
-                       // if it is the same, use it
-                       if(v->etype == et)
-                       if(v->width == w)
-                       if(v->offset == o)
-                               goto out;
-
-                       // if it overlaps, set max
-                       // width and dont registerize
-                       if(overlap(v, o, w))
+               v = var+i;
+               if(v->sym == s && v->name == n) {
+                       if(v->offset == o) {
+                               // if it is the same, use it
+                               if(v->etype != et||
+                                  v->width != w)
+                                       v->addr = 1;
+                               return blsh(i);
+                       }
+
+                       // if it overlaps, disable bothj
+                       if(overlap(v->offset, v->width, o, w)) {
+                               v->addr = 1;
                                flag = 1;
+                       }
                }
-               v++;
        }
-       if(flag)
-               goto none;
 
        switch(et) {
        case 0:
        case TFUNC:
-       case TARRAY:
                goto none;
        }
 
@@ -874,9 +878,10 @@ mkvar(Reg *r, Adr *a)
                        fatal("variable not optimized: %D", a);
                goto none;
        }
+
        i = nvar;
        nvar++;
-       v = &var[i];
+       v = var+i;
        v->sym = s;
        v->offset = o;
        v->name = n;
@@ -884,24 +889,10 @@ mkvar(Reg *r, Adr *a)
        v->etype = et;
        v->width = w;
        if(debug['R'])
-               print("bit=%2d et=%2d w=%d %D\n", i, et, w, a);
+               print("bit=%2d et=%2d w=%d %S %D\n", i, et, w, s, a);
        ostats.nvar++;
 
-out:
        bit = blsh(i);
-
-       // funny punning
-       if(v->etype != et) {
-               if(debug['R'])
-                       print("pun et=%d/%d w=%d/%d o=%d/%d %D\n",
-                               v->etype, et,
-                               v->width, w,
-                               v->offset, o, a);
-               for(z=0; z<BITS; z++)
-                       addrs.b[z] |= bit.b[z];
-               goto none;
-       }
-
        if(n == D_EXTERN || n == D_STATIC)
                for(z=0; z<BITS; z++)
                        externs.b[z] |= bit.b[z];
@@ -909,6 +900,10 @@ out:
                for(z=0; z<BITS; z++)
                        params.b[z] |= bit.b[z];
 
+       // funny punning
+       if(flag)
+               v->addr = 1;
+
        return bit;
 
 none:
index 9e65a06e4295265cb9cd7e08efff6819e07144bb..4625509e9d74929316761f781ce908d0b811257c 100644 (file)
@@ -1769,6 +1769,7 @@ naddr(Node *n, Addr *a, int canemitcode)
        case OLEN:
                // len of string or slice
                naddr(n->left, a, canemitcode);
+               a->etype = TUINT;
                a->offset += Array_nel;
                if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
                        checkoffset(a, canemitcode);
@@ -1777,6 +1778,7 @@ naddr(Node *n, Addr *a, int canemitcode)
        case OCAP:
                // cap of string or slice
                naddr(n->left, a, canemitcode);
+               a->etype = TUINT;
                a->offset += Array_cap;
                if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
                        checkoffset(a, canemitcode);
index 5df0c5be858fc6334cb851c26905ffe41ea8829e..15d1cf335d4fdc585797518d1bd957f9c9502e47 100644 (file)
@@ -513,6 +513,7 @@ struct      Var
        int     width;
        char    name;
        char    etype;
+       char    addr;
 };
 
 EXTERN Var     var[NVAR];