summaryrefslogtreecommitdiff
path: root/src/ir/struct-utils.h
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-03-30 09:27:51 -0700
committerGitHub <noreply@github.com>2022-03-30 09:27:51 -0700
commit3995481071fd746ca8b8479d182aad257cab82e2 (patch)
treec007ee925182f8093aac88df3f84223cdffef28e /src/ir/struct-utils.h
parentcdf5d6e602f5d67116627384c11021b4fc0a3f4d (diff)
downloadbinaryen-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.h28
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);
+ }
}
}
}