diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2017-02-27 10:34:22 -0500 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2017-02-27 10:34:29 -0500 |
commit | e80252a52bf25f762bc986ce6e4e0d17fbb130d0 (patch) | |
tree | 06b476558944a83d6c3e11ecc322a568caf1fe94 | |
parent | 3aecf460f5ab60c96ba90042ffd1cd7df41eeca5 (diff) | |
download | roux-e80252a52bf25f762bc986ce6e4e0d17fbb130d0.tar.gz |
scrub assembly output
Notably, this adds a new pass to get rid of jumps on jumps.
-rw-r--r-- | all.h | 1 | ||||
-rw-r--r-- | cfg.c | 44 | ||||
-rw-r--r-- | emit.c | 11 | ||||
-rw-r--r-- | main.c | 3 |
4 files changed, 55 insertions, 4 deletions
diff --git a/all.h b/all.h index e70bffb..124a8d2 100644 --- a/all.h +++ b/all.h @@ -576,6 +576,7 @@ int dom(Blk *, Blk *); void fillfron(Fn *); void loopiter(Fn *, void (*)(Blk *, Blk *)); void fillloop(Fn *); +void simpljmp(Fn *); /* mem.c */ void memopt(Fn *); diff --git a/cfg.c b/cfg.c index e210589..e695f39 100644 --- a/cfg.c +++ b/cfg.c @@ -278,3 +278,47 @@ fillloop(Fn *fn) b->loop = 1; loopiter(fn, multloop); } + +static void +uffind(Blk **pb, Blk **uf, Fn *fn) +{ + Blk **pb1; + + pb1 = &uf[(*pb)->id]; + if (*pb1 != *pb) + uffind(pb1, uf, fn); + *pb = *pb1; +} + +/* requires rpo and no phis, breaks cfg */ +void +simpljmp(Fn *fn) +{ + + Blk **uf; /* union-find */ + Blk *b; + uint n; + int c; + + uf = alloc(fn->nblk * sizeof uf[0]); + for (n=0; n<fn->nblk; n++) + uf[n] = fn->rpo[n]; + for (b=fn->start; b; b=b->link) { + assert(!b->phi); + if (b->nins == 0) + if (b->jmp.type == Jjmp) + uf[b->id] = b->s1; + } + for (b=fn->start; b; b=b->link) { + if (b->s1) + uffind(&b->s1, uf, fn); + if (b->s2) + uffind(&b->s2, uf, fn); + c = b->jmp.type - Jxjc; + if (0 <= c && c <= NXICmp) + if (b->s1 == b->s2) { + b->jmp.type = Jjmp; + b->s2 = 0; + } + } +} diff --git a/emit.c b/emit.c index c3a274b..138bc1d 100644 --- a/emit.c +++ b/emit.c @@ -505,7 +505,7 @@ emitfn(Fn *fn, FILE *f) static int id0; Blk *b, *s; Ins *i, itmp; - int *r, c, fs, o, n; + int *r, c, fs, o, n, lbl; fprintf(f, ".text\n"); if (fn->export) @@ -532,11 +532,12 @@ emitfn(Fn *fn, FILE *f) emitf("pushq %L0", &itmp, fn, f); } - for (b=fn->start; b; b=b->link) { - fprintf(f, "%sbb%d:\n", locprefix, id0+b->id); - fprintf(f, "/* @%s */\n", b->name); + for (lbl=0, b=fn->start; b; b=b->link) { + if (lbl || b->npred > 1) + fprintf(f, "%sbb%d:\n", locprefix, id0+b->id); for (i=b->ins; i!=&b->ins[b->nins]; i++) emitins(*i, fn, f); + lbl = 1; switch (b->jmp.type) { case Jret0: for (r=&rclob[NRClob]; r>rclob;) @@ -554,6 +555,8 @@ emitfn(Fn *fn, FILE *f) if (b->s1 != b->link) fprintf(f, "\tjmp %sbb%d\n", locprefix, id0+b->s1->id); + else + lbl = 0; break; default: c = b->jmp.type - Jxjc; diff --git a/main.c b/main.c index fe68ae0..4d2e6bd 100644 --- a/main.c +++ b/main.c @@ -72,6 +72,9 @@ func(Fn *fn) spill(fn); rega(fn); fillrpo(fn); + simpljmp(fn); + fillpreds(fn); + fillrpo(fn); assert(fn->rpo[0] == fn->start); for (n=0;; n++) if (n == fn->nblk-1) { |