diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/CoalesceLocals.cpp | 24 |
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; } |