]> Cypherpunks repositories - gostls13.git/commitdiff
5g, 6g, 8g: registerize variables again
authorRuss Cox <rsc@golang.org>
Mon, 3 Oct 2011 21:46:36 +0000 (17:46 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 3 Oct 2011 21:46:36 +0000 (17:46 -0400)
My previous CL:

changeset:   9645:ce2e5f44b310
user:        Russ Cox <rsc@golang.org>
date:        Tue Sep 06 10:24:21 2011 -0400
summary:     gc: unify stack frame layout

introduced a bug wherein no variables were
being registerized, making Go programs 2-3x
slower than they had been before.

This CL fixes that bug (along with some others
it was hiding) and adds a test that optimization
makes at least one test case faster.

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

14 files changed:
src/cmd/5g/gobj.c
src/cmd/5g/gsubr.c
src/cmd/5g/reg.c
src/cmd/6g/gobj.c
src/cmd/6g/gsubr.c
src/cmd/6g/reg.c
src/cmd/8g/gobj.c
src/cmd/8g/gsubr.c
src/cmd/8g/reg.c
src/cmd/gc/bits.c
src/cmd/gc/gen.c
src/cmd/gc/obj.c
test/fixedbugs/bug369.dir/pkg.go [new file with mode: 0644]
test/fixedbugs/bug369.go [new file with mode: 0644]

index 9f728dee76e8b9ad4e17a66aa1a1a0c2bdf4aec1..b562ba888ba26115ccc0563a6a3f0e66bc42ba68 100644 (file)
@@ -307,6 +307,7 @@ datastring(char *s, int len, Addr *a)
        a->offset = widthptr+4;  // skip header
        a->reg = NREG;
        a->sym = sym;
+       a->node = sym->def;
 }
 
 /*
@@ -325,6 +326,7 @@ datagostring(Strlit *sval, Addr *a)
        a->offset = 0;  // header
        a->reg = NREG;
        a->sym = sym;
+       a->node = sym->def;
 }
 
 void
index f8920df87bb5f038fe92609e0779b5a51eacb3a2..29793abf014d78d63587d2b2edb3d0815196a98b 100644 (file)
@@ -512,6 +512,7 @@ nodarg(Type *t, int fp)
                fatal("nodarg: offset not computed for %T", t);
        n->xoffset = t->width;
        n->addable = 1;
+       n->orig = t->nname;
 
 fp:
        switch(fp) {
@@ -1263,6 +1264,7 @@ naddr(Node *n, Addr *a, int canemitcode)
                a->sym = n->left->sym;
                a->type = D_OREG;
                a->name = D_PARAM;
+               a->node = n->left->orig;
                break;
 
        case ONAME:
@@ -1275,6 +1277,9 @@ naddr(Node *n, Addr *a, int canemitcode)
                }
                a->offset = n->xoffset;
                a->sym = n->sym;
+               a->node = n->orig;
+               //if(a->node >= (Node*)&n)
+               //      fatal("stack node");
                if(a->sym == S)
                        a->sym = lookup(".noname");
                if(n->method) {
@@ -1293,8 +1298,6 @@ naddr(Node *n, Addr *a, int canemitcode)
                        break;
                case PAUTO:
                        a->name = D_AUTO;
-                       if (n->sym)
-                               a->node = n->orig;
                        break;
                case PPARAM:
                case PPARAMOUT:
index 9dd3f07f17fc1e28e58db0af04d12a7d810df586..a2e99492d6f55d1447501538a772fbf214b3a898 100644 (file)
@@ -92,8 +92,8 @@ setoutvar(void)
                        ovar.b[z] |= bit.b[z];
                t = structnext(&save);
        }
-//if(bany(b))
-//print("ovars = %Q\n", &ovar);
+//if(bany(ovar))
+//print("ovar = %Q\n", ovar);
 }
 
 void
@@ -911,10 +911,12 @@ mkvar(Reg *r, Adr *a)
        }
 
        node = a->node;
-       if(node == N || node->op != ONAME || node->orig != N)
+       if(node == N || node->op != ONAME || node->orig == N)
                goto none;
        node = node->orig;
-       if(node->sym->name[0] == '.')
+       if(node->orig != node)
+               fatal("%D: bad node", a);
+       if(node->sym == S || node->sym->name[0] == '.')
                goto none;
        et = a->etype;
        o = a->offset;
@@ -1571,7 +1573,7 @@ dumpone(Reg *r)
                if(bany(&r->refahead))
                        print(" ra:%Q ", r->refahead);
                if(bany(&r->calbehind))
-                       print("cb:%Q ", r->calbehind);
+                       print(" cb:%Q ", r->calbehind);
                if(bany(&r->calahead))
                        print(" ca:%Q ", r->calahead);
                if(bany(&r->regdiff))
index 4dcce39c8fe4c1ccb99b8339b34b1800c002ba6c..dfb5e224afc3a6ac3877db45292bfc3702c77cdf 100644 (file)
@@ -310,6 +310,7 @@ datastring(char *s, int len, Addr *a)
        sym = stringsym(s, len);
        a->type = D_EXTERN;
        a->sym = sym;
+       a->node = sym->def;
        a->offset = widthptr+4;  // skip header
        a->etype = TINT32;
 }
@@ -326,6 +327,7 @@ datagostring(Strlit *sval, Addr *a)
        sym = stringsym(sval->s, sval->len);
        a->type = D_EXTERN;
        a->sym = sym;
+       a->node = sym->def;
        a->offset = 0;  // header
        a->etype = TINT32;
 }
index 92b15ef00f77c4cc05fda27c8d9bf8efe8ea16de..c16a3645a8e058415be93b579ab114c091d74c77 100644 (file)
@@ -485,6 +485,7 @@ nodarg(Type *t, int fp)
                fatal("nodarg: offset not computed for %T", t);
        n->xoffset = t->width;
        n->addable = 1;
+       n->orig = t->nname;
 
 fp:
        switch(fp) {
@@ -1119,6 +1120,7 @@ naddr(Node *n, Addr *a, int canemitcode)
                a->offset = n->xoffset;
                a->sym = n->left->sym;
                a->type = D_PARAM;
+               a->node = n->left->orig;
                break;
 
        case ONAME:
@@ -1131,6 +1133,9 @@ naddr(Node *n, Addr *a, int canemitcode)
                }
                a->offset = n->xoffset;
                a->sym = n->sym;
+               a->node = n->orig;
+               //if(a->node >= (Node*)&n)
+               //      fatal("stack node");
                if(a->sym == S)
                        a->sym = lookup(".noname");
                if(n->method) {
@@ -1148,8 +1153,6 @@ naddr(Node *n, Addr *a, int canemitcode)
                        break;
                case PAUTO:
                        a->type = D_AUTO;
-                       if (n->sym)
-                               a->node = n->orig;
                        break;
                case PPARAM:
                case PPARAMOUT:
index f380ced8cb41c795e537fac092ff5c629c24ed0b..d12d4b19b72cdc150c1346ce083b79296bf58f24 100644 (file)
@@ -89,8 +89,8 @@ setoutvar(void)
                        ovar.b[z] |= bit.b[z];
                t = structnext(&save);
        }
-//if(bany(b))
-//print("ovars = %Q\n", &ovar);
+//if(bany(&ovar))
+//print("ovars = %Q\n", ovar);
 }
 
 static void
@@ -968,11 +968,14 @@ mkvar(Reg *r, Adr *a)
                n = t;
                break;
        }
+
        node = a->node;
-       if(node == N || node->op != ONAME || node->orig != N)
+       if(node == N || node->op != ONAME || node->orig == N)
                goto none;
        node = node->orig;
-       if(node->sym->name[0] == '.')
+       if(node->orig != node)
+               fatal("%D: bad node", a);
+       if(node->sym == S || node->sym->name[0] == '.')
                goto none;
        et = a->etype;
        o = a->offset;
@@ -1622,7 +1625,7 @@ dumpone(Reg *r)
                if(bany(&r->refahead))
                        print(" ra:%Q ", r->refahead);
                if(bany(&r->calbehind))
-                       print("cb:%Q ", r->calbehind);
+                       print(" cb:%Q ", r->calbehind);
                if(bany(&r->calahead))
                        print(" ca:%Q ", r->calahead);
                if(bany(&r->regdiff))
index 7025a536e1eacea1fe44c2519b5b75453199a223..d8c8f5ab9fe9c8f20136678f8c8fbf430b787077 100644 (file)
@@ -308,6 +308,7 @@ datastring(char *s, int len, Addr *a)
        sym = stringsym(s, len);
        a->type = D_EXTERN;
        a->sym = sym;
+       a->node = sym->def;
        a->offset = widthptr+4;  // skip header
        a->etype = TINT32;
 }
@@ -324,6 +325,7 @@ datagostring(Strlit *sval, Addr *a)
        sym = stringsym(sval->s, sval->len);
        a->type = D_EXTERN;
        a->sym = sym;
+       a->node = sym->def;
        a->offset = 0;  // header
        a->etype = TINT32;
 }
index 1aae34e3583ea3c2da169ac71c7508563f80acfe..c7c39b4183a1fc41d7be69730e54667a7ee33db2 100644 (file)
@@ -964,6 +964,7 @@ nodarg(Type *t, int fp)
                        fatal("nodarg: offset not computed for %T", t);
                n->xoffset = t->width;
                n->addable = 1;
+               n->orig = t->nname;
                break;
        }
 
@@ -1152,6 +1153,7 @@ memname(Node *n, Type *t)
        strcpy(namebuf, n->sym->name);
        namebuf[0] = '.';       // keep optimizer from registerizing
        n->sym = lookup(namebuf);
+       n->orig->sym = n->sym;
 }
 
 void
@@ -1828,6 +1830,7 @@ naddr(Node *n, Addr *a, int canemitcode)
                a->offset = n->xoffset;
                a->sym = n->left->sym;
                a->type = D_PARAM;
+               a->node = n->left->orig;
                break;
 
        case ONAME:
@@ -1840,6 +1843,9 @@ naddr(Node *n, Addr *a, int canemitcode)
                }
                a->offset = n->xoffset;
                a->sym = n->sym;
+               a->node = n->orig;
+               //if(a->node >= (Node*)&n)
+               //      fatal("stack node");
                if(a->sym == S)
                        a->sym = lookup(".noname");
                if(n->method) {
@@ -1857,8 +1863,6 @@ naddr(Node *n, Addr *a, int canemitcode)
                        break;
                case PAUTO:
                        a->type = D_AUTO;
-                       if (n->sym)
-                               a->node = n->orig;
                        break;
                case PPARAM:
                case PPARAMOUT:
index de5fd87ac8f7757bd292553696776725ac36cf44..29ea68b64fafb4e33fd7c8c01e1647156404e3e9 100644 (file)
@@ -89,8 +89,8 @@ setoutvar(void)
                        ovar.b[z] |= bit.b[z];
                t = structnext(&save);
        }
-//if(bany(b))
-//print("ovars = %Q\n", &ovar);
+//if(bany(ovar))
+//print("ovars = %Q\n", ovar);
 }
 
 static void
@@ -848,10 +848,12 @@ mkvar(Reg *r, Adr *a)
        }
 
        node = a->node;
-       if(node == N || node->op != ONAME || node->orig != N)
+       if(node == N || node->op != ONAME || node->orig == N)
                goto none;
        node = node->orig;
-       if(node->sym->name[0] == '.')
+       if(node->orig != node)
+               fatal("%D: bad node", a);
+       if(node->sym == S || node->sym->name[0] == '.')
                goto none;
        et = a->etype;
        o = a->offset;
@@ -1482,7 +1484,7 @@ dumpone(Reg *r)
                if(bany(&r->refahead))
                        print(" ra:%Q ", r->refahead);
                if(bany(&r->calbehind))
-                       print("cb:%Q ", r->calbehind);
+                       print(" cb:%Q ", r->calbehind);
                if(bany(&r->calahead))
                        print(" ca:%Q ", r->calahead);
                if(bany(&r->regdiff))
index f3b031cc3ed5ed5aec846653537fe71f99fc6f4c..591288db6233b461621e52d0db98bc97cb9a8cbe 100644 (file)
@@ -151,9 +151,9 @@ Qconv(Fmt *fp)
                else
                        fmtprint(fp, " ");
                if(var[i].node == N || var[i].node->sym == S)
-                       fmtprint(fp, "$%lld", var[i].offset);
+                       fmtprint(fp, "$%lld", i);
                else {
-                       fmtprint(fp, var[i].node->sym->name);
+                       fmtprint(fp, "%s", var[i].node->sym->name);
                        if(var[i].offset != 0)
                                fmtprint(fp, "%+lld", (vlong)var[i].offset);
                }
index a818dbc195f666d009812b7e45f23e83a9982afa..cd6d9aaf5a449f14c16ba359cd7c3a9a6b81c7e7 100644 (file)
@@ -805,6 +805,7 @@ tempname(Node *nn, Type *t)
        s = lookup(namebuf);
        n = nod(ONAME, N, N);
        n->sym = s;
+       s->def = n;
        n->type = t;
        n->class = PAUTO;
        n->addable = 1;
index 730b42671c044e3b6896f115aa1a5273c52e8e44..aba2aafd81e3fd6836bc0524df1f3d3f554b01a5 100644 (file)
@@ -267,6 +267,7 @@ stringsym(char *s, int len)
        if(sym->flags & SymUniq)
                return sym;
        sym->flags |= SymUniq;
+       sym->def = newname(sym);
 
        off = 0;
        
diff --git a/test/fixedbugs/bug369.dir/pkg.go b/test/fixedbugs/bug369.dir/pkg.go
new file mode 100644 (file)
index 0000000..cf57041
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkg
+
+func NonASCII(b []byte, i int) int {
+       for i = 0; i < len(b); i++ {
+               if b[i] >= 0x80 {
+                       break
+               }
+       }
+       return i
+}
+
diff --git a/test/fixedbugs/bug369.go b/test/fixedbugs/bug369.go
new file mode 100644 (file)
index 0000000..fbcdf28
--- /dev/null
@@ -0,0 +1,57 @@
+// $G -N -o slow.$A $D/bug369.dir/pkg.go &&
+// $G -o fast.$A $D/bug369.dir/pkg.go &&
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that compiling with optimization turned on produces faster code.
+
+package main
+
+import (
+       "flag"
+       "os"
+       "runtime"
+       "testing"
+
+       fast "./fast"
+       slow "./slow"
+)
+
+var buf = make([]byte, 1048576)
+
+func BenchmarkFastNonASCII(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               fast.NonASCII(buf, 0)
+       }
+}
+
+func BenchmarkSlowNonASCII(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               slow.NonASCII(buf, 0)
+       }
+}
+
+func main() {
+       os.Args = []string{os.Args[0], "-test.benchtime=0.1"}
+       flag.Parse()
+       
+       rslow := testing.Benchmark(BenchmarkSlowNonASCII)
+       rfast := testing.Benchmark(BenchmarkFastNonASCII)
+       tslow := rslow.NsPerOp()
+       tfast := rfast.NsPerOp()
+
+       // Optimization should be good for at least 2x, but be forgiving.
+       // On the ARM simulator we see closer to 1.5x.
+       speedup := float64(tslow)/float64(tfast)
+       want := 1.8
+       if runtime.GOARCH == "arm" {
+               want = 1.3
+       }
+       if speedup < want {
+               println("fast:", tfast, "slow:", tslow, "speedup:", speedup, "want:", want)
+               println("not fast enough")
+       }
+}