mirror of
https://github.com/golang/go
synced 2024-11-22 02:54:39 -07:00
bug in 6g optimizer
8g still needs fixing R=rsc https://golang.org/cl/176057
This commit is contained in:
parent
97a08f7a81
commit
cd00bc78da
@ -1049,6 +1049,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||||||
case OLEN:
|
case OLEN:
|
||||||
// len of string or slice
|
// len of string or slice
|
||||||
naddr(n->left, a, canemitcode);
|
naddr(n->left, a, canemitcode);
|
||||||
|
a->etype = TUINT;
|
||||||
a->offset += Array_nel;
|
a->offset += Array_nel;
|
||||||
if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
|
if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
|
||||||
checkoffset(a, canemitcode);
|
checkoffset(a, canemitcode);
|
||||||
@ -1057,6 +1058,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||||||
case OCAP:
|
case OCAP:
|
||||||
// cap of string or slice
|
// cap of string or slice
|
||||||
naddr(n->left, a, canemitcode);
|
naddr(n->left, a, canemitcode);
|
||||||
|
a->etype = TUINT;
|
||||||
a->offset += Array_cap;
|
a->offset += Array_cap;
|
||||||
if(a->offset >= unmappedzero && a->offset-Array_cap < unmappedzero)
|
if(a->offset >= unmappedzero && a->offset-Array_cap < unmappedzero)
|
||||||
checkoffset(a, canemitcode);
|
checkoffset(a, canemitcode);
|
||||||
|
107
src/cmd/6g/reg.c
107
src/cmd/6g/reg.c
@ -67,7 +67,7 @@ rcmp(const void *a1, const void *a2)
|
|||||||
return p2->varno - p1->varno;
|
return p2->varno - p1->varno;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
setoutvar(void)
|
setoutvar(void)
|
||||||
{
|
{
|
||||||
Type *t;
|
Type *t;
|
||||||
@ -91,6 +91,13 @@ setoutvar(void)
|
|||||||
//print("ovars = %Q\n", &ovar);
|
//print("ovars = %Q\n", &ovar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setaddrs(Bits bit)
|
||||||
|
{
|
||||||
|
if(bany(&bit))
|
||||||
|
var[bnum(bit)].addr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
regopt(Prog *firstp)
|
regopt(Prog *firstp)
|
||||||
{
|
{
|
||||||
@ -181,8 +188,7 @@ regopt(Prog *firstp)
|
|||||||
*/
|
*/
|
||||||
case ALEAL:
|
case ALEAL:
|
||||||
case ALEAQ:
|
case ALEAQ:
|
||||||
for(z=0; z<BITS; z++)
|
setaddrs(bit);
|
||||||
addrs.b[z] |= bit.b[z];
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -378,8 +384,7 @@ regopt(Prog *firstp)
|
|||||||
* funny
|
* funny
|
||||||
*/
|
*/
|
||||||
case ACALL:
|
case ACALL:
|
||||||
for(z=0; z<BITS; z++)
|
setaddrs(bit);
|
||||||
addrs.b[z] |= bit.b[z];
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,6 +458,18 @@ regopt(Prog *firstp)
|
|||||||
if(firstr == R)
|
if(firstr == R)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
for(i=0; i<nvar; i++) {
|
||||||
|
Var *v = var+i;
|
||||||
|
if(v->addr) {
|
||||||
|
bit = blsh(i);
|
||||||
|
for(z=0; z<BITS; z++)
|
||||||
|
addrs.b[z] |= bit.b[z];
|
||||||
|
}
|
||||||
|
|
||||||
|
// print("bit=%2d addr=%d et=%-6E w=%-2d s=%S + %lld\n",
|
||||||
|
// i, v->addr, v->etype, v->width, v->sym, v->offset);
|
||||||
|
}
|
||||||
|
|
||||||
if(debug['R'] && debug['v'])
|
if(debug['R'] && debug['v'])
|
||||||
dumpit("pass1", firstr);
|
dumpit("pass1", firstr);
|
||||||
|
|
||||||
@ -768,31 +785,16 @@ doregbits(int r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
overlap(Var *v, int o2, int w2)
|
overlap(int32 o1, int w1, int32 o2, int w2)
|
||||||
{
|
{
|
||||||
int o1, w1, t1, t2, z;
|
int32 t1, t2;
|
||||||
Bits bit;
|
|
||||||
|
|
||||||
o1 = v->offset;
|
|
||||||
w1 = v->width;
|
|
||||||
t1 = o1+w1;
|
t1 = o1+w1;
|
||||||
t2 = o2+w2;
|
t2 = o2+w2;
|
||||||
|
|
||||||
if(!(t1 > o2 && t2 > o1))
|
if(!(t1 > o2 && t2 > o1))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// set to max extent
|
|
||||||
if(o2 < o1)
|
|
||||||
v->offset = o2;
|
|
||||||
if(t1 > t2)
|
|
||||||
v->width = t1-v->offset;
|
|
||||||
else
|
|
||||||
v->width = t2-v->offset;
|
|
||||||
|
|
||||||
// and dont registerize
|
|
||||||
bit = blsh(v-var);
|
|
||||||
for(z=0; z<BITS; z++)
|
|
||||||
addrs.b[z] |= bit.b[z];
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,6 +811,9 @@ mkvar(Reg *r, Adr *a)
|
|||||||
* mark registers used
|
* mark registers used
|
||||||
*/
|
*/
|
||||||
t = a->type;
|
t = a->type;
|
||||||
|
if(t == D_NONE)
|
||||||
|
goto none;
|
||||||
|
|
||||||
if(r != R) {
|
if(r != R) {
|
||||||
r->regu |= doregbits(t);
|
r->regu |= doregbits(t);
|
||||||
r->regu |= doregbits(a->index);
|
r->regu |= doregbits(a->index);
|
||||||
@ -817,14 +822,15 @@ mkvar(Reg *r, Adr *a)
|
|||||||
switch(t) {
|
switch(t) {
|
||||||
default:
|
default:
|
||||||
goto none;
|
goto none;
|
||||||
|
|
||||||
case D_ADDR:
|
case D_ADDR:
|
||||||
a->type = a->index;
|
a->type = a->index;
|
||||||
bit = mkvar(r, a);
|
bit = mkvar(r, a);
|
||||||
for(z=0; z<BITS; z++)
|
setaddrs(bit);
|
||||||
addrs.b[z] |= bit.b[z];
|
|
||||||
a->type = t;
|
a->type = t;
|
||||||
ostats.naddr++;
|
ostats.naddr++;
|
||||||
goto none;
|
goto none;
|
||||||
|
|
||||||
case D_EXTERN:
|
case D_EXTERN:
|
||||||
case D_STATIC:
|
case D_STATIC:
|
||||||
case D_PARAM:
|
case D_PARAM:
|
||||||
@ -840,32 +846,30 @@ mkvar(Reg *r, Adr *a)
|
|||||||
et = a->etype;
|
et = a->etype;
|
||||||
o = a->offset;
|
o = a->offset;
|
||||||
w = a->width;
|
w = a->width;
|
||||||
v = var;
|
|
||||||
|
|
||||||
flag = 0;
|
flag = 0;
|
||||||
for(i=0; i<nvar; i++) {
|
for(i=0; i<nvar; i++) {
|
||||||
if(s == v->sym)
|
v = var+i;
|
||||||
if(n == v->name) {
|
if(v->sym == s && v->name == n) {
|
||||||
// if it is the same, use it
|
if(v->offset == o) {
|
||||||
if(v->etype == et)
|
// if it is the same, use it
|
||||||
if(v->width == w)
|
if(v->etype != et||
|
||||||
if(v->offset == o)
|
v->width != w)
|
||||||
goto out;
|
v->addr = 1;
|
||||||
|
return blsh(i);
|
||||||
|
}
|
||||||
|
|
||||||
// if it overlaps, set max
|
// if it overlaps, disable bothj
|
||||||
// width and dont registerize
|
if(overlap(v->offset, v->width, o, w)) {
|
||||||
if(overlap(v, o, w))
|
v->addr = 1;
|
||||||
flag = 1;
|
flag = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
v++;
|
|
||||||
}
|
}
|
||||||
if(flag)
|
|
||||||
goto none;
|
|
||||||
|
|
||||||
switch(et) {
|
switch(et) {
|
||||||
case 0:
|
case 0:
|
||||||
case TFUNC:
|
case TFUNC:
|
||||||
case TARRAY:
|
|
||||||
goto none;
|
goto none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -874,9 +878,10 @@ mkvar(Reg *r, Adr *a)
|
|||||||
fatal("variable not optimized: %D", a);
|
fatal("variable not optimized: %D", a);
|
||||||
goto none;
|
goto none;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = nvar;
|
i = nvar;
|
||||||
nvar++;
|
nvar++;
|
||||||
v = &var[i];
|
v = var+i;
|
||||||
v->sym = s;
|
v->sym = s;
|
||||||
v->offset = o;
|
v->offset = o;
|
||||||
v->name = n;
|
v->name = n;
|
||||||
@ -884,24 +889,10 @@ mkvar(Reg *r, Adr *a)
|
|||||||
v->etype = et;
|
v->etype = et;
|
||||||
v->width = w;
|
v->width = w;
|
||||||
if(debug['R'])
|
if(debug['R'])
|
||||||
print("bit=%2d et=%2d w=%d %D\n", i, et, w, a);
|
print("bit=%2d et=%2d w=%d %S %D\n", i, et, w, s, a);
|
||||||
ostats.nvar++;
|
ostats.nvar++;
|
||||||
|
|
||||||
out:
|
|
||||||
bit = blsh(i);
|
bit = blsh(i);
|
||||||
|
|
||||||
// funny punning
|
|
||||||
if(v->etype != et) {
|
|
||||||
if(debug['R'])
|
|
||||||
print("pun et=%d/%d w=%d/%d o=%d/%d %D\n",
|
|
||||||
v->etype, et,
|
|
||||||
v->width, w,
|
|
||||||
v->offset, o, a);
|
|
||||||
for(z=0; z<BITS; z++)
|
|
||||||
addrs.b[z] |= bit.b[z];
|
|
||||||
goto none;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(n == D_EXTERN || n == D_STATIC)
|
if(n == D_EXTERN || n == D_STATIC)
|
||||||
for(z=0; z<BITS; z++)
|
for(z=0; z<BITS; z++)
|
||||||
externs.b[z] |= bit.b[z];
|
externs.b[z] |= bit.b[z];
|
||||||
@ -909,6 +900,10 @@ out:
|
|||||||
for(z=0; z<BITS; z++)
|
for(z=0; z<BITS; z++)
|
||||||
params.b[z] |= bit.b[z];
|
params.b[z] |= bit.b[z];
|
||||||
|
|
||||||
|
// funny punning
|
||||||
|
if(flag)
|
||||||
|
v->addr = 1;
|
||||||
|
|
||||||
return bit;
|
return bit;
|
||||||
|
|
||||||
none:
|
none:
|
||||||
|
@ -1769,6 +1769,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||||||
case OLEN:
|
case OLEN:
|
||||||
// len of string or slice
|
// len of string or slice
|
||||||
naddr(n->left, a, canemitcode);
|
naddr(n->left, a, canemitcode);
|
||||||
|
a->etype = TUINT;
|
||||||
a->offset += Array_nel;
|
a->offset += Array_nel;
|
||||||
if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
|
if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
|
||||||
checkoffset(a, canemitcode);
|
checkoffset(a, canemitcode);
|
||||||
@ -1777,6 +1778,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||||||
case OCAP:
|
case OCAP:
|
||||||
// cap of string or slice
|
// cap of string or slice
|
||||||
naddr(n->left, a, canemitcode);
|
naddr(n->left, a, canemitcode);
|
||||||
|
a->etype = TUINT;
|
||||||
a->offset += Array_cap;
|
a->offset += Array_cap;
|
||||||
if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
|
if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
|
||||||
checkoffset(a, canemitcode);
|
checkoffset(a, canemitcode);
|
||||||
|
@ -513,6 +513,7 @@ struct Var
|
|||||||
int width;
|
int width;
|
||||||
char name;
|
char name;
|
||||||
char etype;
|
char etype;
|
||||||
|
char addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
EXTERN Var var[NVAR];
|
EXTERN Var var[NVAR];
|
||||||
|
Loading…
Reference in New Issue
Block a user