mirror of
https://github.com/golang/go
synced 2024-11-25 10:07:56 -07:00
code optimization on slices
R=rsc CC=golang-dev https://golang.org/cl/1942043
This commit is contained in:
parent
0d40e40f5e
commit
5b0c317c9c
@ -1008,6 +1008,43 @@ sgen(Node *n, Node *ns, int32 w)
|
|||||||
fatal("sgen UINF");
|
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)
|
if(w < 0)
|
||||||
fatal("sgen copy %d", w);
|
fatal("sgen copy %d", w);
|
||||||
|
|
||||||
|
@ -1041,6 +1041,34 @@ clearfat(Node *nl)
|
|||||||
if(debug['g'])
|
if(debug['g'])
|
||||||
dump("\nclearfat", nl);
|
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;
|
w = nl->type->width;
|
||||||
c = w % 8; // bytes
|
c = w % 8; // bytes
|
||||||
q = w / 8; // quads
|
q = w / 8; // quads
|
||||||
|
@ -1683,12 +1683,28 @@ optoas(int op, Type *t)
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ODynam = 1<<0,
|
ODynam = 1<<0,
|
||||||
|
OAddable = 1<<1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static Node clean[20];
|
static Node clean[20];
|
||||||
static int cleani = 0;
|
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
|
void
|
||||||
sudoclean(void)
|
sudoclean(void)
|
||||||
{
|
{
|
||||||
@ -1820,7 +1836,7 @@ oindex:
|
|||||||
if(l->type->etype != TARRAY)
|
if(l->type->etype != TARRAY)
|
||||||
fatal("not ary");
|
fatal("not ary");
|
||||||
if(l->type->bound < 0)
|
if(l->type->bound < 0)
|
||||||
o += ODynam;
|
o |= ODynam;
|
||||||
|
|
||||||
w = n->type->width;
|
w = n->type->width;
|
||||||
if(isconst(r, CTINT))
|
if(isconst(r, CTINT))
|
||||||
@ -1844,8 +1860,8 @@ oindex:
|
|||||||
|
|
||||||
// load the array (reg)
|
// load the array (reg)
|
||||||
if(l->ullman > r->ullman) {
|
if(l->ullman > r->ullman) {
|
||||||
regalloc(reg, types[tptr], N);
|
if(xgen(l, reg, o))
|
||||||
agen(l, reg);
|
o |= OAddable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the index (reg1)
|
// load the index (reg1)
|
||||||
@ -1860,17 +1876,17 @@ oindex:
|
|||||||
|
|
||||||
// load the array (reg)
|
// load the array (reg)
|
||||||
if(l->ullman <= r->ullman) {
|
if(l->ullman <= r->ullman) {
|
||||||
regalloc(reg, types[tptr], N);
|
if(xgen(l, reg, o))
|
||||||
agen(l, reg);
|
o |= OAddable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(o & ODynam) && l->type->width >= unmappedzero && l->op == OIND) {
|
if(!(o & ODynam) && l->type->width >= unmappedzero && l->op == OIND) {
|
||||||
// cannot rely on page protections to
|
// cannot rely on page protections to
|
||||||
// catch array ptr == 0, so dereference.
|
// catch array ptr == 0, so dereference.
|
||||||
n2 = *reg;
|
n2 = *reg;
|
||||||
|
n2.xoffset = 0;
|
||||||
n2.op = OINDREG;
|
n2.op = OINDREG;
|
||||||
n2.type = types[TUINT8];
|
n2.type = types[TUINT8];
|
||||||
n2.xoffset = 0;
|
|
||||||
gins(ATESTB, nodintconst(0), &n2);
|
gins(ATESTB, nodintconst(0), &n2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1880,15 +1896,27 @@ oindex:
|
|||||||
n4.op = OXXX;
|
n4.op = OXXX;
|
||||||
t = types[TUINT32];
|
t = types[TUINT32];
|
||||||
if(o & ODynam) {
|
if(o & ODynam) {
|
||||||
n2 = *reg;
|
if(o & OAddable) {
|
||||||
n2.op = OINDREG;
|
n2 = *l;
|
||||||
n2.type = types[TUINT32];
|
n2.xoffset += Array_nel;
|
||||||
n2.xoffset = Array_nel;
|
n2.type = types[TUINT32];
|
||||||
if(is64(r->type)) {
|
if(is64(r->type)) {
|
||||||
t = types[TUINT64];
|
t = types[TUINT64];
|
||||||
regalloc(&n4, t, N);
|
regalloc(&n4, t, N);
|
||||||
gmove(&n2, &n4);
|
gmove(&n2, &n4);
|
||||||
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 {
|
} else {
|
||||||
if(is64(r->type))
|
if(is64(r->type))
|
||||||
@ -1904,18 +1932,33 @@ oindex:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(o & ODynam) {
|
if(o & ODynam) {
|
||||||
n2 = *reg;
|
if(o & OAddable) {
|
||||||
n2.op = OINDREG;
|
n2 = *l;
|
||||||
n2.type = types[tptr];
|
n2.xoffset += Array_array;
|
||||||
n2.xoffset = Array_array;
|
n2.type = types[TUINT64];
|
||||||
gmove(&n2, reg);
|
gmove(&n2, reg);
|
||||||
|
} else {
|
||||||
|
n2 = *reg;
|
||||||
|
n2.xoffset = Array_array;
|
||||||
|
n2.op = OINDREG;
|
||||||
|
n2.type = types[tptr];
|
||||||
|
gmove(&n2, reg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
naddr(reg1, a, 1);
|
if(o & OAddable) {
|
||||||
a->offset = 0;
|
naddr(reg1, a, 1);
|
||||||
a->scale = w;
|
a->offset = 0;
|
||||||
a->index = a->type;
|
a->scale = w;
|
||||||
a->type = reg->val.u.reg + D_INDIR;
|
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;
|
goto yes;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user