diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2017-02-24 12:00:38 -0500 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2017-02-24 12:00:38 -0500 |
commit | a35dc8c495467306ca149d642b2d2983922d7a9d (patch) | |
tree | b6c7958a7252fd489f7aac02ecc17e1b54948614 | |
parent | 5165fcae767801a20316530c0ec9f096158aa2e4 (diff) | |
download | roux-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.c | 14 | ||||
-rw-r--r-- | all.h | 1 |
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 { |