summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2023-04-19 17:22:28 -0700
committerGitHub <noreply@github.com>2023-04-19 17:22:28 -0700
commit9e5961792a91774962815d58c5c73bfb5612e27c (patch)
tree5f076b905041cc31c0cb58b298f010cbe0a4e226 /src/wasm
parent7cd2396dacf276750a3e27320d6b9d2af6f939d9 (diff)
downloadbinaryen-9e5961792a91774962815d58c5c73bfb5612e27c.tar.gz
binaryen-9e5961792a91774962815d58c5c73bfb5612e27c.tar.bz2
binaryen-9e5961792a91774962815d58c5c73bfb5612e27c.zip
Remove the ability to construct basic types in a TypeBuilder (#5678)
This capability was originally introduced to support calculating LUBs in the equirecursive type system, but has not been needed for anything except tests since the equirecursive type system was removed. Since building basic heap types is no longer useful and was a source of significant complexity, remove the APIs that allowed it and the tests that used those APIs. Also remove test/example/type-builder.cpp, since a significant portion of it tested the removed APIs and the rest is already better tested in test/gtest/type-builder.cpp.
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-type.cpp130
1 files changed, 8 insertions, 122 deletions
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index c9c35ac49..f697ba5a3 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -77,9 +77,8 @@ struct TypeInfo {
bool isNullable() const { return kind == RefKind && ref.nullable; }
// If this TypeInfo represents a Type that can be represented more simply,
- // return that simpler Type. For example, this handles canonicalizing the
- // TypeInfo representing (ref null any) into the BasicType anyref. It also
- // handles eliminating singleton tuple types.
+ // return that simpler Type. For example, this handles eliminating singleton
+ // tuple types.
std::optional<Type> getCanonical() const;
bool operator==(const TypeInfo& other) const;
@@ -105,7 +104,6 @@ struct HeapTypeInfo {
RecGroupInfo* recGroup = nullptr;
size_t recGroupIndex = 0;
enum Kind {
- BasicKind,
SignatureKind,
StructKind,
ArrayKind,
@@ -117,7 +115,6 @@ struct HeapTypeInfo {
Array array;
};
- HeapTypeInfo(HeapType::BasicHeapType basic) : kind(BasicKind), basic(basic) {}
HeapTypeInfo(Signature sig) : kind(SignatureKind), signature(sig) {}
HeapTypeInfo(const Struct& struct_) : kind(StructKind), struct_(struct_) {}
HeapTypeInfo(Struct&& struct_)
@@ -131,11 +128,6 @@ struct HeapTypeInfo {
constexpr bool isArray() const { return kind == ArrayKind; }
constexpr bool isData() const { return isStruct() || isArray(); }
- // If this HeapTypeInfo represents a HeapType that can be represented more
- // simply, return that simpler HeapType. This handles turning BasicKind
- // HeapTypes into their corresponding BasicHeapTypes.
- std::optional<HeapType> getCanonical() const;
-
HeapTypeInfo& operator=(const HeapTypeInfo& other);
bool operator==(const HeapTypeInfo& other) const;
bool operator!=(const HeapTypeInfo& other) const { return !(*this == other); }
@@ -455,27 +447,12 @@ bool isTemp(HeapType type) {
return !type.isBasic() && getHeapTypeInfo(type)->isTemp;
}
-// Given a Type that may or may not be backed by the simplest possible
-// representation, return the equivalent type that is definitely backed by the
-// simplest possible representation.
-Type asCanonical(Type type) {
- if (type.isBasic()) {
- return type;
- } else if (auto canon = getTypeInfo(type)->getCanonical()) {
- return *canon;
- } else {
- return type;
- }
-}
-
HeapType::BasicHeapType getBasicHeapSupertype(HeapType type) {
if (type.isBasic()) {
return type.getBasic();
}
auto* info = getHeapTypeInfo(type);
switch (info->kind) {
- case HeapTypeInfo::BasicKind:
- break;
case HeapTypeInfo::SignatureKind:
return HeapType::func;
case HeapTypeInfo::StructKind:
@@ -597,9 +574,6 @@ HeapTypeInfo::HeapTypeInfo(const HeapTypeInfo& other) {
supertype = other.supertype;
recGroup = other.recGroup;
switch (kind) {
- case BasicKind:
- new (&basic) auto(other.basic);
- return;
case SignatureKind:
new (&signature) auto(other.signature);
return;
@@ -615,8 +589,6 @@ HeapTypeInfo::HeapTypeInfo(const HeapTypeInfo& other) {
HeapTypeInfo::~HeapTypeInfo() {
switch (kind) {
- case BasicKind:
- return;
case SignatureKind:
signature.~Signature();
return;
@@ -630,13 +602,6 @@ HeapTypeInfo::~HeapTypeInfo() {
WASM_UNREACHABLE("unexpected kind");
}
-std::optional<HeapType> HeapTypeInfo::getCanonical() const {
- if (isFinalized && kind == BasicKind) {
- return basic;
- }
- return {};
-}
-
HeapTypeInfo& HeapTypeInfo::operator=(const HeapTypeInfo& other) {
if (&other != this) {
this->~HeapTypeInfo();
@@ -702,9 +667,11 @@ private:
return typename Info::type_t(id);
};
- // Turn e.g. (ref null any) into anyref.
- if (auto canonical = info.getCanonical()) {
- return *canonical;
+ // Turn e.g. singleton tuple into non-tuple.
+ if constexpr (std::is_same_v<Info, TypeInfo>) {
+ if (auto canonical = info.getCanonical()) {
+ return *canonical;
+ }
}
std::lock_guard<std::recursive_mutex> lock(mutex);
// Check whether we already have a type for this structural Info.
@@ -1376,8 +1343,6 @@ HeapType::BasicHeapType HeapType::getBottom() const {
}
auto* info = getHeapTypeInfo(*this);
switch (info->kind) {
- case HeapTypeInfo::BasicKind:
- return HeapType(info->basic).getBottom();
case HeapTypeInfo::SignatureKind:
return nofunc;
case HeapTypeInfo::StructKind:
@@ -1861,10 +1826,7 @@ std::ostream& TypePrinter::print(HeapType type) {
#if TRACE_CANONICALIZATION
os << "(;" << ((type.getID() >> 4) % 1000) << ";)";
#endif
- if (getHeapTypeInfo(type)->kind == HeapTypeInfo::BasicKind) {
- os << "(; noncanonical ;) ";
- print(getHeapTypeInfo(type)->basic);
- } else if (type.isSignature()) {
+ if (type.isSignature()) {
print(type.getSignature(), type.getSuperType());
} else if (type.isStruct()) {
print(type.getStruct(), type.getSuperType());
@@ -2045,8 +2007,6 @@ size_t RecGroupHasher::hash(const HeapTypeInfo& info) const {
}
wasm::rehash(digest, info.kind);
switch (info.kind) {
- case HeapTypeInfo::BasicKind:
- WASM_UNREACHABLE("Basic HeapTypeInfo should have been canonicalized");
case HeapTypeInfo::SignatureKind:
hash_combine(digest, hash(info.signature));
return digest;
@@ -2171,8 +2131,6 @@ bool RecGroupEquator::eq(const HeapTypeInfo& a, const HeapTypeInfo& b) const {
return false;
}
switch (a.kind) {
- case HeapTypeInfo::BasicKind:
- WASM_UNREACHABLE("Basic HeapTypeInfo should have been canonicalized");
case HeapTypeInfo::SignatureKind:
return eq(a.signature, b.signature);
case HeapTypeInfo::StructKind:
@@ -2282,8 +2240,6 @@ void TypeGraphWalkerBase<Self>::scanHeapType(HeapType* ht) {
}
auto* info = getHeapTypeInfo(*ht);
switch (info->kind) {
- case HeapTypeInfo::BasicKind:
- break;
case HeapTypeInfo::SignatureKind:
taskList.push_back(Task::scan(&info->signature.results));
taskList.push_back(Task::scan(&info->signature.params));
@@ -2355,11 +2311,6 @@ void TypeBuilder::grow(size_t n) {
size_t TypeBuilder::size() { return impl->entries.size(); }
-void TypeBuilder::setHeapType(size_t i, HeapType::BasicHeapType basic) {
- assert(i < size() && "Index out of bounds");
- impl->entries[i].set(basic);
-}
-
void TypeBuilder::setHeapType(size_t i, Signature signature) {
assert(i < size() && "index out of bounds");
impl->entries[i].set(signature);
@@ -2380,16 +2331,6 @@ void TypeBuilder::setHeapType(size_t i, Array array) {
impl->entries[i].set(array);
}
-bool TypeBuilder::isBasic(size_t i) {
- assert(i < size() && "index out of bounds");
- return impl->entries[i].info->kind == HeapTypeInfo::BasicKind;
-}
-
-HeapType::BasicHeapType TypeBuilder::getBasic(size_t i) {
- assert(isBasic(i));
- return impl->entries[i].info->basic;
-}
-
HeapType TypeBuilder::getTempHeapType(size_t i) {
assert(i < size() && "index out of bounds");
return impl->entries[i].get();
@@ -2469,8 +2410,6 @@ struct CanonicalizationState {
// Updates the HeapType use sites within `info`.
void updateUses(ReplacementMap& replacements,
std::unique_ptr<HeapTypeInfo>& info);
- // Updates lists and uses.
- void update(ReplacementMap& replacements);
#if TRACE_CANONICALIZATION
void dump() {
@@ -2488,16 +2427,6 @@ struct CanonicalizationState {
#endif // TRACE_CANONICALIZATION
};
-void CanonicalizationState::update(ReplacementMap& replacements) {
- if (replacements.empty()) {
- return;
- }
- updateShallow(replacements);
- for (auto& info : newInfos) {
- updateUses(replacements, info);
- }
-}
-
void CanonicalizationState::updateShallow(ReplacementMap& replacements) {
if (replacements.empty()) {
return;
@@ -2670,8 +2599,6 @@ validateSubtyping(const std::vector<HeapType>& types) {
}
SubTyper typer;
switch (sub->kind) {
- case HeapTypeInfo::BasicKind:
- WASM_UNREACHABLE("unexpected kind");
case HeapTypeInfo::SignatureKind:
if (!typer.isSubType(sub->signature, super->signature)) {
return fail();
@@ -2803,43 +2730,6 @@ std::optional<TypeBuilder::Error> canonicalizeIsorecursive(
return {};
}
-void canonicalizeBasicTypes(CanonicalizationState& state) {
- // Replace heap types backed by BasicKind HeapTypeInfos with their
- // corresponding BasicHeapTypes. The heap types backed by BasicKind
- // HeapTypeInfos exist only to support building basic types in a TypeBuilder
- // and are never canonical.
- CanonicalizationState::ReplacementMap replacements;
- for (auto& info : state.newInfos) {
- if (info->kind == HeapTypeInfo::BasicKind) {
- replacements.insert({asHeapType(info), HeapType(info->basic)});
- }
- // Basic supertypes should be implicit.
- if (info->supertype && info->supertype->kind == HeapTypeInfo::BasicKind) {
- info->supertype = nullptr;
- }
- }
- state.update(replacements);
-
- if (replacements.size()) {
- // Canonicalizing basic heap types may cause their parent types to become
- // canonicalizable as well, for example after creating `(ref null any)` we
- // can futher canonicalize to `anyref`.
- struct TypeCanonicalizer : TypeGraphWalkerBase<TypeCanonicalizer> {
- void scanType(Type* type) {
- if (type->isTuple()) {
- TypeGraphWalkerBase<TypeCanonicalizer>::scanType(type);
- } else {
- *type = asCanonical(*type);
- }
- }
- };
- for (auto& info : state.newInfos) {
- auto root = asHeapType(info);
- TypeCanonicalizer{}.walkRoot(&root);
- }
- }
-}
-
} // anonymous namespace
TypeBuilder::BuildResult TypeBuilder::build() {
@@ -2859,10 +2749,6 @@ TypeBuilder::BuildResult TypeBuilder::build() {
state.newInfos.emplace_back(std::move(info));
}
- // Eagerly replace references to built basic heap types so the more
- // complicated canonicalization algorithms don't need to consider them.
- canonicalizeBasicTypes(state);
-
#if TRACE_CANONICALIZATION
std::cerr << "After replacing basic heap types:\n";
state.dump();