summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/CoalesceLocals.cpp24
1 files changed, 12 insertions, 12 deletions
diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp
index eb3babeb0..313bbc03a 100644
--- a/src/passes/CoalesceLocals.cpp
+++ b/src/passes/CoalesceLocals.cpp
@@ -105,6 +105,10 @@ struct CoalesceLocals
bool interferes(Index i, Index j) {
return interferences.get(std::min(i, j), std::max(i, j));
}
+
+private:
+ // In some cases we need to refinalize at the end.
+ bool refinalize = false;
};
void CoalesceLocals::doWalkFunction(Function* func) {
@@ -118,6 +122,10 @@ void CoalesceLocals::doWalkFunction(Function* func) {
pickIndices(indices);
// apply indices
applyIndices(indices, func->body);
+
+ if (refinalize) {
+ ReFinalize().walkFunctionInModule(func, getModule());
+ }
}
// A copy on a backedge can be especially costly, forcing us to branch just to
@@ -563,21 +571,13 @@ void CoalesceLocals::applyIndices(std::vector<Index>& indices,
drop->value = value;
*action.origin = drop;
} else {
- // This is a tee, and so, as earlier in this function, we must be
- // careful of subtyping. Above we simply avoided the problem by
- // leaving it for other passes, but we do want to remove ineffective
- // stores - nothing else does that as well as this pass. Instead,
- // create a block to cast back to the original type, which avoids
- // changing types here, and leave it to other passes to refine types
- // and remove the block.
auto originalType = (*action.origin)->type;
if (originalType != set->value->type) {
- (*action.origin) =
- Builder(*getModule()).makeBlock({set->value}, originalType);
- } else {
- // No special handling, just use the value.
- *action.origin = set->value;
+ // The value had a more refined type, which we must propagate at
+ // the end.
+ refinalize = true;
}
+ *action.origin = set->value;
}
continue;
}