diff options
author | Ori Bernstein <ori@eigenstate.org> | 2015-08-23 15:12:42 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2015-08-23 15:12:42 -0700 |
commit | f90519332a6d24444a54c2b0943f705e8579550f (patch) | |
tree | 98bb53204bbe193229954add68840ae7d68d2b80 | |
parent | cf9651df0886dc8a4c0fbc6da8488606e1e85c31 (diff) | |
parent | 3dc71f6baaf6ff6a7e5a41fd89ea3ec2c7bdf88c (diff) | |
download | mc-f90519332a6d24444a54c2b0943f705e8579550f.tar.gz |
Merge branch 'peephole-opt'
-rw-r--r-- | 6/Makefile | 1 | ||||
-rw-r--r-- | 6/asm.h | 3 | ||||
-rw-r--r-- | 6/isel.c | 1 | ||||
-rw-r--r-- | 6/peep.c | 89 |
4 files changed, 94 insertions, 0 deletions
@@ -8,6 +8,7 @@ OBJ= \ locs.o \ main.o \ ra.o \ + peep.o \ simp.o \ typeinfo.o \ @@ -290,6 +290,9 @@ void dbglocprint(FILE *fd, Loc *l, char spec); void regalloc(Isel *s); Rclass rclass(Loc *l); +/* machine dependent optimization */ +void peep(Isel *s); + /* useful functions */ size_t tysize(Type *t); size_t tyalign(Type *t); @@ -1041,6 +1041,7 @@ void selfunc(Isel *is, Func *fn, Htab *globls, Htab *strtab) } is->curbb = is->bb[is->nbb - 1]; epilogue(is); + peep(is); regalloc(is); is->stksz->lit = align(is->stksz->lit, 16); } diff --git a/6/peep.c b/6/peep.c new file mode 100644 index 0000000..f36cdff --- /dev/null +++ b/6/peep.c @@ -0,0 +1,89 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <stdarg.h> +#include <ctype.h> +#include <string.h> +#include <assert.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include "parse.h" +#include "mi.h" +#include "asm.h" + + +/* we sometimes leave dead code generated after + * a non-conditional jump. This code scans for + * the non-conditional exit from the BB, and truncates + * at that point */ +static void deadcode(Isel *s, Asmbb *bb) +{ + size_t i; + + if (!bb) + return; + for (i = 0; i < bb->ni; i++) { + if (bb->il[i]->op == Ijmp) { + i++; + break; + } + } + bb->ni = i; +} + +/* checks for of dumb jump code. + * nop jumps: + * jmp .l1 + * .l1: + * TODO: check for jumps over jumps. + */ +static void nopjmp(Isel *s, Asmbb *bb, size_t idx) +{ + Insn *jmp; + Loc *targ; + Asmbb *nextbb; + size_t i; + + /* skip empty bbs */ + if (!bb || !bb->ni) + return; + /* find the target of the last unconditional + * jump in the bb */ + targ = NULL; + if (bb->il[bb->ni - 1]->op == Ijmp) { + jmp = bb->il[bb->ni - 1]; + if (jmp->args[0]->type == Loclbl) + targ = jmp->args[0]; + } + if (!targ) + return; + + /* figure out if it's somewhere in the head of the next bb */ + nextbb = NULL; + for (i = idx + 1; i < s->nbb; i++) { + nextbb = s->bb[i]; + if (nextbb) + break; + } + if (!nextbb) + return; + for (i = 0; i < nextbb->nlbls; i++) { + if (!strcmp(nextbb->lbls[i], targ->lbl)) { + bb->ni--; + break; + } + } +} + +void peep(Isel *s) +{ + size_t i; + + for (i = 0; i < s->nbb; i++) { + deadcode(s, s->bb[i]); + nopjmp(s, s->bb[i], i); + } +} |