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

cmd/8g: do not take the address of string/slice for &s[i]

A similar change was made in 6g recently.

LEALs in cmd/go: 31440 before, 27867 after.

benchmark                 old ns/op    new ns/op    delta
BenchmarkBinaryTree17    7065794000   6723617000   -4.84%
BenchmarkFannkuch11      7767395000   7477945000   -3.73%
BenchmarkGobDecode         34708140     34857820   +0.43%
BenchmarkGobEncode         10998780     10960060   -0.35%
BenchmarkGzip            1603630000   1471052000   -8.27%
BenchmarkGunzip           242573900    240650400   -0.79%
BenchmarkJSONEncode       120842200    117966100   -2.38%
BenchmarkJSONDecode       247254900    249103100   +0.75%
BenchmarkMandelbrot200     29237330     29241790   +0.02%
BenchmarkParse              8111320      8096865   -0.18%
BenchmarkRevcomp         2595780000   2694153000   +3.79%
BenchmarkTemplate         276679600    264497000   -4.40%

benchmark                              old ns/op    new ns/op    delta
BenchmarkAppendFloatDecimal                  429          416   -3.03%
BenchmarkAppendFloat                         780          740   -5.13%
BenchmarkAppendFloatExp                      746          700   -6.17%
BenchmarkAppendFloatNegExp                   752          694   -7.71%
BenchmarkAppendFloatBig                     1228         1108   -9.77%
BenchmarkAppendFloat32Integer                457          416   -8.97%
BenchmarkAppendFloat32ExactFraction          662          631   -4.68%
BenchmarkAppendFloat32Point                  771          735   -4.67%
BenchmarkAppendFloat32Exp                    722          672   -6.93%
BenchmarkAppendFloat32NegExp                 724          659   -8.98%
BenchmarkAppendFloat64Fixed1                 429          400   -6.76%
BenchmarkAppendFloat64Fixed2                 463          442   -4.54%

Update #1914.

R=golang-dev, daniel.morsing, rsc
CC=golang-dev
https://golang.org/cl/6574043
This commit is contained in:
Rémy Oudompheng 2012-10-02 08:19:27 +02:00
parent 041fc8bf96
commit 2de064b63c
2 changed files with 78 additions and 78 deletions

View File

