summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-03-30 12:04:43 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-03-31 09:15:50 -0400
commit729aa97b799f72afdec3604f96526760701f36bc (patch)
tree35761b52e15fe48abe779a07766852717e4e9d6c
parentbeec05cd3b6c85af3f3cc8956f4583d9027d569d (diff)
downloadroux-729aa97b799f72afdec3604f96526760701f36bc.tar.gz
cleanup error handling
-rw-r--r--all.h5
-rw-r--r--copy.c34
-rw-r--r--emit.c40
-rw-r--r--isel.c48
-rw-r--r--mem.c2
-rw-r--r--parse.c12
-rw-r--r--rega.c4
-rw-r--r--spill.c10
-rw-r--r--ssa.c6
-rw-r--r--util.c17
10 files changed, 86 insertions, 92 deletions
diff --git a/all.h b/all.h
index 40c80f6..51b641a 100644
--- a/all.h
+++ b/all.h
@@ -6,6 +6,7 @@
 #include <string.h>
 
 #define MAKESURE(what, x) typedef char make_sure_##what[(x)?1:-1]
+#define die(...) die_(__FILE__, __VA_ARGS__)
 
 typedef unsigned int uint;
 typedef unsigned short ushort;
@@ -481,7 +482,7 @@ extern char debug['Z'+1];
 /* util.c */
 extern Typ typ[NTyp];
 extern Ins insb[NIns], *curi;
-void diag(char *) __attribute__((noreturn));
+void die_(char *, char *, ...) __attribute__((noreturn));
 void *emalloc(size_t);
 void *alloc(size_t);
 void freeall(void);
@@ -522,7 +523,7 @@ extern OpDesc opdesc[NOp];
 void parse(FILE *, char *, void (Dat *), void (Fn *));
 void printfn(Fn *, FILE *);
 void printref(Ref, Fn *, FILE *);
-void err(char *, ...);
+void err(char *, ...) __attribute__((noreturn));
 
 /* mem.c */
 void memopt(Fn *);
diff --git a/copy.c b/copy.c
index ef2d01d..419b079 100644
--- a/copy.c
+++ b/copy.c
@@ -47,7 +47,6 @@ visitphi(Phi *p, Ref *cp, RList **w)
 			break;
 		}
 	}
-	assert(!req(r, R));
 	update(p->to, r, cp, w);
 }
 
@@ -65,6 +64,15 @@ visitins(Ins *i, Ref *cp, RList **w)
 	}
 }
 
+static void
+subst(Ref *r, Ref *cp, Fn *fn)
+{
+	if (rtype(*r) == RTmp && req(copyof(*r, cp), R))
+		err("temporary %%%s is used undefined",
+			fn->tmp[r->val].name);
+	*r = copyof(*r, cp);
+}
+
 void
 copy(Fn *fn)
 {
@@ -93,8 +101,6 @@ copy(Fn *fn)
 		u1 = u + fn->tmp[t].nuse;
 		for (; u<u1; u++)
 			switch (u->type) {
-			default:
-				diag("copy: invalid use");
 			case UPhi:
 				visitphi(u->u.phi, cp, &w);
 				break;
@@ -103,6 +109,8 @@ copy(Fn *fn)
 				break;
 			case UJmp:
 				break;
+			default:
+				die("invalid use %d", u->type);
 			}
 	}
 	for (b=fn->start; b; b=b->link) {
@@ -113,31 +121,19 @@ copy(Fn *fn)
 				continue;
 			}
 			for (a=0; a<p->narg; a++)
-				if (rtype(p->arg[a]) == RTmp) {
-					r = cp[p->arg[a].val];
-					assert(!req(r, R));
-					p->arg[a] = r;
-				}
+				subst(&p->arg[a], cp, fn);
 			pp=&p->link;
 		}
 		for (i=b->ins; i-b->ins < b->nins; i++) {
-			r = cp[i->to.val];
+			r = copyof(i->to, cp);
 			if (!req(r, i->to)) {
 				*i = (Ins){.op = ONop};
 				continue;
 			}
 			for (a=0; a<2; a++)
-				if (rtype(i->arg[a]) == RTmp) {
-					r = cp[i->arg[a].val];
-					assert(!req(r, R));
-					i->arg[a] = r;
-				}
-		}
-		if (rtype(b->jmp.arg) == RTmp) {
-			r = cp[b->jmp.arg.val];
-			assert(!req(r, R));
-			b->jmp.arg = r;
+				subst(&i->arg[a], cp, fn);
 		}
