aboutsummaryrefslogtreecommitdiff
path: root/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'mem.c')
-rw-r--r--mem.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/mem.c b/mem.c
index a574e1f..7570f19 100644
--- a/mem.c
+++ b/mem.c
@@ -197,7 +197,7 @@ coalesce(Fn *fn)
Blk *b, **ps, *succ[3];
Ins *i;
Use *u;
- Tmp *t;
+ Tmp *t, *ts;
Ref *arg;
bits x;
int n, m, nsl, ip, *stk;
@@ -213,6 +213,7 @@ coalesce(Fn *fn)
t->visit = -1;
if (t->alias.type == ALoc)
if (t->alias.slot == &t->alias)
+ if (t->bid == fn->start->id)
if (t->alias.u.loc.sz != -1) {
t->visit = nsl;
vgrow(&sl, ++nsl);
@@ -356,11 +357,22 @@ coalesce(Fn *fn)
/* substitute fused slots */
for (s=sl; s<&sl[nsl]; s++) {
- if (s->s == s)
- continue;
t = &fn->tmp[s->t];
assert(t->ndef == 1 && t->def);
+ if (s->s == s)
+ continue;
*t->def = (Ins){.op = Onop};
+ ts = &fn->tmp[s->s->t];
+ assert(t->bid == ts->bid);
+ if (t->def < ts->def) {
+ /* make sure the slot we
+ * selected has a def that
+ * dominates its new uses
+ */
+ *t->def = *ts->def;
+ *ts->def = (Ins){.op = Onop};
+ ts->def = t->def;
+ }
for (u=t->use; u<&t->use[t->nuse]; u++) {
if (u->type == UJmp) {
b = fn->rpo[u->bid];