Using a zero register results in shorter, faster code.
5g already did this. Bring 6g, 8g, and 9g up to speed.
Reduces godoc binary size by 0.29% using 6g.
This CL includes cosmetic changes to 5g and 8g.
With those cosmetic changes included, componentgen is now
character-for-character equivalent across the four architectures.
Change-Id: I0e13dd48374bad830c725b117a1c86d4197d390c
Reviewed-on: https://go-review.googlesource.com/2606
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
/*
* copy a composite value by moving its individual components.
* Slices, strings and interfaces are supported.
+ * Small structs or arrays with elements of basic type are
+ * also supported.
* nr is N when assigning a zero value.
* return 1 if can do, 0 if cant.
*/
freer = 1;
}
-
// nl and nr are 'cadable' which basically means they are names (variables) now.
// If they are the same variable, don't generate any code, because the
// VARDEF we generate will mark the old value as dead incorrectly.
int
componentgen(Node *nr, Node *nl)
{
- Node nodl, nodr;
+ Node nodl, nodr, tmp;
Type *t;
int freel, freer;
vlong fldcount;
igen(nr, &nodr, N);
freer = 1;
}
+ } else {
+ // When zeroing, prepare a register containing zero.
+ nodconst(&tmp, nl->type, 0);
+ regalloc(&nodr, types[TUINT], N);
+ gmove(&tmp, &nodr);
+ freer = 1;
}
// nl and nr are 'cadable' which basically means they are names (variables) now.
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;
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;
if(nr != N) {
nodr.xoffset += Array_cap-Array_nel;
nodr.type = nodl.type;
- } else
- nodconst(&nodr, nodl.type, 0);
+ }
gmove(&nodr, &nodl);
goto yes;
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;
if(nr != N) {
nodr.xoffset += Array_nel-Array_array;
nodr.type = nodl.type;
- } else
- nodconst(&nodr, nodl.type, 0);
+ }
gmove(&nodr, &nodl);
goto yes;
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;
if(nr != N) {
nodr.xoffset += Array_nel-Array_array;
nodr.type = nodl.type;
- } else
- nodconst(&nodr, nodl.type, 0);
+ }
gmove(&nodr, &nodl);
goto yes;
/*
* copy a composite value by moving its individual components.
* Slices, strings and interfaces are supported.
+ * Small structs or arrays with elements of basic type are
+ * also supported.
* nr is N when assigning a zero value.
* return 1 if can do, 0 if can't.
*/
int
componentgen(Node *nr, Node *nl)
{
- Node nodl, nodr;
+ Node nodl, nodr, tmp;
Type *t;
int freel, freer;
vlong fldcount;
igen(nr, &nodr, N);
freer = 1;
}
+ } else {
+ // When zeroing, prepare a register containing zero.
+ nodconst(&tmp, nl->type, 0);
+ regalloc(&nodr, types[TUINT], N);
+ gmove(&tmp, &nodr);
+ freer = 1;
}
// nl and nr are 'cadable' which basically means they are names (variables) now.
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;
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;
if(nr != N) {
nodr.xoffset += Array_cap-Array_nel;
nodr.type = nodl.type;
- } else
- nodconst(&nodr, nodl.type, 0);
+ }
gmove(&nodr, &nodl);
goto yes;
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;
if(nr != N) {
nodr.xoffset += Array_nel-Array_array;
nodr.type = nodl.type;
- } else
- nodconst(&nodr, nodl.type, 0);
+ }
gmove(&nodr, &nodl);
goto yes;
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;
if(nr != N) {
nodr.xoffset += Array_nel-Array_array;
nodr.type = nodl.type;
- } else
- nodconst(&nodr, nodl.type, 0);
+ }
gmove(&nodr, &nodl);
goto yes;
int
componentgen(Node *nr, Node *nl)
{
- Node nodl, nodr;
+ Node nodl, nodr, tmp;
Type *t;
int freel, freer;
vlong fldcount;
igen(nr, &nodr, N);
freer = 1;
}
+ } else {
+ // When zeroing, prepare a register containing zero.
+ nodconst(&tmp, nl->type, 0);
+ regalloc(&nodr, types[TUINT], N);
+ gmove(&tmp, &nodr);
+ freer = 1;
}
// nl and nr are 'cadable' which basically means they are names (variables) now.
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;
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;
if(nr != N) {
nodr.xoffset += Array_cap-Array_nel;
nodr.type = nodl.type;
- } else
- nodconst(&nodr, nodl.type, 0);
+ }
gmove(&nodr, &nodl);
goto yes;
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;
if(nr != N) {
nodr.xoffset += Array_nel-Array_array;
nodr.type = nodl.type;
- } else
- nodconst(&nodr, nodl.type, 0);
+ }
gmove(&nodr, &nodl);
goto yes;
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;
if(nr != N) {
nodr.xoffset += Array_nel-Array_array;
nodr.type = nodl.type;
- } else
- nodconst(&nodr, nodl.type, 0);
+ }
gmove(&nodr, &nodl);
goto yes;