summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2017-02-24 12:00:38 -0500
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2017-02-24 12:00:38 -0500
commita35dc8c495467306ca149d642b2d2983922d7a9d (patch)
treeb6c7958a7252fd489f7aac02ecc17e1b54948614
parent5165fcae767801a20316530c0ec9f096158aa2e4 (diff)
downloadroux-a35dc8c495467306ca149d642b2d2983922d7a9d.tar.gz
fix pretty bad bug in alias analysis
When a temporary marked local is escaping,
the whole slot must be marked as such.  To
solve this, Alias now holds a pointer to
the alias information of the slot.  For
simplicity of the code, this pointer is
always valid and fetching ->type out of it
is meaningful.
-rw-r--r--alias.c14
-rw-r--r--all.h1
2 files changed, 11 insertions, 4 deletions
diff --git a/alias.c b/alias.c
index a24d9b3..ed64501 100644
--- a/alias.c
+++ b/alias.c
@@ -10,6 +10,7 @@ getalias(Alias *a, Ref r, Fn *fn)
 		die("unreachable");
 	case RTmp:
 		*a = fn->tmp[r.val].alias;
+		a->type = a->slot->type;
 		assert(a->type != ABot);
 		break;
 	case RCon:
@@ -20,6 +21,7 @@ getalias(Alias *a, Ref r, Fn *fn)
 		} else
 			a->type = ACon;
 		a->offset = c->bits.i;
+		a->slot = a;
 		break;
 	}
 }
@@ -79,9 +81,12 @@ alias(Ref p, int sp, Ref q, int sq, int *delta, Fn *fn)
 int
 escapes(Ref r, Fn *fn)
 {
+	Alias *a;
+
 	if (rtype(r) != RTmp)
 		return 1;
-	return fn->tmp[r.val].alias.type != ALoc;
+	a = &fn->tmp[r.val].alias;
+	return !(a->type & 1) || a->slot->type == AEsc;
 }
 
 static void
@@ -92,9 +97,8 @@ esc(Ref r, Fn *fn)
 	assert(rtype(r) <= RType);
 	if (rtype(r) == RTmp) {
 		a = &fn->tmp[r.val].alias;
-		assert(a->type != ABot);
-		if (a->type == ALoc)
-			a->type = AEsc;
+		if (a->slot->type == ALoc)
+			a->slot->type = AEsc;
 	}
 }
 
@@ -116,6 +120,7 @@ fillalias(Fn *fn)
 			a->type = AUnk;
 			a->base = p->to;
 			a->offset = 0;
+			a->slot = a;
 		}
 		for (i=b->ins; i<&b->ins[b->nins]; ++i) {
 			a = 0;
@@ -129,6 +134,7 @@ fillalias(Fn *fn)
 					a->type = AUnk;
 				a->base = i->to;
 				a->offset = 0;
+				a->slot = a;
 			}
 			if (i->op == Ocopy) {
 				assert(a);
diff --git a/all.h b/all.h
index b073124..128d16c 100644
--- a/all.h
+++ b/all.h
@@ -391,6 +391,7 @@ struct Alias {
 	Ref base;
 	char label[NString];
 	int64_t offset;
+	Alias *slot;
 };
 
 struct Tmp {