summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-11-19 21:38:23 -0500
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-11-19 21:38:35 -0500
commitbbaf4fd61b28036c0b9b80ee32b17a0766df12f3 (patch)
tree29820ace8b7bfcb993303ab230f8f4f127f17984
parenta968dc687d8a4fa3303a750d3ef1eea9369b2fdd (diff)
downloadroux-bbaf4fd61b28036c0b9b80ee32b17a0766df12f3.tar.gz
start memopt(), still buggy
-rw-r--r--lisc/Makefile2
-rw-r--r--lisc/lisc.h3
-rw-r--r--lisc/main.c2
-rw-r--r--lisc/mem.c71
-rw-r--r--lisc/ssa.c1
5 files changed, 78 insertions, 1 deletions
diff --git a/lisc/Makefile b/lisc/Makefile
index 6db1153..560fd4f 100644
--- a/lisc/Makefile
+++ b/lisc/Makefile
@@ -1,5 +1,5 @@
 BIN = lisc
-OBJ = main.o util.o parse.o ssa.o copy.o live.o isel.o spill.o rega.o emit.o
+OBJ = main.o util.o parse.o mem.o ssa.o copy.o live.o isel.o spill.o rega.o emit.o
 
 CFLAGS = -Wall -Wextra -std=c99 -g -pedantic
 
diff --git a/lisc/lisc.h b/lisc/lisc.h
index fcce670..6393755 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -373,6 +373,9 @@ void parse(FILE *, void (Dat *), void (Fn *));
 void printfn(Fn *, FILE *);
 void printref(Ref, Fn *, FILE *);
 
+/* mem.c */
+void memopt(Fn *);
+
 /* ssa.c */
 void filluse(Fn *);
 void fillpreds(Fn *);
diff --git a/lisc/main.c b/lisc/main.c
index 90f8b37..a393a69 100644
--- a/lisc/main.c
+++ b/lisc/main.c
@@ -6,6 +6,7 @@ char debug['Z'+1] = {
 	['A'] = 0, /* abi lowering */
 	['I'] = 0, /* instruction selection */
 	['L'] = 0, /* liveness */
+	['M'] = 0, /* memory optimization */
 	['N'] = 0, /* ssa construction */
 	['C'] = 0, /* copy elimination */
 	['S'] = 0, /* spilling */
@@ -52,6 +53,7 @@ func(Fn *fn)
 	fillrpo(fn);
 	fillpreds(fn);
 	filluse(fn);
+	memopt(fn);
 	ssa(fn);
 	filluse(fn);
 	copy(fn);
diff --git a/lisc/mem.c b/lisc/mem.c
new file mode 100644
index 0000000..bfc8218
--- /dev/null
+++ b/lisc/mem.c
@@ -0,0 +1,71 @@
+#include "lisc.h"
+
+/* Memory optimization:
+ *
+ * - replace alloced slots used only in
+ *   load/store operations
+ */
+
+/* require use, maintains use counts */
+void
+memopt(Fn *fn)
+{
+	Blk *b;
+	Ins *i, *l;
+	Tmp *t;
+	Use *u, *ue;
+	int a;
+
+	b = fn->start;
+	for (i=b->ins; i-b->ins < b->nins; i++) {
+		if (OAlloc > i->op || i->op > OAlloc1)
+			continue;
+		assert(NAlign == 3);
+		assert(rtype(i->to) == RTmp);
+		t = &fn->tmp[i->to.val];
+		for (u=t->use; u != &t->use[t->nuse]; u++) {
+			if (u->type != UIns)
+				goto NextIns;
+			l = u->u.ins;
+			if (l->op < OStorel || l->op > OStoreb)
+			if (l->op < OLoad || l->op > OLoad1)
+				goto NextIns;
+		}
+		/* get rid of the alloc and replace uses */
+		*i = (Ins){.op = ONop};
+		t->ndef--;
+		ue = &t->use[t->nuse];
+		for (u=t->use; u != ue; u++) {
+			l = u->u.ins;
+			if (OStorel <= l->op && l->op <= OStoreb) {
+				l->wide = (l->op == OStorel);
+				l->op = OCopy;
+				l->to = l->arg[1];
+				l->arg[1] = R;
+				t->nuse--;
+				t->ndef++;
+			} else
+				switch(l->op) {
+				case OLoad+Tl:
+					l->wide = 1;
+					l->op = OCopy;
+					break;
+				case OLoad+Tsw:
+				case OLoad+Tuw:
+					l->wide = 0;
+					l->op = OCopy;
+					break;
+				default:
+					/* keep l->wide */
+					a = l->op - OLoad;
+					l->op = OExt + a;
+					break;
+				}
+		}
+	NextIns:;
+	}
+	if (debug['M']) {
+		fprintf(stderr, "\n> After memory optimization:\n");
+		printfn(fn, stderr);
+	}
+}
diff --git a/lisc/ssa.c b/lisc/ssa.c
index ac90b6e..9d6ef4a 100644
--- a/lisc/ssa.c
+++ b/lisc/ssa.c
@@ -467,6 +467,7 @@ renblk(Blk *b, Name **stk, Fn *fn)
 		renblk(s, stk, fn);
 }
 
+/* require ndef */
 void
 ssa(Fn *fn)
 {