+		subst(&b->jmp.arg, cp, fn);
 	}
 	if (debug['C']) {
 		fprintf(stderr, "\n> Copy information:");
diff --git a/emit.c b/emit.c
index 7309170..32e4078 100644
--- a/emit.c
+++ b/emit.c
@@ -133,7 +133,7 @@ slot(int s, Fn *fn)
 
 	/* sign extend s using a bitfield */
 	x.i = s;
-	assert(NAlign == 3);
+	/* specific to NAlign == 3 */
 	if (x.i < 0)
 		return -4 * x.i;
 	else {
@@ -146,8 +146,6 @@ static void
 emitcon(Con *con, FILE *f)
 {
 	switch (con->type) {
-	default:
-		diag("emit: invalid constant");
 	case CAddr:
 		if (con->local)
 			fprintf(f, "%s%s", locprefix, con->label);
@@ -159,6 +157,8 @@ emitcon(Con *con, FILE *f)
 	case CBits:
 		fprintf(f, "%"PRId64, con->bits.i);
 		break;
+	default:
+		die("unreachable");
 	}
 }
 
@@ -178,14 +178,14 @@ static Ref
 getarg(char c, Ins *i)
 {
 	switch (c) {
-	default:
-		diag("emit: 0, 1, = expected in format");
 	case '0':
 		return i->arg[0];
 	case '1':
 		return i->arg[1];
 	case '=':
 		return i->to;
+	default:
+		die("invalid arg letter %c", c);
 	}
 }
 
@@ -222,8 +222,8 @@ emitf(char *s, Ins *i, Fn *fn, FILE *f)
 		}
 		/* fall through */
 	case '-':
-		if (req(i->arg[1], i->to) && !req(i->arg[0], i->to))
-			diag("emit: cannot convert to 2-address");
+		assert((!req(i->arg[1], i->to) || req(i->arg[0], i->to)) &&
+			"cannot convert to 2-address");
 		emitcopy(i->to, i->arg[0], i->cls, fn, f);
 		s++;
 		break;
@@ -238,8 +238,6 @@ Next:
 		} else
 			fputc(c, f);
 	switch ((c = *s++)) {
-	default:
-		diag("emit: invalid escape");
 	case '%':
 		fputc('%', f);
 		break;
@@ -258,8 +256,6 @@ Next:
 		c = *s++;
 		ref = getarg(c, i);
 		switch (rtype(ref)) {
-		default:
-			diag("emit: invalid reference");
 		case RTmp:
 			assert(isreg(ref));
 			fprintf(f, "%%%s", regtoa(ref.val, sz));
@@ -294,6 +290,8 @@ Next:
 			fputc('$', f);
 			emitcon(&fn->con[ref.val], f);
 			break;
+		default:
+			die("unreachable");
 		}
 		break;
 	case 'L':
@@ -312,8 +310,6 @@ Next:
 		c = *s++;
 		ref = getarg(c, i);
 		switch (rtype(ref)) {
-		default:
-			diag("emit: invalid memory reference");
 		case RAMem:
 			goto Mem;
 		case RSlot:
@@ -327,8 +323,12 @@ Next:
 			assert(isreg(ref));
 			fprintf(f, "(%%%s)", regtoa(ref.val, SLong));
 			break;
+		default:
+			die("unreachable");
 		}
 		break;
+	default:
+		die("invalid format specifier %%%c", c);
 	}
 	goto Next;
 }
@@ -350,7 +350,7 @@ emitins(Ins i, Fn *fn, FILE *f)
 			/* this linear search should really be a binary
 			 * search */
 			if (omap[o].op == NOp)
