mirror of
https://github.com/golang/go
synced 2024-11-20 05:44:44 -07:00
cmd/6g, cmd/8g: add OINDREG, ODOT, ODOTPTR cases to igen.
Apart from reducing the number of LEAL/LEAQ instructions by about 30%, it gives 8g easier registerization in several cases, for example in strconv. Performance with 6g is not affected. Before (386): src/pkg/strconv/decimal.go:22 TEXT (*decimal).String+0(SB),$240-12 src/pkg/strconv/extfloat.go:540 TEXT (*extFloat).ShortestDecimal+0(SB),$584-20 After (386): src/pkg/strconv/decimal.go:22 TEXT (*decimal).String+0(SB),$196-12 src/pkg/strconv/extfloat.go:540 TEXT (*extFloat).ShortestDecimal+0(SB),$420-20 Benchmarks with GOARCH=386 (on a Core 2). benchmark old ns/op new ns/op delta BenchmarkBinaryTree17 7110191000 7079644000 -0.43% BenchmarkFannkuch11 7769274000 7766514000 -0.04% BenchmarkGobDecode 33454820 34755400 +3.89% BenchmarkGobEncode 11675710 11007050 -5.73% BenchmarkGzip 2013519000 1593855000 -20.84% BenchmarkGunzip 253368200 242667600 -4.22% BenchmarkJSONEncode 152443900 120763400 -20.78% BenchmarkJSONDecode 304112800 247461800 -18.63% BenchmarkMandelbrot200 29245520 29240490 -0.02% BenchmarkParse 8484105 8088660 -4.66% BenchmarkRevcomp 2695688000 2841263000 +5.40% BenchmarkTemplate 363759800 277271200 -23.78% benchmark old ns/op new ns/op delta BenchmarkAtof64Decimal 127 129 +1.57% BenchmarkAtof64Float 166 164 -1.20% BenchmarkAtof64FloatExp 308 300 -2.60% BenchmarkAtof64Big 584 571 -2.23% BenchmarkAppendFloatDecimal 440 430 -2.27% BenchmarkAppendFloat 995 776 -22.01% BenchmarkAppendFloatExp 897 746 -16.83% BenchmarkAppendFloatNegExp 900 752 -16.44% BenchmarkAppendFloatBig 1528 1228 -19.63% BenchmarkAppendFloat32Integer 443 453 +2.26% BenchmarkAppendFloat32ExactFraction 812 661 -18.60% BenchmarkAppendFloat32Point 1002 773 -22.85% BenchmarkAppendFloat32Exp 858 725 -15.50% BenchmarkAppendFloat32NegExp 848 728 -14.15% BenchmarkAppendFloat64Fixed1 447 431 -3.58% BenchmarkAppendFloat64Fixed2 480 462 -3.75% BenchmarkAppendFloat64Fixed3 461 457 -0.87% BenchmarkAppendFloat64Fixed4 509 484 -4.91% Update #1914. R=rsc, nigeltao CC=golang-dev, remy https://golang.org/cl/6494107
This commit is contained in:
parent
65c7dc4ace
commit
f4e76d5e02
@ -798,7 +798,7 @@ igen(Node *n, Node *a, Node *res)
|
||||
Type *fp;
|
||||
Iter flist;
|
||||
Node n1, n2;
|
||||
|
||||
|
||||
switch(n->op) {
|
||||
case ONAME:
|
||||
if((n->class&PHEAP) || n->class == PPARAMREF)
|
||||
@ -806,6 +806,39 @@ igen(Node *n, Node *a, Node *res)
|
||||
*a = *n;
|
||||
return;
|
||||
|
||||
case OINDREG:
|
||||
// Increase the refcount of the register so that igen's caller
|
||||
// has to call regfree.
|
||||
if(n->val.u.reg != D_SP)
|
||||
reg[n->val.u.reg]++;
|
||||
*a = *n;
|
||||
return;
|
||||
|
||||
case ODOT:
|
||||
igen(n->left, a, res);
|
||||
a->xoffset += n->xoffset;
|
||||
a->type = n->type;
|
||||
return;
|
||||
|
||||
case ODOTPTR:
|
||||
regalloc(a, types[tptr], res);
|
||||
cgen(n->left, a);
|
||||
if(n->xoffset != 0) {
|
||||
// explicit check for nil if struct is large enough
|
||||
// that we might derive too big a pointer.
|
||||
if(n->left->type->type->width >= unmappedzero) {
|
||||
n1 = *a;
|
||||
n1.op = OINDREG;
|
||||
n1.type = types[TUINT8];
|
||||
n1.xoffset = 0;
|
||||
gins(ATESTB, nodintconst(0), &n1);
|
||||
}
|
||||
}
|
||||
a->op = OINDREG;
|
||||
a->xoffset += n->xoffset;
|
||||
a->type = n->type;
|
||||
return;
|
||||
|
||||
case OCALLFUNC:
|
||||
fp = structfirst(&flist, getoutarg(n->left->type));
|
||||
cgen_call(n, 0);
|
||||
|
@ -342,9 +342,8 @@ cgen(Node *n, Node *res)
|
||||
}
|
||||
if(isslice(nl->type)) {
|
||||
igen(nl, &n1, res);
|
||||
n1.op = OINDREG;
|
||||
n1.type = types[TUINT32];
|
||||
n1.xoffset = Array_cap;
|
||||
n1.xoffset += Array_cap;
|
||||
gmove(&n1, res);
|
||||
regfree(&n1);
|
||||
break;
|
||||
@ -781,10 +780,10 @@ agen(Node *n, Node *res)
|
||||
void
|
||||
igen(Node *n, Node *a, Node *res)
|
||||
{
|
||||
Node n1;
|
||||
Type *fp;
|
||||
Iter flist;
|
||||
|
||||
Node n1;
|
||||
|
||||
switch(n->op) {
|
||||
case ONAME:
|
||||
if((n->class&PHEAP) || n->class == PPARAMREF)
|
||||
@ -792,6 +791,39 @@ igen(Node *n, Node *a, Node *res)
|
||||
*a = *n;
|
||||
return;
|
||||
|
||||
case OINDREG:
|
||||
// Increase the refcount of the register so that igen's caller
|
||||
// has to call regfree.
|
||||
if(n->val.u.reg != D_SP)
|
||||
reg[n->val.u.reg]++;
|
||||
*a = *n;
|
||||
return;
|
||||
|
||||
case ODOT:
|
||||
igen(n->left, a, res);
|
||||
a->xoffset += n->xoffset;
|
||||
a->type = n->type;
|
||||
return;
|
||||
|
||||
case ODOTPTR:
|
||||
regalloc(a, types[tptr], res);
|
||||
cgen(n->left, a);
|
||||
if(n->xoffset != 0) {
|
||||
// explicit check for nil if struct is large enough
|
||||
// that we might derive too big a pointer.
|
||||
if(n->left->type->type->width >= unmappedzero) {
|
||||
n1 = *a;
|
||||
n1.op = OINDREG;
|
||||
n1.type = types[TUINT8];
|
||||
n1.xoffset = 0;
|
||||
gins(ATESTB, nodintconst(0), &n1);
|
||||
}
|
||||
}
|
||||
a->op = OINDREG;
|
||||
a->xoffset += n->xoffset;
|
||||
a->type = n->type;
|
||||
return;
|
||||
|
||||
case OCALLFUNC:
|
||||
fp = structfirst(&flist, getoutarg(n->left->type));
|
||||
cgen_call(n, 0);
|
||||
|
@ -766,7 +766,7 @@ ginit(void)
|
||||
|
||||
for(i=0; i<nelem(reg); i++)
|
||||
reg[i] = 1;
|
||||
for(i=D_AL; i<=D_DI; i++)
|
||||
for(i=D_AX; i<=D_DI; i++)
|
||||
reg[i] = 0;
|
||||
for(i=0; i<nelem(resvd); i++)
|
||||
reg[resvd[i]]++;
|
||||
@ -782,7 +782,7 @@ gclean(void)
|
||||
for(i=0; i<nelem(resvd); i++)
|
||||
reg[resvd[i]]--;
|
||||
|
||||
for(i=D_AL; i<=D_DI; i++)
|
||||
for(i=D_AX; i<=D_DI; i++)
|
||||
if(reg[i])
|
||||
yyerror("reg %R left allocated at %ux", i, regpc[i]);
|
||||
}
|
||||
@ -792,7 +792,7 @@ anyregalloc(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for(i=D_AL; i<=D_DI; i++) {
|
||||
for(i=D_AX; i<=D_DI; i++) {
|
||||
if(reg[i] == 0)
|
||||
goto ok;
|
||||
for(j=0; j<nelem(resvd); j++)
|
||||
|
@ -170,11 +170,11 @@ struct Type
|
||||
vlong argwid;
|
||||
|
||||
// most nodes
|
||||
Type* type;
|
||||
vlong width; // offset in TFIELD, width in all others
|
||||
Type* type; // actual type for TFIELD, element type for TARRAY, TCHAN, TMAP, TPTRxx
|
||||
vlong width; // offset in TFIELD, width in all others
|
||||
|
||||
// TFIELD
|
||||
Type* down; // also used in TMAP
|
||||
Type* down; // next struct field, also key type in TMAP
|
||||
Strlit* note; // literal string annotation
|
||||
|
||||
// TARRAY
|
||||
|
Loading…
Reference in New Issue
Block a user