1
0
mirror of https://github.com/golang/go synced 2024-11-25 15:57:57 -07:00

cmd/gc: Inline pointer sized T2I interface conversions

This CL also adds support for marking the likelyness of IF nodes in the AST being true. This feature is being used here to mark the slow path as unlikely.

src/pkg/runtime:
benchmark                  old ns/op    new ns/op    delta
BenchmarkConvT2IUintptr           16            1  -91.63%

test/bench/go1:
benchmark                 old ns/op    new ns/op    delta
BenchmarkBinaryTree17    5416917000   5461355000   +0.82%
BenchmarkFannkuch11      3810355000   3842609000   +0.85%
BenchmarkGobDecode         19950950     19855420   -0.48%
BenchmarkGobEncode         11301220     11308530   +0.06%
BenchmarkGzip             548119600    546869200   -0.23%
BenchmarkGunzip           176145400    180208300   +2.31%
BenchmarkJSONEncode        93117400     70163100  -24.65%
BenchmarkJSONDecode       406626800    409999200   +0.83%
BenchmarkMandelbrot200      6300992      6317866   +0.27%
BenchmarkParse              7664396      7451625   -2.78%
BenchmarkRevcomp         1189424000   1412332000  +18.74%
BenchmarkTemplate         491308400    458654200   -6.65%

benchmark                  old MB/s     new MB/s  speedup
BenchmarkGobDecode            38.47        38.66    1.00x
BenchmarkGobEncode            67.92        67.87    1.00x
BenchmarkGzip                 35.40        35.48    1.00x
BenchmarkGunzip              110.16       107.68    0.98x
BenchmarkJSONEncode           20.84        27.66    1.33x
BenchmarkJSONDecode            4.77         4.73    0.99x
BenchmarkParse                 7.56         7.77    1.03x
BenchmarkRevcomp             213.69       179.96    0.84x
BenchmarkTemplate              3.95         4.23    1.07x

R=rsc, dave, nigeltao
CC=golang-dev
https://golang.org/cl/6351090
This commit is contained in:
Daniel Morsing 2012-09-11 21:42:30 +02:00
parent 0184081eb9
commit 8fd65b0e1d
6 changed files with 62 additions and 4 deletions

View File

@ -39,6 +39,7 @@ char *runtimeimport =
"func @\"\".stringiter2(? string, ? int) (@\"\".retk int, @\"\".retv rune)\n" "func @\"\".stringiter2(? string, ? int) (@\"\".retk int, @\"\".retv rune)\n"
"func @\"\".copy(@\"\".to any, @\"\".fr any, @\"\".wid uint32) (? int)\n" "func @\"\".copy(@\"\".to any, @\"\".fr any, @\"\".wid uint32) (? int)\n"
"func @\"\".slicestringcopy(@\"\".to any, @\"\".fr any) (? int)\n" "func @\"\".slicestringcopy(@\"\".to any, @\"\".fr any) (? int)\n"
"func @\"\".typ2Itab(@\"\".typ *byte, @\"\".typ2 *byte, @\"\".cache **byte) (@\"\".ret *byte)\n"
"func @\"\".convI2E(@\"\".elem any) (@\"\".ret any)\n" "func @\"\".convI2E(@\"\".elem any) (@\"\".ret any)\n"
"func @\"\".convI2I(@\"\".typ *byte, @\"\".elem any) (@\"\".ret any)\n" "func @\"\".convI2I(@\"\".typ *byte, @\"\".elem any) (@\"\".ret any)\n"
"func @\"\".convT2E(@\"\".typ *byte, @\"\".elem any) (@\"\".ret any)\n" "func @\"\".convT2E(@\"\".typ *byte, @\"\".elem any) (@\"\".ret any)\n"

View File

