From cd00bc78da52c60663e4536c62b9f3cf3d0262f7 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Fri, 11 Dec 2009 15:55:09 -0800 Subject: [PATCH] bug in 6g optimizer 8g still needs fixing R=rsc https://golang.org/cl/176057 --- src/cmd/6g/gsubr.c | 2 + src/cmd/6g/reg.c | 109 +++++++++++++++++++++------------------------ src/cmd/8g/gsubr.c | 2 + src/cmd/gc/go.h | 1 + 4 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c index 7461649ad9..142d3c245d 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 f406335f4e..4bd888bc33 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; zaddr) { + bit = blsh(i); + for(z=0; zaddr, 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; ztype; + 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; ztype = 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; isym) - 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; zaddr = 1; + return bit; none: diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c index 9e65a06e42..4625509e9d 100644 --- a/src/cmd/8g/gsubr.c +++ b/src/cmd/8g/gsubr.c @@ -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); diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 5df0c5be85..15d1cf335d 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -513,6 +513,7 @@ struct Var int width; char name; char etype; + char addr; }; EXTERN Var var[NVAR]; -- 2.50.0