summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-04-18 14:03:06 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-04-18 14:03:06 -0400
commitc43a07086bdeefe029c5b6da4ec1c8020126d5ca (patch)
treed497b43234d5d59ca40ceb22154d24e15fdeb395
parentc6f3adc52d375d434e3dfd2d23056f0bfdbcdc67 (diff)
downloadroux-c43a07086bdeefe029c5b6da4ec1c8020126d5ca.tar.gz
factor some subtyping logic in clsmerge()
-rw-r--r--all.h2
-rw-r--r--parse.c23
-rw-r--r--ssa.c8
-rw-r--r--util.c17
4 files changed, 32 insertions, 18 deletions
diff --git a/all.h b/all.h
index c729b86..19125b0 100644
--- a/all.h
+++ b/all.h
@@ -190,6 +190,7 @@ enum FCmp {
 };
 
 enum Class {
+	Kx = -1, /* "top" class (see usecheck() and clsmerge()) */
 	Kw,
 	Kl,
 	Ks,
@@ -488,6 +489,7 @@ void idup(Ins **, Ins *, ulong);
 Ins *icpy(Ins *, Ins *, ulong);
 void *vnew(ulong, size_t);
 void vgrow(void *, ulong);
+int clsmerge(short *, short);
 int phicls(int, Tmp *);
 Ref newtmp(char *, int, Fn *);
 void chuse(Ref, int, Fn *);
diff --git a/parse.c b/parse.c
index fa4bd7d..03a89f1 100644
--- a/parse.c
+++ b/parse.c
@@ -4,7 +4,6 @@
 
 enum {
 	Ke = -2, /* Erroneous mode */
-	Kx = -1, /* Invalid operand */
 	Km = Kl, /* Memory pointer (for x64) */
 };
 
@@ -364,7 +363,7 @@ tmpref(char *v)
 	for (t=Tmp0; t<curf->ntmp; t++)
 		if (strcmp(v, curf->tmp[t].name) == 0)
 			return TMP(t);
-	newtmp(0, -1, curf);
+	newtmp(0, Kx, curf);
 	strcpy(curf->tmp[t].name, v);
 	return TMP(t);
 }
@@ -645,7 +644,7 @@ Ins:
 }
 
 static int
-oktype(Ref r, int k, Fn *fn)
+usecheck(Ref r, int k, Fn *fn)
 {
 	return rtype(r) != RTmp || fn->tmp[r.val].cls == k
 		|| (fn->tmp[r.val].cls == Kl && k == Kw);
@@ -672,13 +671,9 @@ typecheck(Fn *fn)
 		for (i=b->ins; i-b->ins < b->nins; i++)
 			if (rtype(i->to) == RTmp) {
 				t = &fn->tmp[i->to.val];
-				k = t->cls;
-				if (k == -1 || (k == Kl && i->cls == Kw))
-					k = i->cls;
-				if (k != i->cls)
+				if (clsmerge(&t->cls, i->cls))
 					err("temporary %%%s is assigned with"
 						" multiple types", t->name);
-				t->cls = k;
 			}
 	}
 	for (b=fn->start; b; b=b->link) {
@@ -693,7 +688,7 @@ typecheck(Fn *fn)
 				if (bshas(ppb, p->blk[n]->id))
 					err("multiple entries for @%s in phi %%%s",
 						p->blk[n]->name, t->name);
-				if (!oktype(p->arg[n], k, fn))
+				if (!usecheck(p->arg[n], k, fn))
 					err("invalid type for operand %%%s in phi %%%s",
 						fn->tmp[p->arg[n].val].name, t->name);
 				bsset(ppb, p->blk[n]->id);
@@ -719,7 +714,7 @@ typecheck(Fn *fn)
 					err("missing %s operand in %s",
 						n == 1 ? "second" : "first",
 						opdesc[i->op].name);
-				if (!oktype(r, k, fn))
+				if (!usecheck(r, k, fn))
 					err("invalid type for %s operand %%%s in %s",
 						n == 1 ? "second" : "first",
 						t->name, opdesc[i->op].name);
@@ -727,12 +722,12 @@ typecheck(Fn *fn)
 		r = b->jmp.arg;
 		if (isret(b->jmp.type)) {
 			if (b->jmp.type == JRetc) {
-				if (!oktype(r, Kl, fn))
+				if (!usecheck(r, Kl, fn))
 					goto JErr;
-			} else if (!oktype(r, b->jmp.type-JRetw, fn))
+			} else if (!usecheck(r, b->jmp.type-JRetw, fn))
 				goto JErr;
 		}
-		if (b->jmp.type == JJnz && !oktype(r, Kw, fn))
+		if (b->jmp.type == JJnz && !usecheck(r, Kw, fn))
 		JErr:
 			err("invalid type for jump argument %%%s in block @%s",
 				fn->tmp[r.val].name, b->name);
@@ -763,7 +758,7 @@ parsefn(int export)
 	curf->con[0].type = CBits;
 	curf->export = export;
 	blink = &curf->start;
-	curf->retty = -1;
+	curf->retty = Kx;
 	if (peek() != TGlo)
 		rcls = parsecls(&curf->retty);
 	else
diff --git a/ssa.c b/ssa.c
index c35fd7e..e5f0f44 100644
--- a/ssa.c
+++ b/ssa.c
@@ -288,7 +288,8 @@ phiins(Fn *fn)
 	Ins *i;
 	Phi *p;
 	Ref r;
-	int t, n, k, nt;
+	int t, n, nt;
+	short k;
 
 	bsinit(u, fn->nblk);
 	bsinit(defs, fn->nblk);
@@ -324,9 +325,8 @@ phiins(Fn *fn)
 							bsset(u, b->id);
 							*--bp = b;
 						}
-						if (k == -1)
-							k = i->cls;
-						assert(k == i->cls);
+						if (clsmerge(&k, i->cls))
+							die("invalid input");
 					}
 				}
 			}
diff --git a/util.c b/util.c
index 96efdfd..527f214 100644
--- a/util.c
+++ b/util.c
@@ -189,6 +189,23 @@ vgrow(void *vp, ulong len)
 }
 
 int
+clsmerge(short *pk, short k)
+{
+	short k1;
+
+	k1 = *pk;
+	if (k1 == Kx) {
+		*pk = k;
+		return 0;
+	}
+	if ((k1 == Kw && k == Kl) || (k1 == Kl && k == Kw)) {
+		*pk = Kw;
+		return 0;
+	}
+	return k1 != k;
+}
+
+int
 phicls(int t, Tmp *tmp /*, int c*/)
 {
 	if (tmp[t].phi)