summary refs log tree commit diff
path: root/alias.c
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2017-04-10 09:09:56 -0400
committerQuentin Carbonneaux <quentin@c9x.me>2017-04-10 09:19:40 -0400
commit19801b9253140443f7c04325dbf67581092b1a99 (patch)
tree223268761cd1ff362d779b8d6c5e2372a0e288a7 /alias.c
parent8241685fb92b44556a870ff33bc3eca75aae8637 (diff)
downloadroux-19801b9253140443f7c04325dbf67581092b1a99.tar.gz
simplify slot logic in alias analysis
The previous code was buggy.  It would put a stack
pointer on the heap when handling "add $foo, 42".
The new code is more straightforward and hopefully
more correct.  Only temporaries with a "stack"
alias class will have a slot pointer.
Diffstat (limited to 'alias.c')
-rw-r--r--alias.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/alias.c b/alias.c
index ed64501..77d5d73 100644
--- a/alias.c
+++ b/alias.c
@@ -10,7 +10,8 @@ getalias(Alias *a, Ref r, Fn *fn)
 		die("unreachable");
 	case RTmp:
 		*a = fn->tmp[r.val].alias;
-		a->type = a->slot->type;
+		if (astack(a->type))
+			a->type = a->slot->type;
 		assert(a->type != ABot);
 		break;
 	case RCon:
@@ -21,7 +22,7 @@ getalias(Alias *a, Ref r, Fn *fn)
 		} else
 			a->type = ACon;
 		a->offset = c->bits.i;
-		a->slot = a;
+		a->slot = 0;
 		break;
 	}
 }
@@ -37,7 +38,7 @@ alias(Ref p, int sp, Ref q, int sq, int *delta, Fn *fn)
 	*delta = ap.offset - aq.offset;
 	ovlap = ap.offset < aq.offset + sq && aq.offset < ap.offset + sp;
 
-	if (ap.type & aq.type & 1) {
+	if (astack(ap.type) && astack(aq.type)) {
 		/* if both are offsets of the same
 		 * stack slot, they alias iif they
 		 * overlap */
@@ -86,7 +87,7 @@ escapes(Ref r, Fn *fn)
 	if (rtype(r) != RTmp)
 		return 1;
 	a = &fn->tmp[r.val].alias;
-	return !(a->type & 1) || a->slot->type == AEsc;
+	return !astack(a->type) || a->slot->type == AEsc;
 }
 
 static void
@@ -97,7 +98,7 @@ esc(Ref r, Fn *fn)
 	assert(rtype(r) <= RType);
 	if (rtype(r) == RTmp) {
 		a = &fn->tmp[r.val].alias;
-		if (a->slot->type == ALoc)
+		if (astack(a->type))
 			a->slot->type = AEsc;
 	}
 }
@@ -120,7 +121,7 @@ fillalias(Fn *fn)
 			a->type = AUnk;
 			a->base = p->to;
 			a->offset = 0;
-			a->slot = a;
+			a->slot = 0;
 		}
 		for (i=b->ins; i<&b->ins[b->nins]; ++i) {
 			a = 0;
@@ -128,13 +129,15 @@ fillalias(Fn *fn)
 				assert(rtype(i->to) == RTmp);
 				a = &fn->tmp[i->to.val].alias;
 				assert(a->type == ABot);
-				if (Oalloc <= i->op && i->op <= Oalloc1)
+				if (Oalloc <= i->op && i->op <= Oalloc1) {
 					a->type = ALoc;
-				else
+					a->slot = a;
+				} else {
 					a->type = AUnk;
+					a->slot = 0;
+				}
 				a->base = i->to;
 				a->offset = 0;
-				a->slot = a;
 			}
 			if (i->op == Ocopy) {
 				assert(a);