summaryrefslogtreecommitdiff
path: root/src/cmd/6g
diff options
context:
space:
mode:
authorKen Thompson <ken@golang.org>2010-08-19 18:18:51 -0700
committerKen Thompson <ken@golang.org>2010-08-19 18:18:51 -0700
commit53fec9ef6fbfde00e098d02f6cf2addc79333378 (patch)
tree54cd597c4b884e8e01541faeeb17ef65a232f930 /src/cmd/6g
parentc348d0b28f8c27b542faab6d2f714ef1aa80904e (diff)
downloadgo-53fec9ef6fbfde00e098d02f6cf2addc79333378.tar.gz
attempt to gete better registeration
from the builtin structures (strings, slices, interfaces) R=rsc CC=golang-dev http://codereview.appspot.com/2007043
Diffstat (limited to 'src/cmd/6g')
-rw-r--r--src/cmd/6g/cgen.c167
-rw-r--r--src/cmd/6g/gg.h1
-rw-r--r--src/cmd/6g/ggen.c31
3 files changed, 135 insertions, 64 deletions
diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c
index 20acae652..76776d702 100644
--- a/src/cmd/6g/cgen.c
+++ b/src/cmd/6g/cgen.c
@@ -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;
+}
diff --git a/src/cmd/6g/gg.h b/src/cmd/6g/gg.h
index 353a86dcd..d578d6752 100644
--- a/src/cmd/6g/gg.h
+++ b/src/cmd/6g/gg.h
@@ -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
diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c
index 7c3cadd50..f0aa16cb4 100644
--- a/src/cmd/6g/ggen.c
+++ b/src/cmd/6g/ggen.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