-				diag("emit: no entry found for instruction");
+				die("not match for %d(%d)", i.op, i.cls);
 			if (omap[o].op == i.op)
 			if (omap[o].cls == i.cls
 			|| (omap[o].cls == Ki && KBASE(i.cls) == 0)
@@ -412,8 +412,6 @@ emitins(Ins i, Fn *fn, FILE *f)
 		/* calls simply have a weird syntax in AT&T
 		 * assembly... */
 		switch (rtype(i.arg[0])) {
-		default:
-			diag("emit: invalid call instruction");
 		case RCon:
 			fprintf(f, "\tcallq ");
 			emitcon(&fn->con[i.arg[0].val], f);
@@ -422,6 +420,8 @@ emitins(Ins i, Fn *fn, FILE *f)
 		case RTmp:
 			emitf("callq *%L0", &i, fn, f);
 			break;
+		default:
+			die("invalid call argument");
 		}
 		break;
 	case OSAlloc:
@@ -450,7 +450,7 @@ static int
 cneg(int cmp)
 {
 	switch (cmp) {
-	default:   diag("emit: cneg() unhandled comparison");
+	default:    die("invalid int comparison %d", cmp);
 	case ICule: return ICugt;
 	case ICult: return ICuge;
 	case ICsle: return ICsgt;
@@ -471,7 +471,7 @@ framesz(Fn *fn)
 {
 	int i, o, f;
 
-	assert(NAlign == 3);
+	/* specific to NAlign == 3 */
 	for (i=0, o=0; i<NRClob; i++)
 		o ^= 1 & (fn->reg >> rclob[i]);
 	f = fn->slot;
@@ -549,12 +549,12 @@ emitfn(Fn *fn, FILE *f)
 					c = cneg(c);
 					s = b->s2;
 				} else
-					diag("emit: unhandled jump (1)");
+					die("unhandled jump");
 				fprintf(f, "\tj%s %sbb%d /* %s */\n",
 					ctoa[c], locprefix, id0+s->id, s->name);
 				break;
 			}
-			diag("emit: unhandled jump (2)");
+			die("unhandled jump %d", b->jmp.type);
 		}
 	}
 	id0 += fn->nblk;
diff --git a/isel.c b/isel.c
index 2a55733..6d19ccc 100644
--- a/isel.c
+++ b/isel.c
@@ -35,7 +35,7 @@ static int
 fcmptoi(int fc)
 {
 	switch (fc) {
-	default:   diag("isel: fcmptoi defaulted");
+	default:   die("invalid fp comparison %d", fc);
 	case FCle: return ICule;
 	case FClt: return ICult;
 	case FCgt: return ICugt;
@@ -85,8 +85,6 @@ noimm(Ref r, Fn *fn)
 	if (rtype(r) != RCon)
 		return 0;
 	switch (fn->con[r.val].type) {
-	default:
-		diag("isel: invalid constant");
 	case CAddr:
 		/* we only support the 'small'
 		 * code model of the ABI, this
@@ -97,6 +95,8 @@ noimm(Ref r, Fn *fn)
 	case CBits:
 		val = fn->con[r.val].bits.i;
 		return (val < INT32_MIN || val > INT32_MAX);
+	default:
+		die("invalid constant");
 	}
 }
 
@@ -208,7 +208,7 @@ sel(Ins i, ANum *an, Fn *fn)
 {
 	Ref r0, r1;
 	int x, k, kc;
-	int64_t val;
+	int64_t sz;
 	Ins *i0;
 
 	if (rtype(i.to) == RTmp)
@@ -308,12 +308,11 @@ Emit:
 		 * (rsp = 0) mod 16
 		 */
 		if (rtype(i.arg[0]) == RCon) {
-			assert(fn->con[i.arg[0].val].type == CBits);
-			val = fn->con[i.arg[0].val].bits.i;
-			val = (val + 15)  & ~INT64_C(15);
-			if (val < 0 || val > INT32_MAX)
-				diag("isel: alloc too large");
-			emit(OSAlloc, Kl, i.to, getcon(val, fn), R);
+			sz = fn->con[i.arg[0].val].bits.i;
+			if (sz < 0 || sz >= INT_MAX-15)
+				err("invalid alloc size %"PRId64, sz);
+			sz = (sz + 15)  & -16;
+			emit(OSAlloc, Kl, i.to, getcon(sz, fn), R);
 		} else {
 			/* r0 = (i.arg[0] + 15) & -16 */
 			r0 = newtmp("isel", Kl, fn);
@@ -335,13 +334,13 @@ Emit:
 			selcmp(i.arg, kc, fn);
 			break;
 		}
-		diag("isel: non-exhaustive implementation");
+		die("unknown instruction");
 	}
 
-	while (i0 > curi && --i0)
-		if (rslot(i0->arg[0], fn) != -1
-		||  rslot(i0->arg[1], fn) != -1)
-			diag("isel: usupported address argument");
+	while (i0 > curi && --i0) {
+		assert(rslot(i0->arg[0], fn) == -1);
+		assert(rslot(i0->arg[1], fn) == -1);
+	}
 }
 
 static Ins *
@@ -733,7 +732,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap)
 		}
 		/* allocate return pad */
 		ra = alloc(sizeof *ra);
-		assert(NAlign == 3);
+		/* specific to NAlign == 3 */
 		aret.align -= 2;
 		if (aret.align < 0)
 			aret.align = 0;
