diff options
author | Ken Thompson <ken@golang.org> | 2009-12-11 15:55:09 -0800 |
---|---|---|
committer | Ken Thompson <ken@golang.org> | 2009-12-11 15:55:09 -0800 |
commit | 25baed90c6149010b9cb1c58861332e697084b76 (patch) | |
tree | 5e8f755b769c165d8cb972e614de29b01d4f31ae /src/cmd/6g | |
parent | 036a739f00d3d82702fe83446a612cbc3effc510 (diff) | |
download | golang-25baed90c6149010b9cb1c58861332e697084b76.tar.gz |
bug in 6g optimizer
8g still needs fixing
R=rsc
http://codereview.appspot.com/176057
Diffstat (limited to 'src/cmd/6g')
-rw-r--r-- | src/cmd/6g/gsubr.c | 2 | ||||
-rw-r--r-- | src/cmd/6g/reg.c | 109 |
2 files changed, 54 insertions, 57 deletions
diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c index 7461649ad..142d3c245 100644 --- a/src/cmd/6g/gsubr.c +++ b/src/cmd/6g/gsubr.c @@ -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); diff --git a/src/cmd/6g/reg.c b/src/cmd/6g/reg.c index f406335f4..4bd888bc3 100644 --- a/src/cmd/6g/reg.c +++ b/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; - - // if it overlaps, set max - // width and dont registerize - if(overlap(v, o, w)) + 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, 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: |