summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/TypeMerging.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/passes/TypeMerging.cpp b/src/passes/TypeMerging.cpp
index 1345071d1..aa9fcca67 100644
--- a/src/passes/TypeMerging.cpp
+++ b/src/passes/TypeMerging.cpp
@@ -57,13 +57,26 @@ using ReferredTypes = SmallUnorderedSet<HeapType, 5>;
struct CastFinder : public PostWalker<CastFinder> {
ReferredTypes referredTypes;
+ // If traps never happen, then ref.cast and call_indirect can never
+ // differentiate between types since they always succeed. Take advantage of
+ // that by not having those instructions inhibit merges in TNH mode.
+ // mode.
+ bool trapsNeverHappen;
+
+ CastFinder(const PassOptions& options)
+ : trapsNeverHappen(options.trapsNeverHappen) {}
+
template<typename T> void visitCast(T* curr) {
if (auto type = curr->getCastType(); type != Type::unreachable) {
referredTypes.insert(type.getHeapType());
}
}
- void visitRefCast(RefCast* curr) { visitCast(curr); }
+ void visitRefCast(RefCast* curr) {
+ if (!trapsNeverHappen) {
+ visitCast(curr);
+ }
+ }
void visitRefTest(RefTest* curr) { visitCast(curr); }
@@ -74,7 +87,9 @@ struct CastFinder : public PostWalker<CastFinder> {
}
void visitCallIndirect(CallIndirect* curr) {
- referredTypes.insert(curr->heapType);
+ if (!trapsNeverHappen) {
+ referredTypes.insert(curr->heapType);
+ }
}
};
@@ -108,14 +123,14 @@ struct TypeMerging : public Pass {
return;
}
- CastFinder finder;
+ CastFinder finder(getPassOptions());
finder.walk(func->body);
referredTypes = std::move(finder.referredTypes);
});
// Also find cast types in the module scope (not possible in the current
// spec, but do it to be future-proof).
- CastFinder moduleFinder;
+ CastFinder moduleFinder(getPassOptions());
moduleFinder.walkModuleCode(module);
// Accumulate all the referredTypes.