diff options
author | Alon Zakai <azakai@google.com> | 2024-10-29 11:41:43 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-29 11:41:43 -0700 |
commit | 2a1cb314d6a028cfd54374f89a47e111678c3d25 (patch) | |
tree | 33cd9be7cc4112ddd6a86c5f381bd50133e9d064 /src | |
parent | 3d3a38700f29236eb7e66742fdc2df8616ab7599 (diff) | |
download | binaryen-2a1cb314d6a028cfd54374f89a47e111678c3d25.tar.gz binaryen-2a1cb314d6a028cfd54374f89a47e111678c3d25.tar.bz2 binaryen-2a1cb314d6a028cfd54374f89a47e111678c3d25.zip |
[GC] Fix handling of public types in TypeRefining (#7037)
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/TypeRefining.cpp | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/passes/TypeRefining.cpp b/src/passes/TypeRefining.cpp index c7a1fce6e..ee12c388d 100644 --- a/src/passes/TypeRefining.cpp +++ b/src/passes/TypeRefining.cpp @@ -137,6 +137,11 @@ struct TypeRefining : public Pass { // that we can avoid wasteful work later if not. bool canOptimize = false; + // We cannot modify public types. + auto publicTypes = ModuleUtils::getPublicHeapTypes(*module); + std::unordered_set<HeapType> publicTypesSet(publicTypes.begin(), + publicTypes.end()); + // We have combined all the information we have about writes to the fields, // but we still need to make sure that the new types makes sense. In // particular, subtyping cares about things like mutability, and we also @@ -155,6 +160,14 @@ struct TypeRefining : public Pass { while (!work.empty()) { auto type = work.pop(); + for (auto subType : subTypes.getImmediateSubTypes(type)) { + work.push(subType); + } + + if (publicTypesSet.count(type)) { + continue; + } + // First, find fields that have nothing written to them at all, and set // their value to their old type. We must pick some type for the field, // and we have nothing better to go on. (If we have a super, and it does @@ -173,7 +186,14 @@ struct TypeRefining : public Pass { if (auto super = type.getDeclaredSuperType()) { auto& superFields = super->getStruct().fields; for (Index i = 0; i < superFields.size(); i++) { - auto newSuperType = finalInfos[*super][i].getLUB(); + // The super's new type is either what we propagated, or, if it is + // public, unchanged since we cannot optimize it + Type newSuperType; + if (!publicTypesSet.count(*super)) { + newSuperType = finalInfos[*super][i].getLUB(); + } else { + newSuperType = superFields[i].type; + } auto& info = finalInfos[type][i]; auto newType = info.getLUB(); if (!Type::isSubType(newType, newSuperType)) { @@ -215,10 +235,6 @@ struct TypeRefining : public Pass { canOptimize = true; } } - - for (auto subType : subTypes.getImmediateSubTypes(type)) { - work.push(subType); - } } if (canOptimize) { |