diff options
author | Alon Zakai <azakai@google.com> | 2022-03-30 09:27:51 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-30 09:27:51 -0700 |
commit | 3995481071fd746ca8b8479d182aad257cab82e2 (patch) | |
tree | c007ee925182f8093aac88df3f84223cdffef28e /src/ir/struct-utils.h | |
parent | cdf5d6e602f5d67116627384c11021b4fc0a3f4d (diff) | |
download | binaryen-3995481071fd746ca8b8479d182aad257cab82e2.tar.gz binaryen-3995481071fd746ca8b8479d182aad257cab82e2.tar.bz2 binaryen-3995481071fd746ca8b8479d182aad257cab82e2.zip |
[Wasm GC] GlobalTypeOptimization: Remove fields from end based on subtypes (#4553)
Previously we'd remove a field from a type if that field has no uses in any
sub- or super-type. In that case we'd remove it from all the types at once.
However, there is a case where we can remove a field only from a parent
but not from its children, if the field is at the end: if A has fields {x, y, z}
and its subtype B has fields {x, y, z, w}, and A pointers only access
field y while B pointers access all the fields, then we can remove z
from A. Removing it from the end is safe, and then B will not only add
w as it did before but also add z. Note that we cannot remove x,
because it is not at the end: removing it from just A but not B would
shift the indexes, making them incompatible.
Diffstat (limited to 'src/ir/struct-utils.h')
-rw-r--r-- | src/ir/struct-utils.h | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/src/ir/struct-utils.h b/src/ir/struct-utils.h index f68692363..bc2eb5485 100644 --- a/src/ir/struct-utils.h +++ b/src/ir/struct-utils.h @@ -221,15 +221,21 @@ public: SubTypes subTypes; void propagateToSuperTypes(StructValuesMap<T>& infos) { - propagate(infos, false); + propagate(infos, false, true); + } + + void propagateToSubTypes(StructValuesMap<T>& infos) { + propagate(infos, true, false); } void propagateToSuperAndSubTypes(StructValuesMap<T>& infos) { - propagate(infos, true); + propagate(infos, true, true); } private: - void propagate(StructValuesMap<T>& combinedInfos, bool toSubTypes) { + void propagate(StructValuesMap<T>& combinedInfos, + bool toSubTypes, + bool toSuperTypes) { UniqueDeferredQueue<HeapType> work; for (auto& [type, _] : combinedInfos) { work.push(type); @@ -238,13 +244,15 @@ private: auto type = work.pop(); auto& infos = combinedInfos[type]; - // Propagate shared fields to the supertype. - if (auto superType = type.getSuperType()) { - auto& superInfos = combinedInfos[*superType]; - auto& superFields = superType->getStruct().fields; - for (Index i = 0; i < superFields.size(); i++) { - if (superInfos[i].combine(infos[i])) { - work.push(*superType); + if (toSuperTypes) { + // Propagate shared fields to the supertype. + if (auto superType = type.getSuperType()) { + auto& superInfos = combinedInfos[*superType]; + auto& superFields = superType->getStruct().fields; + for (Index i = 0; i < superFields.size(); i++) { + if (superInfos[i].combine(infos[i])) { + work.push(*superType); + } } } } |