diff options
-rw-r--r-- | 8/Makefile | 6 | ||||
-rw-r--r-- | 8/main.c | 1 | ||||
-rw-r--r-- | 8/reduce.c | 5 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | opt/df.c | 77 | ||||
-rw-r--r-- | opt/opt.h | 2 | ||||
-rw-r--r-- | parse/bitset.c | 8 | ||||
-rw-r--r-- | parse/parse.h | 1 |
8 files changed, 96 insertions, 5 deletions
@@ -4,9 +4,9 @@ OBJ=isel.o \ reduce.o \ regalloc.o \ -CFLAGS+=-I../parse -LDFLAGS+=-L../parse -lparse -EXTRADEP=../parse/libparse.a +CFLAGS+=-I../parse -I../opt +LDFLAGS+=-L../parse -lparse -L../opt -lopt +EXTRADEP=../parse/libparse.a ../opt/libopt.a include ../mk/lexyacc.mk include ../mk/c.mk @@ -11,6 +11,7 @@ #include "parse.h" #include "asm.h" +#include "opt.h" Node *file; static char *outfile; @@ -11,6 +11,7 @@ #include "parse.h" #include "asm.h" +#include "opt.h" #include "platform.h" /* HACK. We need some platform specific code gen behavior. *sigh.* */ @@ -607,6 +608,7 @@ static void lowerfn(char *name, Node *n, Htab *globls, FILE *fd) int i; Simp s = {0,}; Func fn; + Cfg *cfg; if(debug) printf("\n\nfunction %s\n", name); @@ -622,6 +624,9 @@ static void lowerfn(char *name, Node *n, Htab *globls, FILE *fd) if (debug) for (i = 0; i < s.nstmts; i++) dump(s.stmts[i], stdout); + cfg = mkcfg(s.stmts, s.nstmts); + if (debug) + dumpcfg(cfg, stdout); fn.name = name; fn.isglobl = 1; /* FIXME: we should actually use the visibility of the sym... */ @@ -1,4 +1,5 @@ SUB = parse \ + opt \ 8 -include config.mk @@ -27,6 +27,12 @@ Bb *mkbb(Cfg *cfg) return bb; } +void label(Cfg *cfg, Node *lbl, Bb *bb) +{ + htput(cfg->lblmap, lbl->lbl.name, bb); + lappend(&bb->lbls, &bb->nlbls, lbl->lbl.name); +} + int addnode(Cfg *cfg, Bb *bb, Node *n) { switch (exprop(n)) { @@ -47,16 +53,19 @@ int addnode(Cfg *cfg, Bb *bb, Node *n) Cfg *mkcfg(Node **nl, int nn) { Cfg *cfg; - Bb *bb; + Bb *bb, *targ; + Node *a, *b; int i; cfg = zalloc(sizeof(Cfg)); + cfg->lblmap = mkht(strhash, streq); + bb = mkbb(cfg); for (i = 0; i < nn; i++) { switch (nl[i]->type) { case Nlbl: if (bb->nnl) bb = mkbb(cfg); - lappend(&bb->lbls, &bb->nlbls, nl[i]->lbl.name); + label(cfg, nl[i], bb); break; case Nexpr: if (addnode(cfg, bb, nl[i])) @@ -68,5 +77,69 @@ Cfg *mkcfg(Node **nl, int nn) die("Invalid node type %s in mkcfg", nodestr(nl[i]->type)); } } + for (i = 0; i < cfg->nfixjmp; i++) { + bb = cfg->fixblk[i]; + switch (exprop(cfg->fixjmp[i])) { + case Ojmp: + a = cfg->fixjmp[i]->expr.args[0]; + b = NULL; + break; + case Ocjmp: + a = cfg->fixjmp[i]->expr.args[0]; + b = cfg->fixjmp[i]->expr.args[1]; + break; + default: + die("Bad jump fix thingy"); + break; + } + if (a) { + targ = htget(cfg->lblmap, a->lbl.name); + if (!targ) + die("No bb with label %s", a->lbl.name); + bsput(bb->out, targ->id); + bsput(targ->in, bb->id); + } + if (b) { + targ = htget(cfg->lblmap, b->lbl.name); + if (!targ) + die("No bb with label %s", b->lbl.name); + bsput(bb->out, targ->id); + bsput(targ->in, bb->id); + } + } return cfg; } +void dumpcfg(Cfg *cfg, FILE *fd) +{ + int i, j; + Bb *bb; + char *sep; + + for (j = 0; j < cfg->nbb; j++) { + bb = cfg->bb[j]; + fprintf(fd, "Bb: %d\n", bb->id); + + /* in edges */ + fprintf(fd, "In: "); + sep = ""; + for (i = 0; i < bsmax(bb->in); i++) { + if (bshas(bb->in, i)) + fprintf(fd, "%d%s", i, sep); + sep = ","; + } + fprintf(fd, "\n"); + + /* out edges */ + fprintf(fd, "Out: "); + sep = ""; + for (i = 0; i < bsmax(bb->out); i++) { + if (bshas(bb->in, i)) + fprintf(fd, "%d%s", i, sep); + sep = ","; + } + fprintf(fd, "\n"); + + for (i = 0; i < bb->nnl; i++) + dump(bb->nl[i], fd); + } +} @@ -6,6 +6,7 @@ struct Cfg { size_t nbb; /* for building bb */ + Htab *lblmap; /* label => Bb mapping */ Node **fixjmp; size_t nfixjmp; Bb **fixblk; @@ -24,4 +25,5 @@ struct Bb { /* Takes a reduced block, and returns a flow graph. */ Cfg *mkcfg(Node **nl, int nn); +void dumpcfg(Cfg *c, FILE *fd); void flow(Cfg *cfg); diff --git a/parse/bitset.c b/parse/bitset.c index 9bdfda9..153b602 100644 --- a/parse/bitset.c +++ b/parse/bitset.c @@ -56,6 +56,14 @@ int bscount(Bitset *bs) return n; } +/* Returns the largest value that the bitset can possibly + * hold. It's conservative, but scanning the entire bitset + * is a bit slow. This is mostly an aid to iterate over it. */ +int bsmax(Bitset *bs) +{ + return bs->nchunks*sizeof(uint)*CHAR_BIT; +} + void delbs(Bitset *bs) { free(bs->chunks); diff --git a/parse/parse.h b/parse/parse.h index 27c01c6..b44c197 100644 --- a/parse/parse.h +++ b/parse/parse.h @@ -233,6 +233,7 @@ void bsunion(Bitset *a, Bitset *b); void bsintersect(Bitset *a, Bitset *b); void bsdiff(Bitset *a, Bitset *b); int bscount(Bitset *bs); +int bsmax(Bitset *bs); int bsissubset(Bitset *set, Bitset *sub); Htab *mkht(ulong (*hash)(void *key), int (*cmp)(void *k1, void *k2)); |