From 3995481071fd746ca8b8479d182aad257cab82e2 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 30 Mar 2022 09:27:51 -0700 Subject: [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. --- src/ir/struct-utils.h | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'src/ir/struct-utils.h') 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& infos) { - propagate(infos, false); + propagate(infos, false, true); + } + + void propagateToSubTypes(StructValuesMap& infos) { + propagate(infos, true, false); } void propagateToSuperAndSubTypes(StructValuesMap& infos) { - propagate(infos, true); + propagate(infos, true, true); } private: - void propagate(StructValuesMap& combinedInfos, bool toSubTypes) { + void propagate(StructValuesMap& combinedInfos, + bool toSubTypes, + bool toSuperTypes) { UniqueDeferredQueue 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); + } } } } -- cgit v1.2.3