diff --git a/sys/src/cmd/8c/bound.c b/sys/src/cmd/8c/bound.c deleted file mode 100644 index d93c775ba..000000000 --- a/sys/src/cmd/8c/bound.c +++ /dev/null @@ -1,1117 +0,0 @@ -#include "gc.h" -#include "bound.h" - -static BB* bbfree; -static BBset* bbsfree; -static int bballoc; -static int bbsalloc; -static BB bbz; -static BBset bbsz; -static BB* firstbb; -static BB* lastbb; -static BB* wounded; -static BB* bbaux; -static BBset* recalc; -static BBset* bbhash[BBHASH]; -static BB** ordered; -static int bcount; -static BBset** heap; -static int heapn; -static int bsize; -static char bbbuff[BBBSIZE]; -static int bchange; - -#define bdebug (debug['v']) -#define dbg 0 -#define bcheck 0 - -static long -Rn(Reg *r) -{ - if(r == R) - return -1; - return r->rpo; -} - -static BB* -bba(void) -{ - BB *b; - - bballoc++; - b = bbfree; - if(b == nil) { - b = alloc(sizeof(*b)); - } else - bbfree = b->link; - - *b = bbz; - return b; -} - -static void -bfree(BB *b) -{ - bballoc--; - b->link = bbfree; - bbfree = b; -} - -static BBset* -bbsa(void) -{ - BBset *b; - - bballoc++; - b = bbsfree; - if(b == nil) { - b = alloc(sizeof(*b)); - } else - bbsfree = b->link; - - *b = bbsz; - return b; -} - -static void -bsfree(BBset *b) -{ - bballoc--; - b->link = bbsfree; - bbsfree = b; -} - -static void -dumpheap(void) -{ - int i; - - for(i = 1; i <= heapn; i++) - print(" %d", heap[i]->damage); -} - -static void -checkheap(void) -{ - int N, N2, n, c; - - N = heapn; - N2 = N >> 1; - for(n = 1; n <= N2; n++) { - c = n << 1; - if((heap[c]->damage > heap[n]->damage) - || ((c < N) && (heap[c + 1]->damage > heap[n]->damage))) { - print("bad heap (%d:%d) %d [", n, heap[n]->damage, heapn); - dumpheap(); - print(" ]\n"); - abort(); - } - } -} - -static void -downheap(int n) -{ - int N, N2, d, c; - BBset *s, *t, *u; - - s = heap[n]; - d = s->damage; -//print("down %d %d", n, d); - N = heapn; - N2 = N >> 1; - while(n <= N2) { - c = n << 1; - t = heap[c]; - if(c < N) { - u = heap[c + 1]; - if(t->damage < u->damage) { - t = u; - c++; - } - } -//print(" [%d %d]", c, t->damage); - if(t->damage < d) - break; - heap[n] = t; - t->index = n; - n = c; - } - heap[n] = s; - s->index = n; -//print("\n"); -//checkheap(); -} - -static void -upheap(int n) -{ - int f, d; - BBset *s, *t; - - s = heap[n]; - d = s->damage; -//print("up %d %d", n, d); - while(n > 1) { - f = n >> 1; - t = heap[f]; -//print(" [%d %d]", f, t->damage); - if(t->damage >= d) - break; - heap[n] = t; - t->index = n; - n = f; - } - heap[n] = s; - s->index = n; -//print("\n"); -//checkheap(); -} - -static void -heapremove(BBset *s) -{ - int x; - BBset *t; - - x = s->index; - s->index = 0; - if(x == 0) - return; - if(x == heapn) { - heapn--; - return; - } - t = heap[heapn--]; - heap[x] = t; - t->index = x; - if(s->damage < t->damage) - upheap(x); - else - downheap(x); -} - -static void -heapadd(BBset *s) -{ - int n; - - n = heapn + 1; - heap[n] = s; - s->index = n; - heapn = n; - upheap(n); - -} - -static void -bbsrecalc(BBset *s) -{ - if(s->recalc) - return; - s->recalc = 1; - s->link = recalc; - recalc = s; - heapremove(s); -} - -static void -bbadd(BB *b, Hval h) -{ - int k; - BBset *s; - - k = h[0] & BBMASK; - for(s = bbhash[k]; s != nil; s = s->next) { - if(BBEQ(s->hash, h)) { - b->set = s; - b->link = s->ents; - s->ents = b; - bbsrecalc(s); - return; - } - } - s = bbsa(); - s->next = bbhash[k]; - bbhash[k] = s; - b->set = s; - b->link = nil; - s->ents = b; - BBCP(s->hash, h); - bbsrecalc(s); -} - -static int -hashbb(BB *b, Hval h) -{ - Reg *r; - Prog *p; - char *s; - int c, f, i, n; - - r = b->first; - s = bbbuff; - i = 0; - n = BBBSIZE; - for(;;) { - p = r->prog; - if(p->as != ANOP) { - if(p->to.type == D_BRANCH) - p->to.offset = r->s2->rpo; - c = snprint(s, n, "%P", p); - s += c; - n -= c; - i++; - } - if(r == b->last) - break; - r = r->link; - } - if(n == 0) - return Bbig; - b->len = i; - BBMKHASH(bbbuff, BBBSIZE - n, h); - f = b->flags; - if(i == 1 && r->prog->as == AJMP && b->first->p1 == R) - f = Bjo; - else if(b->first->p1 != R) - f |= Bpre; - if(bdebug) - print("A %x %s %ux %ux\n", f, bbbuff, h[0], h[1]); - return f; -} - -static void -enterbb(BB *b) -{ - Hval h; - - b->flags = hashbb(b, h); - if(b->flags != Bbig) - bbadd(b, h); -} - -static void -preproc(BB *b, int x) -{ - BB *n; - Reg *r; - - ordered[x] = b; - if(b->last->rpo - b->first->rpo > BBBIG) { - b->flags = Bbig; - return; - } - if(b->first->p2 == nil) { - b->flags = Bdel; - return; - } - switch(b->last->prog->as) { - case ARET: - case AJMP: - case AIRETL: - break; - - default: - b->flags = Bdel; - n = bba(); - n->first = b->first; - for(r = b->last->link; r != R; r = r->link) { - switch(r->prog->as) { - case ARET: - case AJMP: - case AIRETL: - n->last = r; - n->flags = Bpin; - enterbb(n); - if(n->flags & Bpin) { - n->aux = bbaux; - bbaux = n; - } - else - bfree(n); - return; - } - } - bfree(n); - return; - } - enterbb(b); -} - -static int -p2len(Reg *r) -{ - int c; - - c = 0; - for(r = r->p2; r != nil; r = r->p2link) - c++; - return c; -} - -static void -calcdamage(BBset *s) -{ - BB *f; - int d, t; - - s->recalc = 0; - f = s->ents; - if(f == nil) - return; - if(f->flags & Bjo) { - if(bdebug) - print("add %ld jo\n", f->first->rpo); - s->damage = COSTJO; - heapadd(s); - return; - } - if(f->link == nil) { - if(bdebug) - print("solo %x %x\n", s->hash[0], s->hash[1]); - return; - } - - d = 0; - t = 0; - while(f != nil) { - if((f->flags & (Bpre|Bpin)) == 0 && f->last->link != R) { - t = 1; - d += (f->last->rpo - f->first->rpo) >> 1; - } - d += p2len(f->first); - f = f->link; - } - - if(t == 0) { - if(bdebug) - print("all pre %ld\n", s->ents->first->rpo); - return; - } - - if(bdebug) - print("add %ld %d\n", s->ents->first->rpo, d); - if(d > COSTHI) - d = COSTHI; - s->damage = d; - heapadd(s); -} - -static Reg* -findjump(BB *b) -{ - Reg *r, *l; - - r = b->first; - l = b->last; - - for(;;) { - if(r->prog->as == AJMP) - break; - if(r == l) { - diag(Z, "findjump botch"); - break; - } - r = r->link; - } - return r; -} - -static BB* -findset(int r) -{ - BB *s, **p; - int n, n2; - - if(r < ordered[0]->first->rpo) - return nil; - n = bcount; - p = ordered; - while(n > 0) { - n2 = n >> 1; - s = p[n2]; - if(r < s->first->rpo) { - n = n2; - continue; - } - if(r > s->last->rpo) { - n2++; - p += n2; - n -= n2; - continue; - } - return s; - } - diag(Z, "findset botch"); - return nil; -} - -static void -wound(Reg *r) -{ - BB *b, *p, **n; - BBset *s; - - b = findset(r->rpo); - if(b == nil) - return; - s = b->set; - if(s == nil) - return; - for(n = &s->ents; (p = *n) != nil; n = &(*n)->link) { - if(p == b) { - *n = b->link; - b->link = wounded; - wounded = b; - bbsrecalc(s); - return; - } - } -} - -static void -printbl(Reg *l) -{ - if(l == nil) { - print("Z"); - return; - } - - print("%ld", l->rpo); - while((l = l->p2link) != nil) - print(" %ld", l->rpo); -} - -static void -appset(Reg *e, Reg *s) -{ - for(;;) { - if(s->p2link == R) { - s->p2link = e; - return; - } - s = s->p2link; - } -} - -static Reg* -delset(Reg *e, Reg *s) -{ - Reg *c, *l; - - c = s; - l = nil; - for(;;) { - if(e == c) { - if(l == nil) - return s->p2link; - l->p2link = c->p2link; - return s; - } - l = c; - c = c->p2link; - if(c == nil) - return s; - } -} - -static void -redest(Reg *s, Reg *d) -{ - while(s != R) { - s->s2 = d; - s = s->p2link; - } -} - -static void -changedest(Reg *s, Reg *d, int x) -{ - Reg *l; - - if(bdebug) { - print("change %ld [", s->rpo); - printbl(s->p2); - print("] -> %ld [", d->rpo); - printbl(d->p2); - print("]\n"); - } - - if(s->p2 == nil) { -// print("deadjmp\n"); - return; - } - - l = s->p2; - for(;;) { - if(bdebug) - print("s2 %ld = %ld\n", l->rpo, d->rpo); - l->s2 = d; - wound(l); - if(l->p2link == nil) - break; - l = l->p2link; - } - - if(x) { - l->p2link = delset(s, d->p2); - d->p2 = s->p2; - } - else { - l->p2link = d->p2; - d->p2 = s->p2; - s->p2 = nil; - } - - if(bdebug) { - print("result ["); - printbl(d->p2); - print("]\n"); - } - - bchange = 1; -} - -static void -bexcise(BB *b) -{ - Reg *r, *l; - - l = b->last; - r = b->first; - if(bdebug) - print("excise %ld to %ld\n", r->rpo, l->rpo); - for(;;) { - r->prog->as = ANOP; - r->prog->to.type = D_NONE; - r->p2 = R; - if(r->s2 != R) { - r->s2->p2 = delset(r, r->s2->p2); - r->s2 = R; - } - if(r == l) - break; - r = r->link; - } -} - -static int -backtrack(Reg *s, Reg *d) -{ - int i; - char l[BINST], r[BINST]; - -//print("backtrack %ld %ld\n", Rn(s), Rn(d)); - i = 0; - while(s != nil && d != nil) { - if(snprint(l, BINST, "%P", s->prog) == BINST) - break; - if(snprint(r, BINST, "%P", d->prog) == BINST) - break; -//print("%s\t%s\n", l, r); - if(strcmp(l, r) != 0) - break; - i++; - s = s->p2link; - d = d->p2link; - } - return i; -} - -static void -checktails(void) -{ - int c; - Reg *r; - - c = 0; - for(r = firstr; r->link != R; r = r->link) { - if(r->prog->as == AJMP && r->s2 != nil) - c += backtrack(r->p1, r->s2->p1); - } - - if(c > 0) - print("tails %s %d\n", firstr->prog->from.sym->name, c); -} - -static void -process(BBset *s) -{ - Reg *h; - BB *f, *o, *p, *t; - - if(bdebug) - print("process %d %x %x\n", s->damage, s->hash[0], s->hash[1]); - f = s->ents; - if(f->flags & Bjo) { - s->ents = nil; - h = findjump(f)->s2; - o = nil; - while(f != nil) { - t = f->link; - if((f->flags & Bjo) != 0 && f->first->s2 != f->first) { - changedest(f->first, h, 1); - bexcise(f); - } - else { - f->link = o; - o = f; - } - f = t; - } - s->ents = o; - } - else { - o = nil; - p = nil; - while(f != nil) { - t = f->link; - if((f->flags & (Bpre|Bpin)) != 0 || (f->last->link == R)) { - f->link = p; - p = f; - } - else { - f->link = o; - o = f; - } - f = t; - } - if(o == nil) { - diag(Z, "all Bpre"); - return; - } - if(p == nil) { - p = o; - o = p->link; - p->link = nil; - s->ents = p; - } - else - s->ents = p; - - h = p->first; - // oblit o list repl with jmp to h - while(o != nil) { - changedest(o->first, h, 1); - bexcise(o); - o = o->link; - } - - bbsrecalc(s); - } -} - -static void -iterate(void) -{ - BBset *s; - BB *b, *t; - - heapn = 0; - - for(;;) { - for(b = wounded; b != nil; b = t) { - t = b->link; - enterbb(b); - } - wounded = nil; - - for(s = recalc; s != nil; s = s->link) - calcdamage(s); - recalc = nil; - - if(heapn == 0) - return; - - s = heap[1]; - heapremove(s); - process(s); - } -} - -static void -cleanup(void) -{ - int i; - BB *l, *n; - BBset *b, *t; - - for(i = 0; i < BBHASH; i++) { - b = bbhash[i]; - bbhash[i] = nil; - while(b != nil) { - t = b->next; - bsfree(b); - b = t; - } - } - for(i = 0; i < bcount; i++) - bfree(ordered[i]); - for(l = bbaux; l != nil; l = n) { - n = l->aux; - bfree(l); - } - bbaux = nil; -} - -static void -prreg(Reg *r) -{ - Prog *p; - - p = r->prog; - if(p->to.type == D_BRANCH) - p->to.offset = r->s2->rpo; - print("%ld:%P\tr %lX ", r->rpo, r->prog, r->regu); - print("p1 %ld p2 %ld p2l %ld s1 %ld s2 %ld link %ld", - Rn(r->p1), Rn(r->p2), Rn(r->p2link), - Rn(r->s1), Rn(r->s2), Rn(r->link)); - if(!r->active) - print(" d"); -// print(" %p %p\n", r->prog, r->prog->link); - print("\n"); -} - -static void prfunc(char*); - -static void -checkr(int d) -{ - Prog *p; - Reg *r, *t; - - for(r = firstr; r->link != R; r = r->link) { - for(p = r->prog->link; p != P && p != r->link->prog; p = p->link) - ; - if(p == P) { - print("%ld: bad prog link\n", r->rpo); - if(d) - prfunc(nil); - abort(); - } - if(r->s1 != R && (r->s1 != r->link || r->link->p1 != r)) { - print("%ld: bad s1 p1\n", r->rpo); - if(d) - prfunc(nil); - abort(); - } - if(r->s2 != R && r->s2->p2 == nil) { - print("%ld: no p2 for s2\n", r->rpo); - if(d) - prfunc(nil); - abort(); - } - if(r->p2 != R) { - t = r->p2->s2; - while(t != r) { - t = t->p2link; - if(t == R) { - print("%ld: bad s2 for p2\n", r->rpo); - if(d) - prfunc(nil); - abort(); - } - } - } - } -} - -static void -prfunc(char *s) -{ - Reg *r; - - if(s != nil) - print("%s structure %s\n", s, firstr->prog->from.sym->name); - for(r = firstr; r != R; r = r->link) - prreg(r); - if(s != nil) { - print("end\n"); - checkr(0); - } -} - -/* find p in r's list and replace with l */ -static void -adjprog(Reg *r, Prog *p, Prog *l) -{ - Prog *t, **n; - - for(n = &r->prog->link; (t = *n) != nil; n = &t->link) { - if(t == p) { - *n = l; - return; - } - } - print("adjprog botch\n"); - abort(); -} - -static void -jumptojump(void) -{ - Reg *r; - - for(r = firstr; r != R; r = r->link) { - if(r->prog->as == AJMP && r->p2 != R && r->s2 != r) { - if(bdebug) - print("jump as dest %ld -> %ld\n", r->rpo, r->s2->rpo); - changedest(r, r->s2, 0); - bchange++; - } - } -} - -/* drag a tail to replace a jump. seems to be a bad idea. */ -static void -rearrange(void) -{ - int i; - Reg *j, *t; - BB *b, *p, *s; - - for(i = 0; i < bcount; i++) { - b = ordered[i]; - if(b->flags & Bdel) - continue; - j = b->last; - if(j->prog->as == AJMP && j->s2->p1 == R) { - t = j->s2; - if(t == b->first) - continue; - s = findset(t->rpo); - if(s == nil) { - diag(Z, "no self"); - continue; - } - if(s == ordered[0]) - continue; - if(s->flags & Bdel) - continue; - if(s->last->link == R) - continue; - if(bdebug) - print("drag %ld to %ld\n", t->rpo, j->rpo); - p = findset(t->rpo - 1); - if(p == nil) { - diag(Z, "no predec"); - continue; - } - if(p->last->link != t) { - diag(Z, "bad predec %ld %ld", p->last->rpo, t->rpo); - continue; - } - - /* poison everything in sight */ - b->flags |= Bdel; - s->flags |= Bdel; - findset(j->link->rpo)->flags |= Bdel; - findset(s->last->link->rpo)->flags |= Bdel; - - /* remove */ - adjprog(p->last, t->prog, s->last->link->prog); - p->last->link = s->last->link; - - /* fix tail */ - adjprog(s->last, s->last->link->prog, j->link->prog); - s->last->link = j->link; - - /* fix head */ - adjprog(j, j->link->prog, t->prog); - j->link = t; - - /* nop the jump */ - j->prog->as = ANOP; - j->prog->to.type = D_NONE; - j->s2 = nil; - j->link->p2 = delset(j, j->link->p2); - j->s1 = t; - t->p1 = j; - if(bcheck) - checkr(1); - bchange++; - } - } -} - -void -jumptodot(void) -{ - Reg *r; - - for(r = firstr; r != R; r = r->link) { - if(r->prog->as == AJMP && r->s2 == r->link) { - if(debug['v']) - print("jump to next %ld\n", r->rpo); - r->prog->as = ANOP; - r->prog->to.type = D_NONE; - r->s2 = nil; - r->link->p2 = delset(r, r->link->p2); - findset(r->rpo)->flags |= Bdel; - findset(r->link->rpo)->flags |= Bdel; - bchange++; - } - } -} - -void -comtarg(void) -{ - int n; - BB *b, *c; - Reg *r, *l, *p, *t; - -loop: - bchange = 0; - - /* excise NOPS because they just get in the way */ - /* some have p2 because they are excised labelled moves */ - - if(debug['v']) { - n = 0; - for(r = firstr; r != R; r = r->link) - r->rpo = n++; - prfunc("prenop"); - } - - r = firstr; - l = r->link; - while(l != R) { - if(l->prog->as == ANOP) { - t = l->p1; - p = l->p2; -if(dbg) print("nop %ld [", l->rpo); -if(dbg) printbl(p); - for(;;) { - adjprog(r, l->prog, l->prog->link); - r->link = l->link; - l->link = freer; - freer = l; - l = r->link; - if(l->prog->as != ANOP) - break; -if(dbg) print("] %ld [", l->rpo); -if(dbg) printbl(l->p2); - if(p == R) - p = l->p2; - else if(l->p2 != nil) - appset(l->p2, p); - } -if(dbg) print("] %ld [", l->rpo); -if(dbg) printbl(l->p2); - if(p != R) { - redest(p, l); - if(l->p2 != R) - appset(p, l->p2); - else - l->p2 = p; - } -if(dbg) print("] -> ["); -if(dbg) printbl(l->p2); -if(dbg) print("]\n"); - if(r->s1 != R) - r->s1 = l; - l->p1 = t; - } - r = l; - l = r->link; - } - - n = 0; - for(r = firstr; r != R; r = r->link) - r->rpo = n++; - - if(debug['v']) - prfunc("input"); - - firstbb = nil; - lastbb = nil; - - if(debug['v']) - print("bbstart\n"); - - n = 0; - r = firstr; - do { - b = bba(); - b->first = r; - for(;;) { - l = r; - r = r->link; - switch(l->prog->as) { - case ARET: - case AJMP: - case AIRETL: - goto out; - } - if(r->p2 != R) - break; - } - out: - b->last = l; - if(lastbb == nil) - firstbb = b; - else - lastbb->link = b; - lastbb = b; - if(bdebug) - print("BB %ld %ld\n", b->first->rpo, b->last->rpo); - n++; - } while(r != R); - - if(debug['v']) - print("end\n"); - - if(n > bsize) { - bsize = n * 3 / 2; - if(bsize < BBINIT) - bsize = BBINIT; - ordered = alloc(bsize * sizeof(*ordered)); - heap = alloc((bsize + 1) * sizeof(*ordered)); - } - - if(debug['v']) - print("preprocstart\n"); - - n = 0; - for(b = firstbb; b != nil; b = c) { - c = b->link; - preproc(b, n++); - } - - if(debug['v']) - print("end\n"); - - bcount = n; - - jumptojump(); - - if(debug['v']) - print("iteratestart\n"); - - iterate(); -//checktails(); - - if(debug['v']) - print("end\n"); - - if(debug['v']) - print("extrastart\n"); - - jumptodot(); -// rearrange(); - - if(debug['v']) - print("end\n"); - - cleanup(); - if(bballoc || bbsalloc) - diag(Z, "bballoc %d %d", bballoc, bbsalloc); - - if(debug['v']) - prfunc("output"); - - if(1 && bchange) - goto loop; -} diff --git a/sys/src/cmd/8c/bound.h b/sys/src/cmd/8c/bound.h deleted file mode 100644 index 796032d62..000000000 --- a/sys/src/cmd/8c/bound.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Bounding Box stuff (brucee 04/03/30). - */ - -#include -#include - -typedef struct BB BB; -typedef struct BBset BBset; -typedef uchar Hval[SHA1dlen]; - -#define BBEQ(a, b) (memcmp((a), (b), SHA1dlen) == 0) -#define BBMKHASH(b, n, h) sha1((uchar *)(b), (n), (h), nil) -#define BBCP(d, s) memmove(d, s, SHA1dlen) - -enum -{ - Bpre = 1 << 0, /* has a flow in */ - Bjo = 1 << 1, /* a jump only */ - Bbig = 1 << 2, /* too big */ - Bdel = 1 << 3, /* deleted or not of interest */ - Bpin = 1 << 4, /* pinned by embedded labels */ - - BBHASH = 64, /* power of 2 <= 256 */ - BBMASK = BBHASH - 1, - - BBINIT = 128, - BBBIG = 64, - BBBSIZE = 8192, - BINST = 128, - - COSTHI = 0x7F, - COSTJO = 0xFF, -}; - -struct BB -{ - Reg* first; - Reg* last; - BBset* set; - BB* link; - BB* aux; - short flags; - short len; -}; - -struct BBset -{ - Hval hash; - BB* ents; - BBset* next; - BBset* link; - short index; - uchar damage; - uchar recalc; -};