Commit cd00bc78 authored by Ken Thompson's avatar Ken Thompson

bug in 6g optimizer

8g still needs fixing

R=rsc
https://golang.org/cl/176057
parent 97a08f7a
...@@ -1049,6 +1049,7 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -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) ...@@ -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);
......
...@@ -67,7 +67,7 @@ rcmp(const void *a1, const void *a2) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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(v->offset == o) {
// if it is the same, use it // if it is the same, use it
if(v->etype == et) if(v->etype != et||
if(v->width == w) v->width != w)
if(v->offset == o) v->addr = 1;
goto out; return blsh(i);
}
// if it overlaps, set max
// width and dont registerize // if it overlaps, disable bothj
if(overlap(v, o, w)) if(overlap(v->offset, v->width, 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) ...@@ -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) ...@@ -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: ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment