diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2022-01-20 14:21:30 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-20 14:21:30 -0800 |
commit | 5436efcc7ff729e6a16506185bea171e943028c7 (patch) | |
tree | dbb6f4b8a269173f089b83b4c311708361ac13aa /src | |
parent | 4205846f0f7cc795808d8737fd9a0c2c2e2ab41d (diff) | |
download | binaryen-5436efcc7ff729e6a16506185bea171e943028c7.tar.gz binaryen-5436efcc7ff729e6a16506185bea171e943028c7.tar.bz2 binaryen-5436efcc7ff729e6a16506185bea171e943028c7.zip |
Remove unused `isNominal` field on HeapTypeInfo (#4465)
This field was originally added with the goal of allowing types from multiple
type systems to coexist by determining the type system on a per-type level
rather than globally. This goal was never fully achieved and the `isNominal`
field is not used outside of tests. Now that we are working on implementing the
hybrid isorecursive system, it does not look like having types from multiple
systems coexist will be useful in the near term, so clean up this tech debt.
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-type.h | 19 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 4 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 2 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 51 |
4 files changed, 13 insertions, 63 deletions
diff --git a/src/wasm-type.h b/src/wasm-type.h index c80e7cd0b..7d6306ef7 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -385,22 +385,13 @@ public: Array getArray() const; // If there is a nontrivial (i.e. non-basic) nominal supertype, return it, - // else an empty optional. Nominal types (in the sense of isNominal, - // i.e. Milestone 4 nominal types) may always have supertypes and other types - // may have supertypes in `TypeSystem::Nominal` mode but not in - // `TypeSystem::Equirecursive` mode. + // else an empty optional. std::optional<HeapType> getSuperType() const; // Return the depth of this heap type in the nominal type hierarchy, i.e. the // number of supertypes in its supertype chain. size_t getDepth() const; - // Whether this is a nominal type in the sense of being a GC Milestone 4 - // nominal type. Although all non-basic HeapTypes are nominal in - // `TypeSystem::Nominal` mode, this will still return false unless the type is - // specifically constructed as a Milestone 4 nominal type. - bool isNominal() const; - constexpr TypeID getID() const { return id; } constexpr BasicHeapType getBasic() const { assert(isBasic() && "Basic heap type expected"); @@ -605,10 +596,6 @@ struct TypeBuilder { // `j`. Does nothing for equirecursive types. void setSubType(size_t i, size_t j); - // Make this type nominal in the sense of the Milestone 4 GC spec, independent - // of the current TypeSystem configuration. - void setNominal(size_t i); - // Returns all of the newly constructed heap types. May only be called once // all of the heap types have been initialized with `setHeapType`. In nominal // mode, all of the constructed HeapTypes will be fresh and distinct. In @@ -647,10 +634,6 @@ struct TypeBuilder { builder.setSubType(index, other.index); return *this; } - Entry& setNominal() { - builder.setNominal(index); - return *this; - } }; Entry operator[](size_t i) { return Entry{*this, i}; } diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 36cb0fd1a..b20269f9b 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -224,7 +224,7 @@ void WasmBinaryWriter::writeTypes() { o << U32LEB(indexedTypes.types.size()); for (Index i = 0; i < indexedTypes.types.size(); ++i) { auto type = indexedTypes.types[i]; - bool nominal = type.isNominal() || getTypeSystem() == TypeSystem::Nominal; + bool nominal = getTypeSystem() == TypeSystem::Nominal; BYN_TRACE("write " << type << std::endl); if (type.isSignature()) { o << S32LEB(nominal ? BinaryConsts::EncodedType::FuncExtending @@ -1962,8 +1962,6 @@ void WasmBinaryBuilder::readTypes() { if (form == BinaryConsts::EncodedType::FuncExtending || form == BinaryConsts::EncodedType::StructExtending || form == BinaryConsts::EncodedType::ArrayExtending) { - // TODO: Let the new nominal types coexist with equirecursive types - // builder[i].setNominal(); auto superIndex = getS64LEB(); // TODO: Actually s33 if (superIndex >= 0) { if (size_t(superIndex) >= numTypes) { diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 9a537586e..f76db38af 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -876,8 +876,6 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { } Element* super = nullptr; if (nominal) { - // TODO: Let the new nominal types coexist with equirecursive types - // builder[index].setNominal(); super = def[def.size() - 1]; if (super->dollared()) { // OK diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 738cd6e29..fc42fe230 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -105,8 +105,8 @@ struct HeapTypeInfo { // Otherwise, the type definition tree is still being constructed via the // TypeBuilder interface, so hashing and equality use pointer identity. bool isFinalized = true; - bool isNominal = false; - // In nominal mode, the supertype of this HeapType, if it exists. + // In nominal or isorecursive mode, the supertype of this HeapType, if it + // exists. HeapTypeInfo* supertype = nullptr; enum Kind { BasicKind, @@ -581,7 +581,6 @@ bool TypeInfo::operator==(const TypeInfo& other) const { HeapTypeInfo::HeapTypeInfo(const HeapTypeInfo& other) { kind = other.kind; supertype = other.supertype; - isNominal = other.isNominal; switch (kind) { case BasicKind: new (&basic) auto(other.basic); @@ -690,7 +689,7 @@ private: std::lock_guard<std::recursive_mutex> lock(mutex); // Nominal HeapTypes are always unique, so don't bother deduplicating them. if constexpr (std::is_same_v<Info, HeapTypeInfo>) { - if (info.isNominal || typeSystem == TypeSystem::Nominal) { + if (typeSystem == TypeSystem::Nominal) { return insertNew(); } } @@ -1215,14 +1214,6 @@ size_t HeapType::getDepth() const { return depth; } -bool HeapType::isNominal() const { - if (isBasic()) { - return false; - } else { - return getHeapTypeInfo(*this)->isNominal; - } -} - bool HeapType::isSubType(HeapType left, HeapType right) { // As an optimization, in the common case do not even construct a SubTyper. if (left == right) { @@ -1342,11 +1333,7 @@ bool SubTyper::isSubType(HeapType a, HeapType b) { // Basic HeapTypes are never subtypes of compound HeapTypes. return false; } - // Nominal and structural types are never subtypes of each other. - if (a.isNominal() != b.isNominal()) { - return false; - } - if (a.isNominal() || typeSystem == TypeSystem::Nominal) { + if (typeSystem == TypeSystem::Nominal) { // Subtyping must be declared in a nominal system, not derived from // structure, so we will not recurse. TODO: optimize this search with some // form of caching. @@ -1525,9 +1512,6 @@ HeapType TypeBounder::lub(HeapType a, HeapType b) { if (a.isBasic() || b.isBasic()) { return getBasicLUB(); } - if (a.isNominal() != b.isNominal()) { - return getBasicLUB(); - } HeapTypeInfo* infoA = getHeapTypeInfo(a); HeapTypeInfo* infoB = getHeapTypeInfo(b); @@ -1536,7 +1520,7 @@ HeapType TypeBounder::lub(HeapType a, HeapType b) { return getBasicLUB(); } - if (a.isNominal() || typeSystem == TypeSystem::Nominal) { + if (typeSystem == TypeSystem::Nominal) { // Walk up the subtype tree to find the LUB. Ascend the tree from both `a` // and `b` in lockstep. The first type we see for a second time must be the // LUB because there are no cycles and the only way to encounter a type @@ -1971,15 +1955,13 @@ size_t FiniteShapeHasher::hash(const TypeInfo& info) { } size_t FiniteShapeHasher::hash(const HeapTypeInfo& info) { - size_t digest = wasm::hash(info.isNominal); - if (info.isNominal || getTypeSystem() == TypeSystem::Nominal) { - rehash(digest, uintptr_t(&info)); - return digest; + if (getTypeSystem() == TypeSystem::Nominal) { + return wasm::hash(uintptr_t(&info)); } // If the HeapTypeInfo is not finalized, then it is mutable and its shape // might change in the future. In that case, fall back to pointer identity to // keep the hash consistent until all the TypeBuilder's types are finalized. - digest = wasm::hash(info.isFinalized); + size_t digest = wasm::hash(info.isFinalized); if (!info.isFinalized) { rehash(digest, uintptr_t(&info)); return digest; @@ -2094,9 +2076,7 @@ bool FiniteShapeEquator::eq(const TypeInfo& a, const TypeInfo& b) { } bool FiniteShapeEquator::eq(const HeapTypeInfo& a, const HeapTypeInfo& b) { - if (a.isNominal != b.isNominal) { - return false; - } else if (a.isNominal || getTypeSystem() == TypeSystem::Nominal) { + if (getTypeSystem() == TypeSystem::Nominal) { return &a == &b; } if (a.isFinalized != b.isFinalized) { @@ -2264,7 +2244,6 @@ struct TypeBuilder::Impl { } void set(HeapTypeInfo&& hti) { hti.supertype = info->supertype; - hti.isNominal = info->isNominal; *info = std::move(hti); info->isTemp = true; info->isFinalized = false; @@ -2359,11 +2338,6 @@ void TypeBuilder::setSubType(size_t i, size_t j) { sub->supertype = super; } -void TypeBuilder::setNominal(size_t i) { - assert(i < size() && "index out of bounds"); - impl->entries[i].info->isNominal = true; -} - namespace { // Helper for TypeBuilder::build() that keeps track of temporary types and @@ -3036,9 +3010,7 @@ void globallyCanonicalize(CanonicalizationState& state) { void canonicalizeEquirecursive(CanonicalizationState& state) { // Equirecursive types always have null supertypes. for (auto& info : state.newInfos) { - if (!info->isNominal) { - info->supertype = nullptr; - } + info->supertype = nullptr; } #if TIME_CANONICALIZATION @@ -3219,8 +3191,7 @@ std::vector<HeapType> TypeBuilder::build() { // Note built signature types. See comment in `HeapType::HeapType(Signature)`. for (auto type : state.results) { - if (type.isSignature() && - (type.isNominal() || getTypeSystem() == TypeSystem::Nominal)) { + if (type.isSignature() && (getTypeSystem() == TypeSystem::Nominal)) { nominalSignatureCache.insertType(type); } } |