]> Cypherpunks repositories - gostls13.git/commitdiff
code optimization on slices
authorKen Thompson <ken@golang.org>
Sat, 14 Aug 2010 02:39:36 +0000 (19:39 -0700)
committerKen Thompson <ken@golang.org>
Sat, 14 Aug 2010 02:39:36 +0000 (19:39 -0700)
R=rsc
CC=golang-dev
https://golang.org/cl/1942043

src/cmd/6g/cgen.c
src/cmd/6g/ggen.c
src/cmd/6g/gsubr.c

index 1fee2476597be0bb809d14d7dce28b83eb3cf82d..20acae652d451d1a1370f032300da74617c1ede4 100644 (file)
@@ -1008,6 +1008,43 @@ sgen(Node *n, Node *ns, int32 w)
                fatal("sgen UINF");
        }
 
+       if(isslice(n->type))
+       if(isslice(ns->type))
+       if(n->addable)
+       if(ns->addable)
+       if(n->op != OINDREG)
+       if(ns->op != OINDREG)
+       if(n->op != OREGISTER)
+       if(ns->op != OREGISTER) {
+               // slices are done component by component
+               // to keep from confusing optimization
+               nodl = *ns;
+               nodl.xoffset += Array_array;
+               nodl.type = types[TUINT64];
+               nodr = *n;
+               nodr.xoffset += Array_array;
+               nodr.type = types[TUINT64];
+               gmove(&nodr, &nodl);
+
+               nodl = *ns;
+               nodl.xoffset += Array_nel;
+               nodl.type = types[TUINT32];
+               nodr = *n;
+               nodr.xoffset += Array_nel;
+               nodr.type = types[TUINT32];
+               gmove(&nodr, &nodl);
+
+               nodl = *ns;
+               nodl.xoffset += Array_cap;
+               nodl.type = types[TUINT32];
+               nodr = *n;
+               nodr.xoffset += Array_cap;
+               nodr.type = types[TUINT32];
+               gmove(&nodr, &nodl);
+
+               return;
+       }
+
        if(w < 0)
                fatal("sgen copy %d", w);
 
index 1e045da8ba2914d811a9e0c3d755bd828ffd63b5..7c3cadd50e41c9be71d6402c32c059c1353eb87d 100644 (file)
@@ -1041,6 +1041,34 @@ clearfat(Node *nl)
        if(debug['g'])
                dump("\nclearfat", nl);
 
+       if(isslice(nl->type))
+       if(nl->addable)
+       if(nl->op != OINDREG)
+       if(nl->op != OREGISTER) {
+               // slices are done component by component
+               // to keep from confusing optimization
+
+               n1 = *nl;
+               n1.xoffset += Array_array;
+               n1.type = types[TUINT64];
+               nodconst(&ax, types[TUINT64], 0);
+               gmove(&ax, &n1);
+
+               n1 = *nl;
+               n1.xoffset += Array_nel;
+               n1.type = types[TUINT32];
+               nodconst(&ax, types[TUINT32], 0);
+               gmove(&ax, &n1);
+
+               n1 = *nl;
+               n1.xoffset += Array_cap;
+               n1.type = types[TUINT32];
+               nodconst(&ax, types[TUINT32], 0);
+               gmove(&ax, &n1);
+
+               return;
+       }
+
        w = nl->type->width;
        c = w % 8;      // bytes
        q = w / 8;      // quads
index 51c9cac6545faf366e7ba553e002d21d05a8f276..e368dcad5094382751c6095eccbd55f9e3bfab5d 100644 (file)
@@ -1683,12 +1683,28 @@ optoas(int op, Type *t)
 
 enum
 {
-       ODynam  = 1<<0,
+       ODynam          = 1<<0,
+       OAddable        = 1<<1,
 };
 
 static Node    clean[20];
 static int     cleani = 0;
 
