]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/8g: import componentgen from 6g.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Sun, 9 Sep 2012 18:30:08 +0000 (20:30 +0200)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Sun, 9 Sep 2012 18:30:08 +0000 (20:30 +0200)
This makes the compilers code more similar and improves
code generation a lot.

The number of LEAL instructions generated for cmd/go drops
by 60%.

% GOARCH=386 go build -gcflags -S -a cmd/go | grep LEAL | wc -l
Before:       89774
After:        47548

benchmark                              old ns/op    new ns/op    delta
BenchmarkAppendFloatDecimal                  540          444  -17.78%
BenchmarkAppendFloat                        1160         1035  -10.78%
BenchmarkAppendFloatExp                     1060          922  -13.02%
BenchmarkAppendFloatNegExp                  1053          920  -12.63%
BenchmarkAppendFloatBig                     1773         1558  -12.13%
BenchmarkFormatInt                         13065        12481   -4.47%
BenchmarkAppendInt                         10981         9900   -9.84%
BenchmarkFormatUint                         3804         3650   -4.05%
BenchmarkAppendUint                         3506         3303   -5.79%
BenchmarkUnquoteEasy                         714          683   -4.34%
BenchmarkUnquoteHard                        5117         2915  -43.03%

Update #1914.

R=nigeltao, rsc, golang-dev
CC=golang-dev, remy
https://golang.org/cl/6489067

src/cmd/8g/cgen.c
src/cmd/8g/gg.h
src/cmd/8g/ggen.c

index 1ae49acaa0fdf4dea139a4430f2c13b3e677b293..3ef75712c0206deb229183b3756e691ee2c6969c 100644 (file)
@@ -777,7 +777,7 @@ igen(Node *n, Node *a, Node *res)
                        break;
                *a = *n;
                return;
+
        case OCALLFUNC:
                fp = structfirst(&flist, getoutarg(n->left->type));
                cgen_call(n, 0);
@@ -1197,6 +1197,11 @@ sgen(Node *n, Node *res, int64 w)
                return;
        }
 
+       if (w == 8 || w == 12) {
+               if(componentgen(n, res))
+                       return;
+       }
+
        // offset on the stack
        osrc = stkof(n);
        odst = stkof(res);
@@ -1280,3 +1285,162 @@ sgen(Node *n, Node *res, int64 w)
        }
 }
 
+static int
+cadable(Node *n)
+{
+       if(!n->addable) {
+               // dont know how it happens,
+               // but it does
+               return 0;
+       }
+
+       switch(n->op) {
+       case ONAME:
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * copy a structure component by component
+ * return 1 if can do, 0 if cant.
+ * nr is N for copy zero
+ */
+int
+componentgen(Node *nr, Node *nl)
+{
+       Node nodl, nodr;
+       int freel, freer;
+
+       freel = 0;
+       freer = 0;
+
+       switch(nl->type->etype) {
+       default:
+               goto no;
+
+       case TARRAY:
+               if(!isslice(nl->type))
+                       goto no;
+       case TSTRING:
+       case TINTER:
+               break;
+       }
+
+       nodl = *nl;
+       if(!cadable(nl)) {
+               if(nr == N || !cadable(nr))
+                       goto no;
+               igen(nl, &nodl, N);
+               freel = 1;
+       }
+
+       if(nr != N) {
+               nodr = *nr;
+               if(!cadable(nr)) {
+                       igen(nr, &nodr, N);
+                       freer = 1;
+               }
+       }
+
+       switch(nl->type->etype) {
+       case TARRAY:
+               if(!isslice(nl->type))
+                       goto no;
+
+               nodl.xoffset += Array_array;
+               nodl.type = ptrto(nl->type->type);
+
+               if(nr != N) {
+                       nodr.xoffset += Array_array;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               nodl.xoffset += Array_nel-Array_array;
+               nodl.type = types[TUINT32];
+
+               if(nr != N) {
+                       nodr.xoffset += Array_nel-Array_array;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               nodl.xoffset += Array_cap-Array_nel;
+               nodl.type = types[TUINT32];
+
+               if(nr != N) {
+                       nodr.xoffset += Array_cap-Array_nel;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               goto yes;
+
+       case TSTRING:
+               nodl.xoffset += Array_array;
+               nodl.type = ptrto(types[TUINT8]);
+
+               if(nr != N) {
+                       nodr.xoffset += Array_array;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               nodl.xoffset += Array_nel-Array_array;
+               nodl.type = types[TUINT32];
+
+               if(nr != N) {
+                       nodr.xoffset += Array_nel-Array_array;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               goto yes;
+
+       case TINTER:
+               nodl.xoffset += Array_array;
+               nodl.type = ptrto(types[TUINT8]);
+
+               if(nr != N) {
+                       nodr.xoffset += Array_array;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               nodl.xoffset += Array_nel-Array_array;
+               nodl.type = ptrto(types[TUINT8]);
+
+               if(nr != N) {
+                       nodr.xoffset += Array_nel-Array_array;
+                       nodr.type = nodl.type;
+               } else
+                       nodconst(&nodr, nodl.type, 0);
+               gmove(&nodr, &nodl);
+
+               goto yes;
+
+       case TSTRUCT:
+               goto no;
+       }
+
+no:
+       if(freer)
+               regfree(&nodr);
+       if(freel)
+               regfree(&nodl);
+       return 0;
+
+yes:
+       if(freer)
+               regfree(&nodr);
+       if(freel)
+               regfree(&nodl);
+       return 1;
+}
index 12632f651c199da71c01432f5ec9e30f2f0b3783..a30c95d715fa457b9aff7dca25ee112fd6fb2dad 100644 (file)
@@ -107,6 +107,7 @@ void        cgen_aret(Node*, Node*);
 Node*  ncon(uint32);
 void   mgen(Node*, Node*, Node*);
 void   mfree(Node*);
+int    componentgen(Node*, Node*);
 
 /*
  * cgen64.c
index 749f913ef5ee4548a52d1a4a8a3ae34546cdd731..a31f660740c9dcfb101235801d25836fd57ad5f1 100644 (file)
@@ -59,6 +59,10 @@ clearfat(Node *nl)
                dump("\nclearfat", nl);
 
        w = nl->type->width;
+       if(w == 8 || w == 12)
+               if(componentgen(N, nl))
+                       return;
+
        c = w % 4;      // bytes
        q = w / 4;      // quads