@ -456,23 +456,30 @@ flt2: // binary
} }
/* /*
* generate array index into res. * generate an addressable node in res, containing the value of n.
* n might be any size; res is 32-bit. * n is an array index, and might be any size; res width is <= 32-bit.
* returns Prog* to patch to panic call. * returns Prog* to patch to panic call.
*/ */
Prog* Prog*
cgenindex(Node *n, Node *res) igenindex(Node *n, Node *res)
{ {
Node tmp, lo, hi, zero; Node tmp, lo, hi, zero;
if(!is64(n->type)) { if(!is64(n->type)) {
cgen(n, res); if(n->addable) {
// nothing to do.
*res = *n;
} else {
tempname(res, types[TUINT32]);
cgen(n, res);
}
return nil; return nil;
} }
tempname(&tmp, types[TINT64]); tempname(&tmp, types[TINT64]);
cgen(n, &tmp); cgen(n, &tmp);
split64(&tmp, &lo, &hi); split64(&tmp, &lo, &hi);
tempname(res, types[TUINT32]);
gmove(&lo, res); gmove(&lo, res);
if(debug['B']) { if(debug['B']) {
splitclean(); splitclean();
@ -492,7 +499,7 @@ void
agen(Node *n, Node *res) agen(Node *n, Node *res)
{ {
Node *nl, *nr; Node *nl, *nr;
Node n1, n2, n3, n4, tmp; Node n1, n2, n3, n4, tmp, nlen;
Type *t; Type *t;
uint32 w; uint32 w;
uint64 v; uint64 v;
@ -574,109 +581,117 @@ agen(Node *n, Node *res)
p2 = nil; // to be patched to panicindex. p2 = nil; // to be patched to panicindex.
w = n->type->width; w = n->type->width;
if(nr->addable) { if(nr->addable) {
if(!isconst(nr, CTINT)) // Generate &nl first, and move nr into register.
tempname(&tmp, types[TINT32]);
if(!isconst(nl, CTSTR)) if(!isconst(nl, CTSTR))
agenr(nl, &n3, res); igen(nl, &n3, res);
if(!isconst(nr, CTINT)) { if(!isconst(nr, CTINT)) {
p2 = cgenindex(nr, &tmp); p2 = igenindex(nr, &tmp);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1); gmove(&tmp, &n1);
} }
} else if(nl->addable) { } else if(nl->addable) {
// Generate nr first, and move &nl into register.
if(!isconst(nr, CTINT)) { if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]); p2 = igenindex(nr, &tmp);
p2 = cgenindex(nr, &tmp);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1); gmove(&tmp, &n1);
} }
if(!isconst(nl, CTSTR)) { if(!isconst(nl, CTSTR))
regalloc(&n3, types[tptr], res); igen(nl, &n3, res);
agen(nl, &n3);
}
} else { } else {
tempname(&tmp, types[TINT32]); p2 = igenindex(nr, &tmp);
p2 = cgenindex(nr, &tmp);
nr = &tmp; nr = &tmp;
if(!isconst(nl, CTSTR)) if(!isconst(nl, CTSTR))
agenr(nl, &n3, res); igen(nl, &n3, res);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gins(optoas(OAS, tmp.type), &tmp, &n1); gins(optoas(OAS, tmp.type), &tmp, &n1);
} }
// &a is in &n3 (allocated in res) // For fixed array we really want the pointer in n3.
// i is in &n1 (if not constant) if(isfixedarray(nl->type)) {
regalloc(&n2, types[tptr], &n3);
agen(&n3, &n2);
regfree(&n3);
n3 = n2;
}
// &a[0] is in n3 (allocated in res)
// i is in n1 (if not constant)
// len(a) is in nlen (if needed)
// w is width // w is width
// explicit check for nil if array is large enough // explicit check for nil if array is large enough
// that we might derive too big a pointer. // that we might derive too big a pointer.
if(isfixedarray(nl->type) && nl->type->width >= unmappedzero) { if(isfixedarray(nl->type) && nl->type->width >= unmappedzero) {
regalloc(&n4, types[tptr], &n3); n4 = n3;
gmove(&n3, &n4);
n4.op = OINDREG; n4.op = OINDREG;
n4.type = types[TUINT8]; n4.type = types[TUINT8];
n4.xoffset = 0; n4.xoffset = 0;
gins(ATESTB, nodintconst(0), &n4); gins(ATESTB, nodintconst(0), &n4);
regfree(&n4);
} }
// constant index // constant index
if(isconst(nr, CTINT)) { if(isconst(nr, CTINT)) {
if(isconst(nl, CTSTR)) if(isconst(nl, CTSTR))
fatal("constant string constant index"); fatal("constant string constant index"); // front end should handle
v = mpgetfix(nr->val.u.xval); v = mpgetfix(nr->val.u.xval);
if(isslice(nl->type) || nl->type->etype == TSTRING) { if(isslice(nl->type) || nl->type->etype == TSTRING) {
if(!debug['B'] && !n->bounded) { if(!debug['B'] && !n->bounded) {
n1 = n3; nlen = n3;
n1.op = OINDREG; nlen.type = types[TUINT32];
n1.type = types[tptr]; nlen.xoffset += Array_nel;
n1.xoffset = Array_nel;
nodconst(&n2, types[TUINT32], v); nodconst(&n2, types[TUINT32], v);
gins(optoas(OCMP, types[TUINT32]), &n1, &n2); gins(optoas(OCMP, types[TUINT32]), &nlen, &n2);
p1 = gbranch(optoas(OGT, types[TUINT32]), T, +1); p1 = gbranch(optoas(OGT, types[TUINT32]), T, +1);
ginscall(panicindex, -1); ginscall(panicindex, -1);
patch(p1, pc); patch(p1, pc);
} }
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
n1.xoffset = Array_array;
gmove(&n1, &n3);
} }
if (v*w != 0) { // Load base pointer in n2 = n3.
nodconst(&n2, types[tptr], v*w); regalloc(&n2, types[tptr], &n3);
gins(optoas(OADD, types[tptr]), &n2, &n3); n3.type = types[tptr];
} n3.xoffset += Array_array;
gmove(&n3, res); gmove(&n3, &n2);
regfree(&n3); regfree(&n3);
if (v*w != 0) {
nodconst(&n1, types[tptr], v*w);
gins(optoas(OADD, types[tptr]), &n1, &n2);
}
gmove(&n2, res);
regfree(&n2);
break; break;
} }
regalloc(&n2, types[TINT32], &n1); // i // i is in register n1, extend to 32 bits.
t = types[TUINT32];
if(issigned[n1.type->etype])
t = types[TINT32];
regalloc(&n2, t, &n1); // i
gmove(&n1, &n2); gmove(&n1, &n2);
regfree(&n1); regfree(&n1);
if(!debug['B'] && !n->bounded) { if(!debug['B'] && !n->bounded) {
// check bounds // check bounds
if(isconst(nl, CTSTR)) t = types[TUINT32];
nodconst(&n1, types[TUINT32], nl->val.u.sval->len); if(isconst(nl, CTSTR)) {
else if(isslice(nl->type) || nl->type->etype == TSTRING) { nodconst(&nlen, t, nl->val.u.sval->len);
n1 = n3; } else if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1.op = OINDREG; nlen = n3;
n1.type = types[tptr]; nlen.type = t;
n1.xoffset = Array_nel; nlen.xoffset += Array_nel;
} else } else {
nodconst(&n1, types[TUINT32], nl->type->bound); nodconst(&nlen, t, nl->type->bound);
gins(optoas(OCMP, types[TUINT32]), &n2, &n1); }
p1 = gbranch(optoas(OLT, types[TUINT32]), T, +1); gins(optoas(OCMP, t), &n2, &nlen);
p1 = gbranch(optoas(OLT, t), T, +1);
if(p2) if(p2)
patch(p2, pc); patch(p2, pc);
ginscall(panicindex, -1); ginscall(panicindex, -1);
patch(p1, pc); patch(p1, pc);
} }
if(isconst(nl, CTSTR)) { if(isconst(nl, CTSTR)) {
regalloc(&n3, types[tptr], res); regalloc(&n3, types[tptr], res);
p1 = gins(ALEAL, N, &n3); p1 = gins(ALEAL, N, &n3);
@ -686,24 +701,27 @@ agen(Node *n, Node *res)
goto indexdone; goto indexdone;
} }
// Load base pointer in n3.
regalloc(&tmp, types[tptr], &n3);
if(isslice(nl->type) || nl->type->etype == TSTRING) { if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3; n3.type = types[tptr];
n1.op = OINDREG; n3.xoffset += Array_array;
n1.type = types[tptr]; gmove(&n3, &tmp);
n1.xoffset = Array_array;
gmove(&n1, &n3);
} }
regfree(&n3);
n3 = tmp;
if(w == 0) { if(w == 0) {
// nothing to do // nothing to do
} else if(w == 1 || w == 2 || w == 4 || w == 8) { } else if(w == 1 || w == 2 || w == 4 || w == 8) {
// LEAL (n3)(n2*w), n3
p1 = gins(ALEAL, &n2, &n3); p1 = gins(ALEAL, &n2, &n3);
p1->from.scale = w; p1->from.scale = w;
p1->from.index = p1->from.type; p1->from.index = p1->from.type;
p1->from.type = p1->to.type + D_INDIR; p1->from.type = p1->to.type + D_INDIR;
} else { } else {
nodconst(&n1, types[TUINT32], w); nodconst(&tmp, types[TUINT32], w);
gins(optoas(OMUL, types[TUINT32]), &n1, &n2); gins(optoas(OMUL, types[TUINT32]), &tmp, &n2);
gins(optoas(OADD, types[tptr]), &n2, &n3); gins(optoas(OADD, types[tptr]), &n2, &n3);
} }
@ -861,23 +879,6 @@ igen(Node *n, Node *a, Node *res)
a->type = n->type; a->type = n->type;
} }
/*
* generate:
* newreg = &n;
*
* caller must regfree(a).
*/
void
agenr(Node *n, Node *a, Node *res)
{
Node n1;
tempname(&n1, types[tptr]);
agen(n, &n1);
regalloc(a, types[tptr], res);
gmove(&n1, a);
}
/* /*
* branch gen * branch gen
* if(n == true) goto to; * if(n == true) goto to;

View File

@ -95,7 +95,6 @@ void ginscall(Node*, int);
* cgen.c * cgen.c
*/ */
void agen(Node*, Node*); void agen(Node*, Node*);
void agenr(Node *n, Node *a, Node *res);
void igen(Node*, Node*, Node*); void igen(Node*, Node*, Node*);
vlong fieldoffset(Type*, Node*); vlong fieldoffset(Type*, Node*);
void sgen(Node*, Node*, int64); void sgen(Node*, Node*, int64);