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:
parent
b737644266
commit
ae0862c1ec
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user