summaryrefslogtreecommitdiff
path: root/src/ir
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir')
-rw-r--r--src/ir/type-updating.cpp18
-rw-r--r--src/ir/type-updating.h24
2 files changed, 31 insertions, 11 deletions
diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp
index 12a8c7c36..760d71b9c 100644
--- a/src/ir/type-updating.cpp
+++ b/src/ir/type-updating.cpp
@@ -28,7 +28,10 @@ namespace wasm {
GlobalTypeRewriter::GlobalTypeRewriter(Module& wasm) : wasm(wasm) {}
-void GlobalTypeRewriter::update() { mapTypes(rebuildTypes()); }
+void GlobalTypeRewriter::update(
+ const std::vector<HeapType>& additionalPrivateTypes) {
+ mapTypes(rebuildTypes(additionalPrivateTypes));
+}
GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes(
const std::vector<HeapType>& additionalPrivateTypes) {
@@ -40,8 +43,17 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes(
Index i = 0;
auto privateTypes = ModuleUtils::getPrivateHeapTypes(wasm);
- for (auto t : additionalPrivateTypes) {
- privateTypes.push_back(t);
+ if (!additionalPrivateTypes.empty()) {
+ // Only add additional private types that are not already in the list.
+ std::unordered_set<HeapType> privateTypesSet(privateTypes.begin(),
+ privateTypes.end());
+
+ for (auto t : additionalPrivateTypes) {
+ if (!privateTypesSet.count(t)) {
+ privateTypes.push_back(t);
+ privateTypesSet.insert(t);
+ }
+ }
}
// Topological sort to have supertypes first, but we have to account for the
diff --git a/src/ir/type-updating.h b/src/ir/type-updating.h
index 1626b40bd..60b92e585 100644
--- a/src/ir/type-updating.h
+++ b/src/ir/type-updating.h
@@ -352,7 +352,12 @@ public:
// Main entry point. This performs the entire process of creating new heap
// types and calling the hooks below, then applies the new types throughout
// the module.
- void update();
+ //
+ // This only operates on private types (so as not to modify the module's
+ // external ABI). It takes as a parameter a list of public types to consider
+ // private, which allows more flexibility (e.g. in closed world if a pass
+ // knows a type is safe to modify despite being public, it can add it).
+ void update(const std::vector<HeapType>& additionalPrivateTypes = {});
using TypeMap = std::unordered_map<HeapType, HeapType>;
@@ -398,7 +403,10 @@ public:
// Helper for the repeating pattern of just updating Signature types using a
// map of old heap type => new Signature.
- static void updateSignatures(const SignatureUpdates& updates, Module& wasm) {
+ static void
+ updateSignatures(const SignatureUpdates& updates,
+ Module& wasm,
+ const std::vector<HeapType>& additionalPrivateTypes = {}) {
if (updates.empty()) {
return;
}
@@ -407,9 +415,11 @@ public:
const SignatureUpdates& updates;
public:
- SignatureRewriter(Module& wasm, const SignatureUpdates& updates)
+ SignatureRewriter(Module& wasm,
+ const SignatureUpdates& updates,
+ const std::vector<HeapType>& additionalPrivateTypes)
: GlobalTypeRewriter(wasm), updates(updates) {
- update();
+ update(additionalPrivateTypes);
}
void modifySignature(HeapType oldSignatureType, Signature& sig) override {
@@ -419,7 +429,7 @@ public:
sig.results = getTempType(iter->second.results);
}
}
- } rewriter(wasm, updates);
+ } rewriter(wasm, updates, additionalPrivateTypes);
}
protected:
@@ -427,9 +437,7 @@ protected:
// returns a map from the old types to the modified types. Used internally in
// update().
//
- // This only operates on private types (so as not to modify the module's
- // external ABI). It takes as a parameter a list of public types to consider
- // private, which allows more flexibility.
+ // See above regarding private types.
TypeMap
rebuildTypes(const std::vector<HeapType>& additionalPrivateTypes = {});