summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2017-02-27 10:34:22 -0500
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2017-02-27 10:34:29 -0500
commite80252a52bf25f762bc986ce6e4e0d17fbb130d0 (patch)
tree06b476558944a83d6c3e11ecc322a568caf1fe94
parent3aecf460f5ab60c96ba90042ffd1cd7df41eeca5 (diff)
downloadroux-e80252a52bf25f762bc986ce6e4e0d17fbb130d0.tar.gz
scrub assembly output
Notably, this adds a new pass to get rid of
jumps on jumps.
-rw-r--r--all.h1
-rw-r--r--cfg.c44
-rw-r--r--emit.c11
-rw-r--r--main.c3
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) {