From e80252a52bf25f762bc986ce6e4e0d17fbb130d0 Mon Sep 17 00:00:00 2001 From: Quentin Carbonneaux Date: Mon, 27 Feb 2017 10:34:22 -0500 Subject: scrub assembly output Notably, this adds a new pass to get rid of jumps on jumps. --- all.h | 1 + cfg.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ emit.c | 11 +++++++---- 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; nnblk; 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) { -- cgit 1.4.1