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