From: Ken Thompson Date: Sat, 14 Aug 2010 02:39:36 +0000 (-0700) Subject: code optimization on slices X-Git-Tag: weekly.2010-08-25~56 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5b0c317c9c1aae37d9e58959946b6750efd4f793;p=gostls13.git code optimization on slices R=rsc CC=golang-dev https://golang.org/cl/1942043 --- diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c index 1fee247659..20acae652d 100644 --- a/src/cmd/6g/cgen.c +++ b/src/cmd/6g/cgen.c @@ -1008,6 +1008,43 @@ sgen(Node *n, Node *ns, int32 w) fatal("sgen UINF"); } + if(isslice(n->type)) + if(isslice(ns->type)) + if(n->addable) + if(ns->addable) + if(n->op != OINDREG) + if(ns->op != OINDREG) + if(n->op != OREGISTER) + if(ns->op != OREGISTER) { + // slices are done component by component + // to keep from confusing optimization + nodl = *ns; + nodl.xoffset += Array_array; + nodl.type = types[TUINT64]; + nodr = *n; + nodr.xoffset += Array_array; + nodr.type = types[TUINT64]; + gmove(&nodr, &nodl); + + nodl = *ns; + nodl.xoffset += Array_nel; + nodl.type = types[TUINT32]; + nodr = *n; + nodr.xoffset += Array_nel; + nodr.type = types[TUINT32]; + gmove(&nodr, &nodl); + + nodl = *ns; + nodl.xoffset += Array_cap; + nodl.type = types[TUINT32]; + nodr = *n; + nodr.xoffset += Array_cap; + nodr.type = types[TUINT32]; + gmove(&nodr, &nodl); + + return; + } + if(w < 0) fatal("sgen copy %d", w); diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c index 1e045da8ba..7c3cadd50e 100644 --- a/src/cmd/6g/ggen.c +++ b/src/cmd/6g/ggen.c @@ -1041,6 +1041,34 @@ clearfat(Node *nl) if(debug['g']) dump("\nclearfat", nl); + if(isslice(nl->type)) + if(nl->addable) + if(nl->op != OINDREG) + if(nl->op != OREGISTER) { + // slices are done component by component + // to keep from confusing optimization + + n1 = *nl; + n1.xoffset += Array_array; + n1.type = types[TUINT64]; + nodconst(&ax, types[TUINT64], 0); + gmove(&ax, &n1); + + n1 = *nl; + n1.xoffset += Array_nel; + n1.type = types[TUINT32]; + nodconst(&ax, types[TUINT32], 0); + gmove(&ax, &n1); + + n1 = *nl; + n1.xoffset += Array_cap; + n1.type = types[TUINT32]; + nodconst(&ax, types[TUINT32], 0); + gmove(&ax, &n1); + + return; + } + w = nl->type->width; c = w % 8; // bytes q = w / 8; // quads diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c index 51c9cac654..e368dcad50 100644 --- a/src/cmd/6g/gsubr.c +++ b/src/cmd/6g/gsubr.c @@ -1683,12 +1683,28 @@ optoas(int op, Type *t) enum { - ODynam = 1<<0, + ODynam = 1<<0, + OAddable = 1<<1, }; static Node clean[20]; static int cleani = 0; +int +xgen(Node *n, Node *a, int o) +{ + regalloc(a, types[tptr], N); + + if(o & ODynam) + if(n->addable) + if(n->op != OINDREG) + if(n->op != OREGISTER) + return 1; + + agen(n, a); + return 0; +} + void sudoclean(void) { @@ -1820,7 +1836,7 @@ oindex: if(l->type->etype != TARRAY) fatal("not ary"); if(l->type->bound < 0) - o += ODynam; + o |= ODynam; w = n->type->width; if(isconst(r, CTINT)) @@ -1844,8 +1860,8 @@ oindex: // load the array (reg) if(l->ullman > r->ullman) { - regalloc(reg, types[tptr], N); - agen(l, reg); + if(xgen(l, reg, o)) + o |= OAddable; } // load the index (reg1) @@ -1860,17 +1876,17 @@ oindex: // load the array (reg) if(l->ullman <= r->ullman) { - regalloc(reg, types[tptr], N); - agen(l, reg); + if(xgen(l, reg, o)) + o |= OAddable; } if(!(o & ODynam) && l->type->width >= unmappedzero && l->op == OIND) { // cannot rely on page protections to // catch array ptr == 0, so dereference. n2 = *reg; + n2.xoffset = 0; n2.op = OINDREG; n2.type = types[TUINT8]; - n2.xoffset = 0; gins(ATESTB, nodintconst(0), &n2); } @@ -1880,15 +1896,27 @@ oindex: n4.op = OXXX; t = types[TUINT32]; if(o & ODynam) { - n2 = *reg; - n2.op = OINDREG; - n2.type = types[TUINT32]; - n2.xoffset = Array_nel; - if(is64(r->type)) { - t = types[TUINT64]; - regalloc(&n4, t, N); - gmove(&n2, &n4); - n2 = n4; + if(o & OAddable) { + n2 = *l; + n2.xoffset += Array_nel; + n2.type = types[TUINT32]; + if(is64(r->type)) { + t = types[TUINT64]; + regalloc(&n4, t, N); + gmove(&n2, &n4); + n2 = n4; + } + } else { + n2 = *reg; + n2.xoffset = Array_nel; + n2.op = OINDREG; + n2.type = types[TUINT32]; + if(is64(r->type)) { + t = types[TUINT64]; + regalloc(&n4, t, N); + gmove(&n2, &n4); + n2 = n4; + } } } else { if(is64(r->type)) @@ -1904,18 +1932,33 @@ oindex: } if(o & ODynam) { - n2 = *reg; - n2.op = OINDREG; - n2.type = types[tptr]; - n2.xoffset = Array_array; - gmove(&n2, reg); + if(o & OAddable) { + n2 = *l; + n2.xoffset += Array_array; + n2.type = types[TUINT64]; + gmove(&n2, reg); + } else { + n2 = *reg; + n2.xoffset = Array_array; + n2.op = OINDREG; + n2.type = types[tptr]; + gmove(&n2, reg); + } } - naddr(reg1, a, 1); - a->offset = 0; - a->scale = w; - a->index = a->type; - a->type = reg->val.u.reg + D_INDIR; + if(o & OAddable) { + naddr(reg1, a, 1); + a->offset = 0; + a->scale = w; + a->index = a->type; + a->type = reg->val.u.reg + D_INDIR; + } else { + naddr(reg1, a, 1); + a->offset = 0; + a->scale = w; + a->index = a->type; + a->type = reg->val.u.reg + D_INDIR; + } goto yes;