1
0
mirror of https://github.com/golang/go synced 2024-11-12 04:40:22 -07:00

cmd/8g: import componentgen from 6g.

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
This commit is contained in:
Rémy Oudompheng 2012-09-09 20:30:08 +02:00
parent b737644266
commit ae0862c1ec
3 changed files with 170 additions and 1 deletions

View 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;
}

View 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

View 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