@ -410,7 +410,7 @@ gen(Node *n)
p1 = gjmp(P); // goto test p1 = gjmp(P); // goto test
p2 = gjmp(P); // p2: goto else p2 = gjmp(P); // p2: goto else
patch(p1, pc); // test: patch(p1, pc); // test:
bgen(n->ntest, 0, 0, p2); // if(!test) goto p2 bgen(n->ntest, 0, -n->likely, p2); // if(!test) goto p2
genlist(n->nbody); // then genlist(n->nbody); // then
p3 = gjmp(P); // goto done p3 = gjmp(P); // goto done
patch(p2, pc); // else: patch(p2, pc); // else:
@ -746,12 +746,17 @@ ret:
void void
cgen_eface(Node *n, Node *res) cgen_eface(Node *n, Node *res)
{ {
/*
* the right node of an eface may contain function calls that uses res as an argument,
* so it's important that it is done first
*/
Node dst; Node dst;
dst = *res; dst = *res;
dst.type = types[tptr]; dst.type = types[tptr];
cgen(n->left, &dst);
dst.xoffset += widthptr; dst.xoffset += widthptr;
cgen(n->right, &dst); cgen(n->right, &dst);
dst.xoffset -= widthptr;
cgen(n->left, &dst);
} }
/* /*

View File

@ -257,6 +257,7 @@ struct Node
uchar implicit; uchar implicit;
uchar addrtaken; // address taken, even if not moved to heap uchar addrtaken; // address taken, even if not moved to heap
uchar dupok; // duplicate definitions ok (for func) uchar dupok; // duplicate definitions ok (for func)
schar likely; // likeliness of if statement
// most nodes // most nodes
Type* type; Type* type;

View File

@ -59,6 +59,7 @@ func copy(to any, fr any, wid uint32) int
func slicestringcopy(to any, fr any) int func slicestringcopy(to any, fr any) int
// interface conversions // interface conversions
func typ2Itab(typ *byte, typ2 *byte, cache **byte) (ret *byte)
func convI2E(elem any) (ret any) func convI2E(elem any) (ret any)
func convI2I(typ *byte, elem any) (ret any) func convI2I(typ *byte, elem any) (ret any)
func convT2E(typ *byte, elem any) (ret any) func convT2E(typ *byte, elem any) (ret any)

View File

@ -374,7 +374,7 @@ walkexpr(Node **np, NodeList **init)
int et; int et;
int64 v; int64 v;
int32 lno; int32 lno;
Node *n, *fn; Node *n, *fn, *n1, *n2;
Sym *sym; Sym *sym;
char buf[100], *p; char buf[100], *p;
@ -771,6 +771,44 @@ walkexpr(Node **np, NodeList **init)
l = nod(OADDR, sym->def, N); l = nod(OADDR, sym->def, N);
l->addable = 1; l->addable = 1;
ll = list(ll, l); ll = list(ll, l);
if(n->left->type->width == widthptr &&
isint[simsimtype(n->left->type)]) {
/* For pointer types, we can make a special form of optimization
*
* These statements are put onto the expression init list:
* Itab *tab = atomicloadtype(&cache);
* if(tab == nil)
* tab = typ2Itab(type, itype, &cache);
*
* The CONVIFACE expression is replaced with this:
* OEFACE{tab, ptr};
*/
l = temp(ptrto(types[TUINT8]));
n1 = nod(OAS, l, sym->def);
typecheck(&n1, Etop);
*init = list(*init, n1);
fn = syslook("typ2Itab", 1);
n1 = nod(OCALL, fn, N);
n1->list = ll;
typecheck(&n1, Erv);
walkexpr(&n1, init);
n2 = nod(OIF, N, N);
n2->ntest = nod(OEQ, l, nodnil());
n2->nbody = list1(nod(OAS, l, n1));
n2->likely = -1;
typecheck(&n2, Etop);
*init = list(*init, n2);
l = nod(OEFACE, l, n->left);
l->typecheck = n->typecheck;
l->type = n->type;
n = l;
goto ret;
}
} }
ll = list(ll, n->left); ll = list(ll, n->left);
argtype(fn, n->left->type); argtype(fn, n->left->type);
@ -1168,7 +1206,7 @@ walkexpr(Node **np, NodeList **init)
else else
r = nod(OOROR, nod(ONE, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r); r = nod(OOROR, nod(ONE, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r);
typecheck(&r, Erv); typecheck(&r, Erv);
walkexpr(&r, nil); walkexpr(&r, init);
r->type = n->type; r->type = n->type;
n = r; n = r;
goto ret; goto ret;

View File

@ -183,6 +183,18 @@ copyout(Type *t, void **src, void *dst)
alg->copy(size, dst, *src); alg->copy(size, dst, *src);
} }
#pragma textflag 7
void
runtime·typ2Itab(Type *t, InterfaceType *inter, Itab **cache, Itab *ret)
{
Itab *tab;
tab = itab(inter, t, 0);
runtime·atomicstorep(cache, tab);
ret = tab;
FLUSH(&ret);
}
// func convT2I(typ *byte, typ2 *byte, cache **byte, elem any) (ret any) // func convT2I(typ *byte, typ2 *byte, cache **byte, elem any) (ret any)
#pragma textflag 7 #pragma textflag 7
void void