Commit 3dc3ef4c authored by Ken Thompson's avatar Ken Thompson

attempt to gete better registeration

from the builtin structures (strings,
slices, interfaces)

R=rsc
CC=golang-dev
https://golang.org/cl/2007043
parent 1a667f52
......@@ -1008,46 +1008,13 @@ 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);
if(w == 16)
if(componentgen(n, ns))
return;
// offset on the stack
osrc = stkof(n);
odst = stkof(ns);
......@@ -1141,3 +1108,129 @@ sgen(Node *n, Node *ns, int32 w)
restx(&nodr, &oldr);
restx(&cx, &oldcx);
}
/*
* copy a structure component by component
* return 1 if can do, 0 if cant.
* nr is N for copy zero
*/
int
componentgen(Node *nr, Node *nl)
{
Node nodl, nodr;
int free;
free = 0;
if(!nl->addable || nl->op != ONAME)
goto no;
nodl = *nl;
if(nr != N) {
if(!nr->addable || nr->op != ONAME)
goto no;
nodr = *nr;
if(nr->op != ONAME && nr->op != OINDREG) {
igen(nr, &nodr, N);
free = 1;
}
}
switch(nl->type->etype) {
case TARRAY:
if(!isslice(nl->type))
goto no;
nodl.xoffset += Array_array;
nodl.type = ptrto(nl->type->type);
if(nr != N) {
nodr.xoffset += Array_array;
nodr.type = nodl.type;
} else
nodconst(&nodr, nodl.type, 0);
gmove(&nodr, &nodl);
nodl.xoffset += Array_nel-Array_array;
nodl.type = types[TUINT32];
if(nr != N) {
nodr.xoffset += Array_nel-Array_array;
nodr.type = nodl.type;
} else
nodconst(&nodr, nodl.type, 0);
gmove(&nodr, &nodl);
nodl.xoffset += Array_cap-Array_nel;
nodl.type = types[TUINT32];
if(nr != N) {
nodr.xoffset += Array_cap-Array_nel;
nodr.type = nodl.type;
} else
nodconst(&nodr, nodl.type, 0);
gmove(&nodr, &nodl);
goto yes;
case TSTRING:
nodl.xoffset += Array_array;
nodl.type = ptrto(types[TUINT8]);
if(nr != N) {
nodr.xoffset += Array_array;
nodr.type = nodl.type;
} else
nodconst(&nodr, nodl.type, 0);
gmove(&nodr, &nodl);
nodl.xoffset += Array_nel-Array_array;
nodl.type = types[TUINT32];
if(nr != N) {
nodr.xoffset += Array_nel-Array_array;
nodr.type = nodl.type;
} else
nodconst(&nodr, nodl.type, 0);
gmove(&nodr, &nodl);
goto yes;
case TINTER:
nodl.xoffset += Array_array;
nodl.type = ptrto(types[TUINT8]);
if(nr != N) {
nodr.xoffset += Array_array;
nodr.type = nodl.type;
} else
nodconst(&nodr, nodl.type, 0);
gmove(&nodr, &nodl);
nodl.xoffset += Array_nel-Array_array;
nodl.type = ptrto(types[TUINT8]);
if(nr != N) {
nodr.xoffset += Array_nel-Array_array;
nodr.type = nodl.type;
} else
nodconst(&nodr, nodl.type, 0);
gmove(&nodr, &nodl);
goto yes;
case TSTRUCT:
goto no;
}
no:
if(free)
regfree(&nodr);
return 0;
yes:
if(free)
regfree(&nodr);
return 1;
}
......@@ -99,6 +99,7 @@ void cgen_aret(Node*, Node*);
int cgen_inline(Node*, Node*);
void restx(Node*, Node*);
void savex(int, Node*, Node*, Node*, Type*);
int componentgen(Node*, Node*);
/*
* gsubr.c
......
......@@ -1041,35 +1041,12 @@ 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;
if(w == 16)
if(componentgen(N, nl))
return;
c = w % 8; // bytes
q = w / 8; // quads
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment