commit e80252a52bf25f762bc986ce6e4e0d17fbb130d0
parent 3aecf460f5ab60c96ba90042ffd1cd7df41eeca5
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Mon, 27 Feb 2017 10:34:22 -0500
scrub assembly output
Notably, this adds a new pass to get rid of
jumps on jumps.
Diffstat:
4 files changed, 55 insertions(+), 4 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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) {