@@ -822,7 +821,7 @@ selpar(Fn *fn, Ins *i0, Ins *i1)
 	} else
 		classify(i0, i1, ac, OPar, 0);
 
-	assert(NAlign == 3);
+	/* specific to NAlign == 3 */
 
 	s = 4;
 	for (i=i0, a=ac; i<i1; i++, a++) {
@@ -856,7 +855,6 @@ selpar(Fn *fn, Ins *i0, Ins *i1)
 	for (i=i0, a=ac; i<i1; i++, a++) {
 		if (i->op != OParc || a->inmem)
 			continue;
-		assert(NAlign == 3);
 		for (al=0; a->align >> (al+2); al++)
 			;
 		r = TMP(a->cls[0]);
@@ -876,12 +874,12 @@ static int
 aref(Ref r, ANum *ai)
 {
 	switch (rtype(r)) {
-	default:
-		diag("isel: aref defaulted");
 	case RCon:
 		return 2;
 	case RTmp:
 		return ai[r.val].n;
+	default:
+		die("constant or temporary expected");
 	}
 }
 
@@ -986,8 +984,6 @@ amatch(Addr *a, Ref r, ANum *ai, Fn *fn, int top)
 		}
 	}
 	switch (ai[r.val].n) {
-	default:
-		diag("isel: amatch defaulted");
 	case 3: /* s * i */
 		if (!top) {
 			a->index = al;
@@ -1023,6 +1019,8 @@ amatch(Addr *a, Ref r, ANum *ai, Fn *fn, int top)
 		amatch(a, ar, ai, fn, 0);
 		amatch(a, al, ai, fn, 0);
 		break;
+	default:
+		die("unreachable");
 	}
 }
 
@@ -1092,15 +1090,15 @@ isel(Fn *fn)
 
 	/* assign slots to fast allocs */
 	b = fn->start;
