summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--all.h11
-rw-r--r--copy.c48
-rw-r--r--main.c1
-rw-r--r--simpl.c46
-rw-r--r--ssa.c14
6 files changed, 66 insertions, 56 deletions
diff --git a/Makefile b/Makefile
index 4040923..fc649f8 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ ABI = sysv
 V = @
 OBJDIR = obj
 
-SRC = main.c util.c parse.c cfg.c mem.c ssa.c alias.c load.c simpl.c copy.c fold.c live.c $(ABI).c isel.c spill.c rega.c emit.c
+SRC = main.c util.c parse.c cfg.c mem.c ssa.c alias.c load.c copy.c fold.c live.c $(ABI).c isel.c spill.c rega.c emit.c
 OBJ = $(SRC:%.c=$(OBJDIR)/%.o)
 
 CFLAGS += -Wall -Wextra -std=c99 -g -pedantic
diff --git a/all.h b/all.h
index f518a36..e70bffb 100644
--- a/all.h
+++ b/all.h
@@ -228,7 +228,7 @@ enum Op {
 	Ostores,
 	Ostored,
 #define isstore(o) (Ostoreb <= o && o <= Ostored)
-	Oloadsb,  /* needs to match OExt (mem.c) */
+	Oloadsb,  /* must match Oext and Tmp.width */
 	Oloadub,
 	Oloadsh,
 	Oloaduh,
@@ -407,6 +407,15 @@ struct Tmp {
 	} hint;
 	int phi;
 	Alias alias;
+	enum {
+		WFull,
+		Wsb, /* must match Oload/Oext order */
+		Wub,
+		Wsh,
+		Wuh,
+		Wsw,
+		Wuw
+	} width;
 	int visit;
 };
 
diff --git a/copy.c b/copy.c
index bcb7b4d..7442306 100644
--- a/copy.c
+++ b/copy.c
@@ -51,13 +51,51 @@ visitphi(Phi *p, Ref *cp, RList ***pw)
 	update(p->to, r, cp, pw);
 }
 
+static int
+iscopy(Ins *i, Ref r, Fn *fn)
+{
+	static bits extcpy[] = {
+		[WFull] = 0,
+		[Wsb] = BIT(Wsb) | BIT(Wsh) | BIT(Wsw),
+		[Wub] = BIT(Wub) | BIT(Wuh) | BIT(Wuw),
+		[Wsh] = BIT(Wsh) | BIT(Wsw),
+		[Wuh] = BIT(Wuh) | BIT(Wuw),
+		[Wsw] = BIT(Wsw),
+		[Wuw] = BIT(Wuw),
+	};
+	int k, w;
+	Tmp *t;
+
+	if (i->op == Ocopy)
+		return 1;
+	if (!isext(i->op))
+		return 0;
+	if (i->op == Oextsw || i->op == Oextuw)
+	if (i->cls == Kw)
+		return 1;
+	if (rtype(r) == RTmp) {
+		t = &fn->tmp[r.val];
+		w = t->width;
+		k = t->cls;
+		assert(k == Kw || k == Kl);
+	} else {
+		assert(rtype(r) == RCon);
+		w = WFull;
+		k = Kl;
+	}
+	if (i->cls == Kl && k == Kw)
+		/* not enough bits in r */
+		return 0;
+	return (BIT(Wsb + (i->op - Oextsb)) & extcpy[w]) != 0;
+}
+
 static void