+int
+xgen(Node *n, Node *a, int o)
+{
+       regalloc(a, types[tptr], N);
+
+       if(o & ODynam)
+       if(n->addable)
+       if(n->op != OINDREG)
+       if(n->op != OREGISTER)
+               return 1;
+
+       agen(n, a);
+       return 0;
+}
+
 void
 sudoclean(void)
 {
@@ -1820,7 +1836,7 @@ oindex:
        if(l->type->etype != TARRAY)
                fatal("not ary");
        if(l->type->bound < 0)
-               o += ODynam;
+               o |= ODynam;
 
        w = n->type->width;
        if(isconst(r, CTINT))
@@ -1844,8 +1860,8 @@ oindex:
 
        // load the array (reg)
        if(l->ullman > r->ullman) {
-               regalloc(reg, types[tptr], N);
-               agen(l, reg);
+               if(xgen(l, reg, o))
+                       o |= OAddable;
        }
 
        // load the index (reg1)
@@ -1860,17 +1876,17 @@ oindex:
 
        // load the array (reg)
        if(l->ullman <= r->ullman) {
-               regalloc(reg, types[tptr], N);
-               agen(l, reg);
+               if(xgen(l, reg, o))
+                       o |= OAddable;
        }
 
        if(!(o & ODynam) && l->type->width >= unmappedzero && l->op == OIND) {
                // cannot rely on page protections to
                // catch array ptr == 0, so dereference.
                n2 = *reg;
+               n2.xoffset = 0;
                n2.op = OINDREG;
                n2.type = types[TUINT8];
-               n2.xoffset = 0;
                gins(ATESTB, nodintconst(0), &n2);
        }
 
@@ -1880,15 +1896,27 @@ oindex:
                n4.op = OXXX;
                t = types[TUINT32];
                if(o & ODynam) {
-                       n2 = *reg;
-                       n2.op = OINDREG;
-                       n2.type = types[TUINT32];
-                       n2.xoffset = Array_nel;
-                       if(is64(r->type)) {
-                               t = types[TUINT64];
-                               regalloc(&n4, t, N);
-                               gmove(&n2, &n4);
-                               n2 = n4;
+                       if(o & OAddable) {
+                               n2 = *l;
+                               n2.xoffset += Array_nel;
+                               n2.type = types[TUINT32];
+                               if(is64(r->type)) {
+                                       t = types[TUINT64];
+                                       regalloc(&n4, t, N);
+                                       gmove(&n2, &n4);
+                                       n2 = n4;
+                               }
+                       } else {
+                               n2 = *reg;
+                               n2.xoffset = Array_nel;
+                               n2.op = OINDREG;
+                               n2.type = types[TUINT32];
+                               if(is64(r->type)) {
+                                       t = types[TUINT64];
+                                       regalloc(&n4, t, N);
+                                       gmove(&n2, &n4);
+                                       n2 = n4;
+                               }
                        }
                } else {
                        if(is64(r->type))
@@ -1904,18 +1932,33 @@ oindex:
        }
 
        if(o & ODynam) {
-               n2 = *reg;
-               n2.op = OINDREG;
-               n2.type = types[tptr];
-               n2.xoffset = Array_array;
-               gmove(&n2, reg);
+               if(o & OAddable) {
+                       n2 = *l;
+                       n2.xoffset += Array_array;
+                       n2.type = types[TUINT64];
+                       gmove(&n2, reg);
+               } else {
+                       n2 = *reg;
+                       n2.xoffset = Array_array;
+                       n2.op = OINDREG;
+                       n2.type = types[tptr];
+                       gmove(&n2, reg);
+               }
        }
 
-       naddr(reg1, a, 1);
-       a->offset = 0;
-       a->scale = w;
-       a->index = a->type;
-       a->type = reg->val.u.reg + D_INDIR;
+       if(o & OAddable) {
+               naddr(reg1, a, 1);
+               a->offset = 0;
+               a->scale = w;
+               a->index = a->type;
+               a->type = reg->val.u.reg + D_INDIR;
+       } else {
+               naddr(reg1, a, 1);
+               a->offset = 0;
+               a->scale = w;
+               a->index = a->type;
+               a->type = reg->val.u.reg + D_INDIR;
+       }
 
        goto yes;