-	assert(NAlign == 3 && "change n=4 and sz /= 4 below");
+	/* specific to NAlign == 3 */ /* or change n=4 and sz /= 4 below */
 	for (al=OAlloc, n=4; al<=OAlloc1; al++, n*=2)
 		for (i=b->ins; i-b->ins < b->nins; i++)
 			if (i->op == al) {
 				if (rtype(i->arg[0]) != RCon)
 					break;
 				sz = fn->con[i->arg[0].val].bits.i;
-				if (sz < 0 || sz >= INT_MAX-3)
-					diag("isel: invalid alloc size");
+				if (sz < 0 || sz >= INT_MAX-15)
+					err("invalid alloc size %"PRId64, sz);
 				sz = (sz + n-1) & -n;
 				sz /= 4;
 				fn->tmp[i->to.val].slot = fn->slot;
diff --git a/mem.c b/mem.c
index bda43d7..98556e1 100644
--- a/mem.c
+++ b/mem.c
@@ -22,7 +22,7 @@ memopt(Fn *fn)
 	for (i=b->ins; i-b->ins < b->nins; i++) {
 		if (OAlloc > i->op || i->op > OAlloc1)
 			continue;
-		assert(NAlign == 3);
+		/* specific to NAlign == 3 */
 		assert(rtype(i->to) == RTmp);
 		t = &fn->tmp[i->to.val];
 		for (u=t->use; u != &t->use[t->nuse]; u++) {
diff --git a/parse.c b/parse.c
index 2590971..1fd032a 100644
--- a/parse.c
+++ b/parse.c
@@ -159,18 +159,14 @@ static int ntyp;
 void
 err(char *s, ...)
 {
-	char buf[100], *p, *end;
 	va_list ap;
 
-	p = buf;
-	end = buf + sizeof(buf);
-
 	va_start(ap, s);
-	p += snprintf(p, end - p, "%s:%d: ", inpath, lnum);
-	p += vsnprintf(p, end - p, s, ap);
+	fprintf(stderr, "%s:%d: ", inpath, lnum);
+	vfprintf(stderr, s, ap);
+	fprintf(stderr, "\n");
 	va_end(ap);
-
-	diag(buf);
+	exit(1);
 }
 
 static int
diff --git a/rega.c b/rega.c
index 7f8edcf..0f1ad17 100644
--- a/rega.c
+++ b/rega.c
@@ -125,7 +125,7 @@ ralloc(RMap *m, int t)
 		for (r=r0; r<r1; r++)
 			if (!bshas(m->b, r))
 				goto Found;
-		diag("rega: no more regs");
+		die("no more regs");
 	}
 Found:
 	radd(m, t, r);
@@ -170,7 +170,7 @@ pmadd(Ref src, Ref dst, int k)
 		cpm = cpm * 2 + 16;
 		pm = realloc(pm, cpm * sizeof pm[0]);
 		if (!pm)
-			diag("pmadd: out of memory");
+			die("pmadd, out of memory");
 	}
 	pm[npm].src = src;
 	pm[npm].dst = dst;
diff --git a/spill.c b/spill.c
index 72f8106..8684993 100644
--- a/spill.c
+++ b/spill.c
@@ -94,8 +94,7 @@ fillcost(Fn *fn)
 			tmpuse(p->to, 0, 0, fn);
 			for (a=0; a<p->narg; a++) {
 				n = p->blk[a]->loop;
-				assert(b->npred==p->narg &&
-					"wrong cfg");
+				assert(b->npred==p->narg && "wrong cfg");
 				n /= b->npred;
 				tmpuse(p->arg[a], 1, n, fn);
 			}
@@ -146,11 +145,10 @@ slot(int t)
 {
 	int s;
 
-	if (t < Tmp0)
-		diag("spill: cannot spill register");
+	assert(t >= Tmp0 && "cannot spill register");
 	s = tmp[t].slot;
 	if (s == -1) {
-		assert(NAlign == 3);
+		/* specific to NAlign == 3 */
 		/* nice logic to pack stack slots
 		 * on demand, there can be only
 		 * one hole and slot4 points to it
@@ -491,7 +489,7 @@ spill(Fn *fn)
 	}
 
 	/* align the locals to a 16 byte boundary */
-	assert(NAlign == 3);
+	/* specific to NAlign == 3 */
 	slot8 += slot8 & 3;
 	fn->slot += slot8;
 
diff --git a/ssa.c b/ssa.c
index 0c163aa..201f22c 100644
--- a/ssa.c
+++ b/ssa.c
@@ -15,8 +15,6 @@ adduse(Tmp *tmp, int ty, Blk *b, ...)
 	u->type = ty;
 	u->bid = b->id;
 	switch (ty) {
-	default:
-		diag("ssa: adduse defaulted");
 	case UPhi:
 		u->u.phi = va_arg(ap, Phi *);
 		break;
@@ -25,6 +23,8 @@ adduse(Tmp *tmp, int ty, Blk *b, ...)
 		break;
 	case UJmp:
 		break;
+	default:
+		die("unreachable");
 	}
 	va_end(ap);
 }
@@ -465,7 +465,7 @@ renblk(Blk *b, Name **stk, Fn *fn)
 			if ((t=fn->tmp[t].visit)) {
 				m = p->narg++;
 				if (m == NPred)
-					diag("ssa: too many phi arguments");
+					die("renblk, too many phi args");
 				p->arg[m] = getstk(t, b, stk);
 				p->blk[m] = b;
 			}
diff --git a/util.c b/util.c
index 65b3ff8..1654491 100644
--- a/util.c
+++ b/util.c
@@ -1,4 +1,5 @@
 #include "all.h"
+#include <stdarg.h>
 
 typedef struct Bitset Bitset;
 typedef struct Vec Vec;
@@ -28,9 +29,14 @@ static void **pool = ptr;
 static int nptr = 1;
 
 void
-diag(char *s)
+die_(char *file, char *s, ...)
 {
-	fputs(s, stderr);
+	va_list ap;
+
+	fprintf(stderr, "%s: dying: ", file);
+	va_start(ap, s);
+	vfprintf(stderr, s, ap);
+	va_end(ap);
 	fputc('\n', stderr);
 	abort();
 }
@@ -42,7 +48,7 @@ emalloc(size_t n)
 
 	p = calloc(1, n);
 	if (!p)
-		diag("emalloc: out of memory");
+		die("emalloc, out of memory");
 	return p;
 }
 
@@ -95,7 +101,7 @@ void
 emit(int op, int k, Ref to, Ref arg0, Ref arg1)
 {
 	if (curi == insb)
-		diag("emit: too many instructions");
+		die("emit, too many instructions");
 	*--curi = (Ins){
 		.op = op, .cls = k,
 		.to = to, .arg = {arg0, arg1}
@@ -210,8 +216,7 @@ addcon(Con *c0, Con *c1)
 		*c0 = *c1;
 	else {
 		if (c1->type == CAddr) {
-			if (c0->type == CAddr)
-				diag("addcon: adding two addresses");
+			assert(c0->type != CAddr && "adding two addresses");
 			c0->type = CAddr;
 			strcpy(c0->label, c1->label);
 		}