-visitins(Ins *i, Ref *cp, RList ***pw)
+visitins(Ins *i, Ref *cp, RList ***pw, Fn *fn)
 {
 	Ref r;
 
-	if (i->op == Ocopy) {
-		r = copyof(i->arg[0], cp);
+	r = copyof(i->arg[0], cp);
+	if (iscopy(i, r, fn)) {
 		update(i->to, r, cp, pw);
 	} else if (!req(i->to, R)) {
 		assert(rtype(i->to) == RTmp);
@@ -91,7 +129,7 @@ copy(Fn *fn)
 		for (p=b->phi; p; p=p->link)
 			visitphi(p, cp, &pw);
 		for (i=b->ins; i-b->ins < b->nins; i++)
-			visitins(i, cp, &pw);
+			visitins(i, cp, &pw, fn);
 	}
 	while ((w1=w)) {
 		t = w->t;
@@ -103,7 +141,7 @@ copy(Fn *fn)
 				visitphi(u->u.phi, cp, &pw);
 				break;
 			case UIns:
-				visitins(u->u.ins, cp, &pw);
+				visitins(u->u.ins, cp, &pw, fn);
 				break;
 			case UJmp:
 				break;
diff --git a/main.c b/main.c
index 1a8973f..fe68ae0 100644
--- a/main.c
+++ b/main.c
@@ -59,7 +59,6 @@ func(Fn *fn)
 	loadopt(fn);
 	filluse(fn);
 	ssacheck(fn);
-	simpl(fn);
 	copy(fn);
 	filluse(fn);
 	fold(fn);
diff --git a/simpl.c b/simpl.c
deleted file mode 100644
index 384a8da..0000000
--- a/simpl.c
+++ /dev/null
@@ -1,46 +0,0 @@
-#include "all.h"
-
-static void
-elimext(Ins *i, int ext, Fn *fn)
-{
-	Tmp *t;
-	Use *u;
-
-	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
-		&& u->u.ins->op == ext
-		&& (u->u.ins->cls == i->cls || i->cls == Kl)) {
-			u->u.ins->op = Ocopy;
-			elimext(u->u.ins, ext, fn);
-		}
-}
-
-/* requires & preserves uses */
-void
-simpl(Fn *fn)
-{
-	Blk *b;
-	Ins *i;
-	int ext;
-
-	for (b=fn->start; b; b=b->link)
-		for (i=b->ins; i<&b->ins[b->nins]; i++)
-			switch (i->op) {
-			case Oloadsb:
-			case Oloadub:
-			case Oloadsh:
-			case Oloaduh:
-				ext = Oextsb + (i->op - Oloadsb);
-				goto Elimext;
-			case Oextsb:
-			case Oextub:
-			case Oextsh:
-			case Oextuh:
-				ext = i->op;
-			Elimext:
-				elimext(i, ext, fn);
-				break;
-			}
-}
diff --git a/ssa.c b/ssa.c
index 8a28eeb..632ebbe 100644
--- a/ssa.c
+++ b/ssa.c
@@ -31,7 +31,7 @@ adduse(Tmp *tmp, int ty, Blk *b, ...)
 	va_end(ap);
 }
 
-/* fill usage, phi, and class information
+/* fill usage, width, phi, and class information
  * must not change .visit fields
  */
 void
@@ -40,7 +40,7 @@ filluse(Fn *fn)
 	Blk *b;
 	Phi *p;
 	Ins *i;
-	int m, t;
+	int m, t, w;
 	uint a;
 	Tmp *tmp;
 
@@ -51,6 +51,7 @@ filluse(Fn *fn)
 		tmp[t].nuse = 0;
 		tmp[t].phi = 0;
 		tmp[t].cls = 0;
+		tmp[t].width = WFull;
 		if (tmp[t].use == 0)
 			tmp[t].use = vnew(0, sizeof(Use), Pfn);
 	}
@@ -72,7 +73,16 @@ filluse(Fn *fn)
 		for (i=b->ins; i-b->ins < b->nins; i++) {
 			if (!req(i->to, R)) {
 				assert(rtype(i->to) == RTmp);
+				w = WFull;
+				if (isload(i->op) && i->op != Oload)
+					w = Wsb + (i->op - Oloadsb);
+				if (isext(i->op))
+					w = Wsb + (i->op - Oextsb);
+				if (w == Wsw || w == Wuw)
+				if (i->cls == Kw)
+					w = WFull;
 				t = i->to.val;
+				tmp[t].width = w;
 				tmp[t].ndef++;
 				tmp[t].cls = i->cls;
 			}