shithub: mc

Download patch

ref: f90519332a6d24444a54c2b0943f705e8579550f
parent: cf9651df0886dc8a4c0fbc6da8488606e1e85c31
parent: 3dc71f6baaf6ff6a7e5a41fd89ea3ec2c7bdf88c
author: Ori Bernstein <[email protected]>
date: Sun Aug 23 11:12:42 EDT 2015

Merge branch 'peephole-opt'

--- a/6/Makefile
+++ b/6/Makefile
@@ -8,6 +8,7 @@
 	locs.o \
 	main.o \
 	ra.o \
+	peep.o \
 	simp.o \
 	typeinfo.o \
 
--- a/6/asm.h
+++ b/6/asm.h
@@ -290,6 +290,9 @@
 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);
--- a/6/isel.c
+++ b/6/isel.c
@@ -1041,6 +1041,7 @@
     }
     is->curbb = is->bb[is->nbb - 1];
     epilogue(is);
+    peep(is);
     regalloc(is);
     is->stksz->lit = align(is->stksz->lit, 16);
 }
--- /dev/null
+++ b/6/peep.c
@@ -1,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);
+    }
+}