1
0
mirror of https://github.com/golang/go synced 2024-11-25 16:17:56 -07:00

better job on 2007043

better registerization

R=rsc
CC=golang-dev
https://golang.org/cl/1955049
This commit is contained in:
Ken Thompson 2010-08-23 12:38:15 -07:00
parent 534dbc738f
commit 96cbdd62b6

View File

@ -1109,6 +1109,22 @@ sgen(Node *n, Node *ns, int32 w)
restx(&cx, &oldcx); restx(&cx, &oldcx);
} }
static int
cadable(Node *n)
{
if(!n->addable) {
// dont know how it happens,
// but it does
return 0;
}
switch(n->op) {
case ONAME:
return 1;
}
return 0;
}
/* /*
* copy a structure component by component * copy a structure component by component
* return 1 if can do, 0 if cant. * return 1 if can do, 0 if cant.
@ -1118,20 +1134,36 @@ int
componentgen(Node *nr, Node *nl) componentgen(Node *nr, Node *nl)
{ {
Node nodl, nodr; Node nodl, nodr;
int free; int freel, freer;
free = 0; freel = 0;
if(!nl->addable || nl->op != ONAME) freer = 0;
switch(nl->type->etype) {
default:
goto no; goto no;
nodl = *nl; case TARRAY:
if(nr != N) { if(!isslice(nl->type))
if(!nr->addable || nr->op != ONAME)
goto no; goto no;
case TSTRING:
case TINTER:
break;
}
nodl = *nl;
if(!cadable(nl)) {
if(nr == N || !cadable(nr))
goto no;
igen(nl, &nodl, N);
freel = 1;
}
if(nr != N) {
nodr = *nr; nodr = *nr;
if(nr->op != ONAME && nr->op != OINDREG) { if(!cadable(nr)) {
igen(nr, &nodr, N); igen(nr, &nodr, N);
free = 1; freer = 1;
} }
} }
@ -1173,7 +1205,6 @@ componentgen(Node *nr, Node *nl)
goto yes; goto yes;
case TSTRING: case TSTRING:
nodl.xoffset += Array_array; nodl.xoffset += Array_array;
nodl.type = ptrto(types[TUINT8]); nodl.type = ptrto(types[TUINT8]);
@ -1197,7 +1228,6 @@ componentgen(Node *nr, Node *nl)
goto yes; goto yes;
case TINTER: case TINTER:
nodl.xoffset += Array_array; nodl.xoffset += Array_array;
nodl.type = ptrto(types[TUINT8]); nodl.type = ptrto(types[TUINT8]);
@ -1225,12 +1255,16 @@ componentgen(Node *nr, Node *nl)
} }
no: no:
if(free) if(freer)
regfree(&nodr); regfree(&nodr);
if(freel)
regfree(&nodl);
return 0; return 0;
yes: yes:
if(free) if(freer)
regfree(&nodr); regfree(&nodr);
if(freel)
regfree(&nodl);
return 1; return 1;
} }