From d2bc904c0ece35fe7e537ec42cc1e9cc94815681 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 12 Dec 2025 16:56:34 -0800 Subject: [PATCH] [NFC] Make fields of BrandTypeIterator constexpr Make enough constructors of Type and Field constexpr that we can make the fieldOptions array in BrandTypeIterator constexpr as well. This lets us remove logic for initializing this array at runtime. --- src/passes/MinimizeRecGroups.cpp | 60 +++++++++++--------------------- src/wasm-type.h | 13 ++++--- 2 files changed, 28 insertions(+), 45 deletions(-) diff --git a/src/passes/MinimizeRecGroups.cpp b/src/passes/MinimizeRecGroups.cpp index c10f517db42..13f569e464a 100644 --- a/src/passes/MinimizeRecGroups.cpp +++ b/src/passes/MinimizeRecGroups.cpp @@ -107,10 +107,27 @@ struct TypeSCCs // provides an infinite sequence of possible brand types, prioritizing those // with the most compact encoding. struct BrandTypeIterator { - // See `initFieldOptions` for the 18 options. static constexpr Index optionCount = 18; - static std::array fieldOptions; - static void initFieldOptions(); + static constexpr std::array fieldOptions = {{ + Field(Field::i8, Mutable), + Field(Field::i16, Mutable), + Field(Type::i32, Mutable), + Field(Type::i64, Mutable), + Field(Type::f32, Mutable), + Field(Type::f64, Mutable), + Field(Type(HeapType::any, Nullable), Mutable), + Field(Type(HeapType::func, Nullable), Mutable), + Field(Type(HeapType::ext, Nullable), Mutable), + Field(Type(HeapType::none, Nullable), Mutable), + Field(Type(HeapType::nofunc, Nullable), Mutable), + Field(Type(HeapType::noext, Nullable), Mutable), + Field(Type(HeapType::any, NonNullable), Mutable), + Field(Type(HeapType::func, NonNullable), Mutable), + Field(Type(HeapType::ext, NonNullable), Mutable), + Field(Type(HeapType::none, NonNullable), Mutable), + Field(Type(HeapType::nofunc, NonNullable), Mutable), + Field(Type(HeapType::noext, NonNullable), Mutable), + }}; struct FieldInfo { uint8_t index = 0; @@ -316,32 +333,6 @@ void GroupClassInfo::permute(RecGroupInfo& info) { } } -std::array - BrandTypeIterator::fieldOptions = {{}}; - -void BrandTypeIterator::initFieldOptions() { - BrandTypeIterator::fieldOptions = {{ - Field(Field::i8, Mutable), - Field(Field::i16, Mutable), - Field(Type::i32, Mutable), - Field(Type::i64, Mutable), - Field(Type::f32, Mutable), - Field(Type::f64, Mutable), - Field(Type(HeapType::any, Nullable), Mutable), - Field(Type(HeapType::func, Nullable), Mutable), - Field(Type(HeapType::ext, Nullable), Mutable), - Field(Type(HeapType::none, Nullable), Mutable), - Field(Type(HeapType::nofunc, Nullable), Mutable), - Field(Type(HeapType::noext, Nullable), Mutable), - Field(Type(HeapType::any, NonNullable), Mutable), - Field(Type(HeapType::func, NonNullable), Mutable), - Field(Type(HeapType::ext, NonNullable), Mutable), - Field(Type(HeapType::none, NonNullable), Mutable), - Field(Type(HeapType::nofunc, NonNullable), Mutable), - Field(Type(HeapType::noext, NonNullable), Mutable), - }}; -} - struct MinimizeRecGroups : Pass { // The types we are optimizing and their indices in this list. std::vector types; @@ -387,8 +378,6 @@ struct MinimizeRecGroups : Pass { return; } - initBrandOptions(); - auto typeInfo = ModuleUtils::collectHeapTypeInfo( *module, ModuleUtils::TypeInclusion::AllTypes, @@ -445,15 +434,6 @@ struct MinimizeRecGroups : Pass { rewriteTypes(*module); } - void initBrandOptions() { - // Initialize the field options for brand types lazily here to avoid - // depending on global constructor ordering. - [[maybe_unused]] static bool fieldsInitialized = []() { - BrandTypeIterator::initFieldOptions(); - return true; - }(); - } - void updateShapes() { while (!shapesToUpdate.empty()) { auto index = shapesToUpdate.back(); diff --git a/src/wasm-type.h b/src/wasm-type.h index d6dc254734a..98aacb074b2 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -324,7 +324,7 @@ class Type { constexpr Type(BasicType id) : id(id) {} // But converting raw TypeID is more dangerous, so make it explicit - explicit Type(TypeID id) : id(id) {} + explicit constexpr Type(TypeID id) : id(id) {} // Construct tuple from a list of single types Type(std::initializer_list); @@ -335,7 +335,9 @@ class Type { // Construct from a heap type description. Also covers construction from // Signature, Struct or Array via implicit conversion to HeapType. - Type(HeapType heapType, Nullability nullable, Exactness exact = Inexact) + constexpr Type(HeapType heapType, + Nullability nullable, + Exactness exact = Inexact) : Type(heapType.getID() | (nullable == Nullable ? NullMask : 0) | (exact == Exact ? ExactMask : 0)) { assert(!(heapType.getID() & @@ -659,10 +661,11 @@ struct Field { Mutability mutable_; // Arbitrary defaults for convenience. - Field() : type(Type::i32), packedType(not_packed), mutable_(Mutable) {} - Field(Type type, Mutability mutable_) + constexpr Field() + : type(Type::i32), packedType(not_packed), mutable_(Mutable) {} + constexpr Field(Type type, Mutability mutable_) : type(type), packedType(not_packed), mutable_(mutable_) {} - Field(PackedType packedType, Mutability mutable_) + constexpr Field(PackedType packedType, Mutability mutable_) : type(Type::i32), packedType(packedType), mutable_(mutable_) {} constexpr bool isPacked() const {