diff options
-rw-r--r-- | src/ir/subtypes.h | 36 | ||||
-rw-r--r-- | src/ir/type-updating.cpp | 170 | ||||
-rw-r--r-- | src/passes/GlobalTypeOptimization.cpp | 4 | ||||
-rw-r--r-- | src/passes/TypeMerging.cpp | 33 | ||||
-rw-r--r-- | src/tools/wasm-ctor-eval.cpp | 36 | ||||
-rw-r--r-- | src/wasm-type-ordering.h | 66 | ||||
-rw-r--r-- | test/ctor-eval/gc-2.wast.out | 10 | ||||
-rw-r--r-- | test/lit/ctor-eval/gc-cycle-multi.wast | 27 | ||||
-rw-r--r-- | test/lit/ctor-eval/gc-cycle.wast | 252 | ||||
-rw-r--r-- | test/lit/passes/gto-mutability.wast | 8 | ||||
-rw-r--r-- | test/lit/passes/signature-pruning.wast | 6 | ||||
-rw-r--r-- | test/lit/passes/signature-refining.wast | 8 | ||||
-rw-r--r-- | test/lit/passes/type-merging.wast | 64 | ||||
-rw-r--r-- | test/lit/passes/type-ssa_and_merging.wast | 10 |
14 files changed, 311 insertions, 419 deletions
diff --git a/src/ir/subtypes.h b/src/ir/subtypes.h index 47ee51ac3..c69250043 100644 --- a/src/ir/subtypes.h +++ b/src/ir/subtypes.h @@ -18,7 +18,7 @@ #define wasm_ir_subtypes_h #include "ir/module-utils.h" -#include "support/old_topological_sort.h" +#include "support/topological_sort.h" #include "wasm.h" namespace wasm { @@ -79,29 +79,19 @@ struct SubTypes { } // A topological sort that visits subtypes first. - auto getSubTypesFirstSort() const { - struct SubTypesFirstSort : OldTopologicalSort<HeapType, SubTypesFirstSort> { - const SubTypes& parent; - - SubTypesFirstSort(const SubTypes& parent) : parent(parent) { - for (auto type : parent.types) { - // The roots are types with no supertype. - if (!type.getDeclaredSuperType()) { - push(type); - } - } - } - - void pushPredecessors(HeapType type) { - // Things we need to process before each type are its subtypes. Once we - // know their depth, we can easily compute our own. - for (auto pred : parent.getImmediateSubTypes(type)) { - push(pred); - } + std::vector<HeapType> getSubTypesFirstSort() const { + std::vector<std::pair<HeapType, std::vector<HeapType>>> graph; + graph.reserve(types.size()); + for (auto type : types) { + if (auto it = typeSubTypes.find(type); it != typeSubTypes.end()) { + graph.emplace_back(*it); + } else { + graph.emplace_back(type, std::vector<HeapType>{}); } - }; - - return SubTypesFirstSort(*this); + } + auto sorted = TopologicalSort::sortOf(graph.begin(), graph.end()); + std::reverse(sorted.begin(), sorted.end()); + return sorted; } // Computes the depth of children for each type. This is 0 if the type has no diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index 467971989..dedbb6316 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -40,118 +40,72 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes( // world scenario, don't modify public types because we assume that they may // be reflected on or used for linking. Figure out where each private type // will be located in the builder. - // - // There are two code paths here: a new one that is used when there are type - // indices to preserve and an old one that is used otherwise. The old code - // path is kept around to avoid unnecessary changes to test outputs while we - // incrementally add --preserve-type-order to tests that could benefit from - // it. Once we are done adding --preserve-type-order to tests, we should - // remove the old code path here since the new code path is strictly better. - if (wasm.typeIndices.size()) { - // New code path, currently used only with --preserve-type-order. - auto typeInfo = ModuleUtils::collectHeapTypeInfo( - wasm, - ModuleUtils::TypeInclusion::UsedIRTypes, - ModuleUtils::VisibilityHandling::FindVisibility); - - std::unordered_set<HeapType> additionalSet(additionalPrivateTypes.begin(), - additionalPrivateTypes.end()); - - std::vector<std::pair<HeapType, SmallVector<HeapType, 1>>> - privateSupertypes; - privateSupertypes.reserve(typeInfo.size()); - for (auto& [type, info] : typeInfo) { - if (info.visibility != ModuleUtils::Visibility::Private && - !additionalSet.count(type)) { - continue; - } - privateSupertypes.push_back({type, {}}); - - if (auto super = getDeclaredSuperType(type)) { - auto it = typeInfo.find(*super); - // Record the supertype only if it is among the private types. - if ((it != typeInfo.end() && - it->second.visibility == ModuleUtils::Visibility::Private) || - additionalSet.count(*super)) { - privateSupertypes.back().second.push_back(*super); - } - } - } - - // Topological sort to have subtypes first. This is the opposite of the - // order we need, so the comparison is the opposite of what we ultimately - // want. - std::vector<HeapType> sorted; - if (wasm.typeIndices.empty()) { - sorted = TopologicalSort::sortOf(privateSupertypes.begin(), - privateSupertypes.end()); - } else { - sorted = - TopologicalSort::minSortOf(privateSupertypes.begin(), - privateSupertypes.end(), - [&](Index a, Index b) { - auto typeA = privateSupertypes[a].first; - auto typeB = privateSupertypes[b].first; - // Preserve type order. - auto itA = wasm.typeIndices.find(typeA); - auto itB = wasm.typeIndices.find(typeB); - bool hasA = itA != wasm.typeIndices.end(); - bool hasB = itB != wasm.typeIndices.end(); - if (hasA != hasB) { - // Types with preserved indices must be - // sorted before (after in this reversed - // comparison) types without indices to - // maintain transitivity. - return !hasA; - } - if (hasA && *itA != *itB) { - return !(itA->second < itB->second); - } - // Break ties by the arbitrary order we - // have collected the types in. - return a > b; - }); - } - std::reverse(sorted.begin(), sorted.end()); - Index i = 0; - for (auto type : sorted) { - typeIndices[type] = i++; + auto typeInfo = ModuleUtils::collectHeapTypeInfo( + wasm, + ModuleUtils::TypeInclusion::UsedIRTypes, + ModuleUtils::VisibilityHandling::FindVisibility); + + std::unordered_set<HeapType> additionalSet(additionalPrivateTypes.begin(), + additionalPrivateTypes.end()); + + std::vector<std::pair<HeapType, SmallVector<HeapType, 1>>> privateSupertypes; + privateSupertypes.reserve(typeInfo.size()); + for (auto& [type, info] : typeInfo) { + if (info.visibility != ModuleUtils::Visibility::Private && + !additionalSet.count(type)) { + continue; } - } else { - // Old code path. - - auto privateTypes = ModuleUtils::getPrivateHeapTypes(wasm); - - if (!additionalPrivateTypes.empty()) { - // Only add additional private types that are not already in the list. - std::unordered_set<HeapType> privateTypesSet(privateTypes.begin(), - privateTypes.end()); + privateSupertypes.push_back({type, {}}); - for (auto t : additionalPrivateTypes) { - if (!privateTypesSet.count(t)) { - privateTypes.push_back(t); - privateTypesSet.insert(t); - } + if (auto super = getDeclaredSuperType(type)) { + auto it = typeInfo.find(*super); + // Record the supertype only if it is among the private types. + if ((it != typeInfo.end() && + it->second.visibility == ModuleUtils::Visibility::Private) || + additionalSet.count(*super)) { + privateSupertypes.back().second.push_back(*super); } } + } - // Topological sort to have supertypes first, but we have to account for the - // fact that we may be replacing the supertypes to get the order correct. - struct SupertypesFirst - : HeapTypeOrdering::SupertypesFirstBase<SupertypesFirst> { - GlobalTypeRewriter& parent; - - SupertypesFirst(GlobalTypeRewriter& parent) : parent(parent) {} - std::optional<HeapType> getDeclaredSuperType(HeapType type) { - return parent.getDeclaredSuperType(type); - } - }; - - SupertypesFirst sortedTypes(*this); - Index i = 0; - for (auto type : sortedTypes.sort(privateTypes)) { - typeIndices[type] = i++; - } + // Topological sort to have subtypes first. This is the opposite of the + // order we need, so the comparison is the opposite of what we ultimately + // want. + std::vector<HeapType> sorted; + if (wasm.typeIndices.empty()) { + sorted = TopologicalSort::sortOf(privateSupertypes.begin(), + privateSupertypes.end()); + } else { + sorted = + TopologicalSort::minSortOf(privateSupertypes.begin(), + privateSupertypes.end(), + [&](Index a, Index b) { + auto typeA = privateSupertypes[a].first; + auto typeB = privateSupertypes[b].first; + // Preserve type order. + auto itA = wasm.typeIndices.find(typeA); + auto itB = wasm.typeIndices.find(typeB); + bool hasA = itA != wasm.typeIndices.end(); + bool hasB = itB != wasm.typeIndices.end(); + if (hasA != hasB) { + // Types with preserved indices must be + // sorted before (after in this reversed + // comparison) types without indices to + // maintain transitivity. + return !hasA; + } + if (hasA && *itA != *itB) { + return !(itA->second < itB->second); + } + // Break ties by the arbitrary order we + // have collected the types in. + return a > b; + }); + } + std::reverse(sorted.begin(), sorted.end()); + Index i = 0; + for (auto type : sorted) { + typeIndices[type] = i++; } if (typeIndices.size() == 0) { @@ -168,7 +122,7 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes( typeBuilder.createRecGroup(0, typeBuilder.size()); // Create the temporary heap types. - Index i = 0; + i = 0; auto map = [&](HeapType type) -> HeapType { if (auto it = typeIndices.find(type); it != typeIndices.end()) { return typeBuilder[it->second]; diff --git a/src/passes/GlobalTypeOptimization.cpp b/src/passes/GlobalTypeOptimization.cpp index eec8e206d..dac6fd7b6 100644 --- a/src/passes/GlobalTypeOptimization.cpp +++ b/src/passes/GlobalTypeOptimization.cpp @@ -171,8 +171,8 @@ struct GlobalTypeOptimization : public Pass { // fields in a supertype is a constraint on what subtypes can do. That is, // we decide for each supertype what the optimal order is, and consider that // fixed, and then subtypes can decide how to sort fields that they append. - HeapTypeOrdering::SupertypesFirst sorted; - for (auto type : sorted.sort(propagator.subTypes.types)) { + for (auto type : + HeapTypeOrdering::supertypesFirst(propagator.subTypes.types)) { if (!type.isStruct()) { continue; } diff --git a/src/passes/TypeMerging.cpp b/src/passes/TypeMerging.cpp index 1cac7732f..206addd2f 100644 --- a/src/passes/TypeMerging.cpp +++ b/src/passes/TypeMerging.cpp @@ -142,6 +142,17 @@ struct TypeMerging : public Pass { return type; } + std::vector<HeapType> + mergeableSupertypesFirst(const std::vector<HeapType>& types) { + return HeapTypeOrdering::supertypesFirst( + types, [&](HeapType type) -> std::optional<HeapType> { + if (auto super = type.getDeclaredSuperType()) { + return getMerged(*super); + } + return std::nullopt; + }); + } + void run(Module* module_) override; // We will do two different kinds of merging: First, we will merge types into @@ -163,20 +174,6 @@ struct TypeMerging : public Pass { void applyMerges(); }; -struct MergeableSupertypesFirst - : HeapTypeOrdering::SupertypesFirstBase<MergeableSupertypesFirst> { - TypeMerging& merging; - - MergeableSupertypesFirst(TypeMerging& merging) : merging(merging) {} - - std::optional<HeapType> getDeclaredSuperType(HeapType type) { - if (auto super = type.getDeclaredSuperType()) { - return merging.getMerged(*super); - } - return std::nullopt; - } -}; - // Hash and equality-compare HeapTypes based on their top-level structure (i.e. // "shape"), ignoring nontrivial heap type children that will not be // differentiated between until we run the DFA partition refinement. @@ -305,8 +302,7 @@ bool TypeMerging::merge(MergeKind kind) { // For each type, either create a new partition or add to its supertype's // partition. - MergeableSupertypesFirst sortedTypes(*this); - for (auto type : sortedTypes.sort(mergeable)) { + for (auto type : mergeableSupertypesFirst(mergeable)) { // We need partitions for any public children of this type since those // children will participate in the DFA we're creating. for (auto child : getPublicChildren(type)) { @@ -414,7 +410,7 @@ bool TypeMerging::merge(MergeKind kind) { std::vector<HeapType> newMergeable; bool merged = false; for (const auto& partition : refinedPartitions) { - auto target = *MergeableSupertypesFirst(*this).sort(partition).begin(); + auto target = mergeableSupertypesFirst(partition).front(); newMergeable.push_back(target); for (auto type : partition) { if (type != target) { @@ -452,8 +448,7 @@ TypeMerging::splitSupertypePartition(const std::vector<HeapType>& types) { std::unordered_set<HeapType> includedTypes(types.begin(), types.end()); std::vector<std::vector<HeapType>> partitions; std::unordered_map<HeapType, Index> partitionIndices; - MergeableSupertypesFirst sortedTypes(*this); - for (auto type : sortedTypes.sort(types)) { + for (auto type : mergeableSupertypesFirst(types)) { auto super = type.getDeclaredSuperType(); if (super && includedTypes.count(*super)) { // We must already have a partition for the supertype we can add to. diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index d74790b2a..464654d4f 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -36,9 +36,9 @@ #include "support/colors.h" #include "support/file.h" #include "support/insert_ordered.h" -#include "support/old_topological_sort.h" #include "support/small_set.h" #include "support/string.h" +#include "support/topological_sort.h" #include "tool-options.h" #include "wasm-builder.h" #include "wasm-interpreter.h" @@ -609,9 +609,9 @@ private: Builder builder(*wasm); // First, find what constraints we have on the ordering of the globals. We - // will build up a map of each global to the globals it must be after. - using MustBeAfter = InsertOrderedMap<Name, InsertOrderedSet<Name>>; - MustBeAfter mustBeAfter; + // will build up a map of each global to the globals it must be before. + using MustBeBefore = InsertOrderedMap<Name, InsertOrderedSet<Name>>; + MustBeBefore mustBeBefore; for (auto& global : wasm->globals) { if (!global->init) { @@ -672,31 +672,12 @@ private: // Any global.gets that cannot be fixed up are constraints. for (auto* get : scanner.unfixableGets) { - mustBeAfter[global->name].insert(get->name); + mustBeBefore[global->name]; + mustBeBefore[get->name].insert(global->name); } } - if (!mustBeAfter.empty()) { - // We found constraints that require reordering, so do so. - struct MustBeAfterSort : OldTopologicalSort<Name, MustBeAfterSort> { - MustBeAfter& mustBeAfter; - - MustBeAfterSort(MustBeAfter& mustBeAfter) : mustBeAfter(mustBeAfter) { - for (auto& [global, _] : mustBeAfter) { - push(global); - } - } - - void pushPredecessors(Name global) { - auto iter = mustBeAfter.find(global); - if (iter != mustBeAfter.end()) { - for (auto other : iter->second) { - push(other); - } - } - } - }; - + if (!mustBeBefore.empty()) { auto oldGlobals = std::move(wasm->globals); // After clearing the globals vector, clear the map as well. wasm->updateMaps(); @@ -706,7 +687,8 @@ private: globalIndexes[oldGlobals[i]->name] = i; } // Add the globals that had an important ordering, in the right order. - for (auto global : MustBeAfterSort(mustBeAfter)) { + for (auto global : + TopologicalSort::sortOf(mustBeBefore.begin(), mustBeBefore.end())) { wasm->addGlobal(std::move(oldGlobals[globalIndexes[global]])); } // Add all other globals after them. diff --git a/src/wasm-type-ordering.h b/src/wasm-type-ordering.h index 9ccf4c568..0f23b4953 100644 --- a/src/wasm-type-ordering.h +++ b/src/wasm-type-ordering.h @@ -20,58 +20,34 @@ #include <unordered_set> #include "support/insert_ordered.h" -#include "support/old_topological_sort.h" +#include "support/topological_sort.h" #include "wasm-type.h" namespace wasm::HeapTypeOrdering { -// Given a collection of types, iterate through it such that each type in the -// collection is visited only after its immediate supertype in the collection is -// visited. -template<typename SupertypeProvider> -struct SupertypesFirstBase - : OldTopologicalSort<HeapType, SupertypesFirstBase<SupertypeProvider>> { - // For each type in the input collection, whether it is a supertype. Used to - // track membership in the input collection. - InsertOrderedMap<HeapType, bool> typeSet; - - SupertypeProvider& self() { return *static_cast<SupertypeProvider*>(this); } - - template<typename T> SupertypeProvider& sort(const T& types) { - for (auto type : types) { - typeSet[type] = false; - } - // Find the supertypes that are in the collection. - for (auto [type, _] : typeSet) { - if (auto super = self().getDeclaredSuperType(type)) { - if (auto it = typeSet.find(*super); it != typeSet.end()) { - it->second = true; - } - } - } - // Types that are not supertypes of others are the roots. - for (auto [type, isSuper] : typeSet) { - if (!isSuper) { - this->push(type); - } - } - return self(); +// Given a collection of types, return a sequence of the types such that each +// type in the sequence comes only after its immediate supertype in the +// collection is visited. +template<typename T> +std::vector<HeapType> supertypesFirst( + const T& types, + std::function<std::optional<HeapType>(HeapType)> getSuper = + [](HeapType type) { return type.getDeclaredSuperType(); }) { + + InsertOrderedMap<HeapType, std::vector<HeapType>> subtypes; + for (auto type : types) { + subtypes.insert({type, {}}); } - - void pushPredecessors(HeapType type) { - // Do not visit types that weren't in the input collection. - if (auto super = self().getDeclaredSuperType(type); - super && typeSet.count(*super)) { - this->push(*super); + // Find the supertypes that are in the collection. + for (auto [type, _] : subtypes) { + if (auto super = getSuper(type)) { + if (auto it = subtypes.find(*super); it != subtypes.end()) { + it->second.push_back(type); + } } } -}; - -struct SupertypesFirst : SupertypesFirstBase<SupertypesFirst> { - std::optional<HeapType> getDeclaredSuperType(HeapType type) { - return type.getDeclaredSuperType(); - } -}; + return TopologicalSort::sortOf(subtypes.begin(), subtypes.end()); +} } // namespace wasm::HeapTypeOrdering diff --git a/test/ctor-eval/gc-2.wast.out b/test/ctor-eval/gc-2.wast.out index 4d80f764e..ebac37653 100644 --- a/test/ctor-eval/gc-2.wast.out +++ b/test/ctor-eval/gc-2.wast.out @@ -1,15 +1,15 @@ (module (type $struct (sub (struct (field i32)))) (type $1 (func (result i32))) - (global $ctor-eval$global_4 (ref $struct) (struct.new $struct - (i32.const 9999) - )) - (global $global3 (ref $struct) (global.get $ctor-eval$global_4)) - (global $global2 (mut (ref null $struct)) (global.get $ctor-eval$global_4)) (global $ctor-eval$global (ref $struct) (struct.new $struct (i32.const 1337) )) + (global $ctor-eval$global_4 (ref $struct) (struct.new $struct + (i32.const 9999) + )) (global $global1 (ref any) (global.get $ctor-eval$global)) + (global $global2 (mut (ref null $struct)) (global.get $ctor-eval$global_4)) + (global $global3 (ref $struct) (global.get $ctor-eval$global_4)) (export "keepalive" (func $keepalive)) (func $keepalive (type $1) (result i32) (select diff --git a/test/lit/ctor-eval/gc-cycle-multi.wast b/test/lit/ctor-eval/gc-cycle-multi.wast index 705b76f2f..070291432 100644 --- a/test/lit/ctor-eval/gc-cycle-multi.wast +++ b/test/lit/ctor-eval/gc-cycle-multi.wast @@ -13,27 +13,26 @@ ;; CHECK: (type $2 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_8 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_6 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: )) - ;; CHECK: (global $c (mut (ref null $A)) (global.get $ctor-eval$global_8)) - ;; CHECK: (global $ctor-eval$global_7 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (i32.const 20) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_7)) - (global $a (mut (ref null $A)) (ref.null $A)) - ;; CHECK: (global $ctor-eval$global_6 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_8 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (i32.const 30) ;; CHECK-NEXT: )) - ;; CHECK: (global $b (mut (ref null $A)) (global.get $ctor-eval$global_6)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_6)) + (global $a (mut (ref null $A)) (ref.null $A)) + ;; CHECK: (global $b (mut (ref null $A)) (global.get $ctor-eval$global_7)) (global $b (mut (ref null $A)) (ref.null $A)) + ;; CHECK: (global $c (mut (ref null $A)) (global.get $ctor-eval$global_8)) (global $c (mut (ref null $A)) (ref.null $A)) (func $makeCycle (param $i i32) (result (ref $A)) @@ -118,16 +117,16 @@ ) ;; CHECK: (func $start (type $1) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_8) -;; CHECK-NEXT: (global.get $ctor-eval$global_8) +;; CHECK-NEXT: (global.get $ctor-eval$global_6) +;; CHECK-NEXT: (global.get $ctor-eval$global_6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (struct.set $A 0 ;; CHECK-NEXT: (global.get $ctor-eval$global_7) ;; CHECK-NEXT: (global.get $ctor-eval$global_7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_6) -;; CHECK-NEXT: (global.get $ctor-eval$global_6) +;; CHECK-NEXT: (global.get $ctor-eval$global_8) +;; CHECK-NEXT: (global.get $ctor-eval$global_8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/ctor-eval/gc-cycle.wast b/test/lit/ctor-eval/gc-cycle.wast index 36333a8bd..a342ba3c9 100644 --- a/test/lit/ctor-eval/gc-cycle.wast +++ b/test/lit/ctor-eval/gc-cycle.wast @@ -151,20 +151,20 @@ ;; CHECK: (type $2 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_8 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_7 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_8)) - (global $a (mut (ref null $A)) (ref.null $A)) - - ;; CHECK: (global $ctor-eval$global_7 (ref $A) (struct.new $A - ;; CHECK-NEXT: (global.get $ctor-eval$global_8) + ;; CHECK: (global $ctor-eval$global_8 (ref $A) (struct.new $A + ;; CHECK-NEXT: (global.get $ctor-eval$global_7) ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: )) - ;; CHECK: (global $b (mut (ref null $A)) (global.get $ctor-eval$global_7)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_7)) + (global $a (mut (ref null $A)) (ref.null $A)) + + ;; CHECK: (global $b (mut (ref null $A)) (global.get $ctor-eval$global_8)) (global $b (mut (ref null $A)) (ref.null $A)) (func $test (export "test") @@ -223,8 +223,8 @@ ;; CHECK: (func $start (type $1) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_8) ;; CHECK-NEXT: (global.get $ctor-eval$global_7) +;; CHECK-NEXT: (global.get $ctor-eval$global_8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -250,20 +250,20 @@ ;; CHECK: (type $3 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_8 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_7 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_8)) - (global $a (mut (ref null $A)) (ref.null $A)) - - ;; CHECK: (global $ctor-eval$global_7 (ref $B) (struct.new $B - ;; CHECK-NEXT: (global.get $ctor-eval$global_8) + ;; CHECK: (global $ctor-eval$global_8 (ref $B) (struct.new $B + ;; CHECK-NEXT: (global.get $ctor-eval$global_7) ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: )) - ;; CHECK: (global $b (mut (ref null $B)) (global.get $ctor-eval$global_7)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_7)) + (global $a (mut (ref null $A)) (ref.null $A)) + + ;; CHECK: (global $b (mut (ref null $B)) (global.get $ctor-eval$global_8)) (global $b (mut (ref null $B)) (ref.null $B)) (func $test (export "test") @@ -321,8 +321,8 @@ ;; CHECK: (func $start (type $2) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_8) ;; CHECK-NEXT: (global.get $ctor-eval$global_7) +;; CHECK-NEXT: (global.get $ctor-eval$global_8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -348,19 +348,19 @@ ;; CHECK: (type $3 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_8 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_7 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_8)) - - ;; CHECK: (global $ctor-eval$global_7 (ref $B) (struct.new $B - ;; CHECK-NEXT: (global.get $ctor-eval$global_8) + ;; CHECK: (global $ctor-eval$global_8 (ref $B) (struct.new $B + ;; CHECK-NEXT: (global.get $ctor-eval$global_7) ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: )) - ;; CHECK: (global $b (mut (ref null $B)) (global.get $ctor-eval$global_7)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_7)) + + ;; CHECK: (global $b (mut (ref null $B)) (global.get $ctor-eval$global_8)) (global $b (mut (ref null $B)) (ref.null $B)) (global $a (mut (ref null $A)) (ref.null $A)) @@ -420,8 +420,8 @@ ;; CHECK: (func $start (type $2) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_8) ;; CHECK-NEXT: (global.get $ctor-eval$global_7) +;; CHECK-NEXT: (global.get $ctor-eval$global_8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -446,12 +446,17 @@ ;; CHECK: (type $3 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_8 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_7 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_8)) + ;; CHECK: (global $ctor-eval$global_8 (ref $B) (struct.new $B + ;; CHECK-NEXT: (global.get $ctor-eval$global_7) + ;; CHECK-NEXT: (i32.const 1337) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_7)) (global $a (mut (ref null $A)) (ref.null $A)) (global $b (mut (ref null $B)) (ref.null $B)) @@ -481,11 +486,6 @@ ) ) - ;; CHECK: (global $ctor-eval$global_7 (ref $B) (struct.new $B - ;; CHECK-NEXT: (global.get $ctor-eval$global_8) - ;; CHECK-NEXT: (i32.const 1337) - ;; CHECK-NEXT: )) - ;; CHECK: (export "test" (func $test_3)) ;; CHECK: (export "keepalive" (func $keepalive)) @@ -506,8 +506,8 @@ ;; CHECK: (func $start (type $2) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_8) ;; CHECK-NEXT: (global.get $ctor-eval$global_7) +;; CHECK-NEXT: (global.get $ctor-eval$global_8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -536,12 +536,17 @@ ;; CHECK: (type $3 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_8 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_7 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_8)) + ;; CHECK: (global $ctor-eval$global_8 (ref $B) (struct.new $B + ;; CHECK-NEXT: (global.get $ctor-eval$global_7) + ;; CHECK-NEXT: (i32.const 1337) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_7)) (global $a (mut (ref null $A)) (ref.null $A)) (func $test (export "test") @@ -569,11 +574,6 @@ ) ) - ;; CHECK: (global $ctor-eval$global_7 (ref $B) (struct.new $B - ;; CHECK-NEXT: (global.get $ctor-eval$global_8) - ;; CHECK-NEXT: (i32.const 1337) - ;; CHECK-NEXT: )) - ;; CHECK: (export "test" (func $test_3)) ;; CHECK: (export "keepalive" (func $keepalive)) @@ -594,8 +594,8 @@ ;; CHECK: (func $start (type $2) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_8) ;; CHECK-NEXT: (global.get $ctor-eval$global_7) +;; CHECK-NEXT: (global.get $ctor-eval$global_8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -614,17 +614,22 @@ ;; CHECK: (type $2 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_13 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_12 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (i32.const 1337) + ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) ;; CHECK: (global $ctor-eval$global_14 (ref $A) (struct.new $A - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_14)) + ;; CHECK: (global $ctor-eval$global_13 (ref $A) (struct.new $A + ;; CHECK-NEXT: (global.get $ctor-eval$global_14) + ;; CHECK-NEXT: (i32.const 99999) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_12)) (global $a (mut (ref null $A)) (ref.null $A)) (global $b (mut (ref null $A)) (ref.null $A)) @@ -665,11 +670,6 @@ ) ) - ;; CHECK: (global $ctor-eval$global_12 (ref $A) (struct.new $A - ;; CHECK-NEXT: (global.get $ctor-eval$global_13) - ;; CHECK-NEXT: (i32.const 99999) - ;; CHECK-NEXT: )) - ;; CHECK: (export "test" (func $test_3)) ;; CHECK: (export "keepalive" (func $keepalive)) @@ -690,12 +690,8 @@ ;; CHECK: (func $start (type $1) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_13) -;; CHECK-NEXT: (global.get $ctor-eval$global_14) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_14) ;; CHECK-NEXT: (global.get $ctor-eval$global_12) +;; CHECK-NEXT: (global.get $ctor-eval$global_13) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -729,25 +725,25 @@ ;; CHECK: (type $4 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_14 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_12 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_13 (ref $B) (array.new_fixed $B 10 - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) + ;; CHECK: (global $ctor-eval$global_14 (ref $B) (array.new_fixed $B 10 + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_14)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_12)) (global $a (mut (ref null $A)) (ref.null $A)) (func $test (export "test") @@ -784,9 +780,9 @@ ) ) - ;; CHECK: (global $ctor-eval$global_12 (ref $C) (array.new_fixed $C 2 - ;; CHECK-NEXT: (global.get $ctor-eval$global_13) + ;; CHECK: (global $ctor-eval$global_13 (ref $C) (array.new_fixed $C 2 ;; CHECK-NEXT: (global.get $ctor-eval$global_14) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) ;; CHECK-NEXT: )) ;; CHECK: (export "test" (func $test_3)) @@ -809,8 +805,8 @@ ;; CHECK: (func $start (type $3) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_14) ;; CHECK-NEXT: (global.get $ctor-eval$global_12) +;; CHECK-NEXT: (global.get $ctor-eval$global_13) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -837,25 +833,25 @@ ;; CHECK: (type $4 (func (result i32))) - ;; CHECK: (global $ctor-eval$global_14 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_12 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_13 (ref $B) (array.new_fixed $B 10 - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) - ;; CHECK-NEXT: (global.get $ctor-eval$global_14) + ;; CHECK: (global $ctor-eval$global_14 (ref $B) (array.new_fixed $B 10 + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_14)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_12)) (global $a (mut (ref null $A)) (ref.null $A)) (global $b (mut (ref null $B)) (ref.null $B)) @@ -896,9 +892,9 @@ ) ) - ;; CHECK: (global $ctor-eval$global_12 (ref $C) (array.new_fixed $C 2 - ;; CHECK-NEXT: (global.get $ctor-eval$global_13) + ;; CHECK: (global $ctor-eval$global_13 (ref $C) (array.new_fixed $C 2 ;; CHECK-NEXT: (global.get $ctor-eval$global_14) + ;; CHECK-NEXT: (global.get $ctor-eval$global_12) ;; CHECK-NEXT: )) ;; CHECK: (export "test" (func $test_3)) @@ -921,8 +917,8 @@ ;; CHECK: (func $start (type $3) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_14) ;; CHECK-NEXT: (global.get $ctor-eval$global_12) +;; CHECK-NEXT: (global.get $ctor-eval$global_13) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -948,13 +944,25 @@ ;; CHECK: (type $3 (func (result anyref))) - ;; CHECK: (global $ctor-eval$global_16 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_17 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_16)) + ;; CHECK: (global $ctor-eval$global_14 (ref $A) (struct.new $A + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $ctor-eval$global_18 (ref $A) (struct.new $A + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_14)) (global $a (mut (ref null $A)) (ref.null $A)) (global $b (mut (ref null $B)) (ref.null $B)) @@ -986,27 +994,15 @@ ) ) - ;; CHECK: (global $ctor-eval$global_19 (ref $A) (struct.new $A - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: )) - - ;; CHECK: (global $ctor-eval$global_15 (ref $A) (struct.new $A - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: )) - - ;; CHECK: (global $ctor-eval$global_14 (ref $B) (array.new_fixed $B 3 - ;; CHECK-NEXT: (global.get $ctor-eval$global_15) - ;; CHECK-NEXT: (global.get $ctor-eval$global_16) - ;; CHECK-NEXT: (global.get $ctor-eval$global_19) + ;; CHECK: (global $ctor-eval$global_16 (ref $B) (array.new_fixed $B 3 + ;; CHECK-NEXT: (global.get $ctor-eval$global_17) + ;; CHECK-NEXT: (global.get $ctor-eval$global_14) + ;; CHECK-NEXT: (global.get $ctor-eval$global_18) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_17 (ref $B) (array.new_fixed $B 0)) + ;; CHECK: (global $ctor-eval$global_15 (ref $B) (array.new_fixed $B 0)) - ;; CHECK: (global $ctor-eval$global_18 (ref $B) (array.new_fixed $B 0)) + ;; CHECK: (global $ctor-eval$global_19 (ref $B) (array.new_fixed $B 0)) ;; CHECK: (export "test" (func $test_3)) @@ -1028,16 +1024,16 @@ ;; CHECK: (func $start (type $2) ;; CHECK-NEXT: (struct.set $A 0 -;; CHECK-NEXT: (global.get $ctor-eval$global_16) -;; CHECK-NEXT: (global.get $ctor-eval$global_17) +;; CHECK-NEXT: (global.get $ctor-eval$global_14) +;; CHECK-NEXT: (global.get $ctor-eval$global_15) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (struct.set $A 1 -;; CHECK-NEXT: (global.get $ctor-eval$global_16) ;; CHECK-NEXT: (global.get $ctor-eval$global_14) +;; CHECK-NEXT: (global.get $ctor-eval$global_16) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (struct.set $A 2 -;; CHECK-NEXT: (global.get $ctor-eval$global_16) -;; CHECK-NEXT: (global.get $ctor-eval$global_18) +;; CHECK-NEXT: (global.get $ctor-eval$global_14) +;; CHECK-NEXT: (global.get $ctor-eval$global_19) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1060,23 +1056,23 @@ ;; CHECK: (type $3 (func (result anyref))) - ;; CHECK: (global $ctor-eval$global_16 (ref $B) (array.new_fixed $B 3 + ;; CHECK: (global $ctor-eval$global_17 (ref $B) (array.new_fixed $B 0)) + + ;; CHECK: (global $ctor-eval$global_14 (ref $B) (array.new_fixed $B 3 ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_19 (ref $B) (array.new_fixed $B 0)) - - ;; CHECK: (global $ctor-eval$global_15 (ref $B) (array.new_fixed $B 0)) + ;; CHECK: (global $ctor-eval$global_18 (ref $B) (array.new_fixed $B 0)) - ;; CHECK: (global $ctor-eval$global_14 (ref $A) (struct.new $A - ;; CHECK-NEXT: (global.get $ctor-eval$global_15) - ;; CHECK-NEXT: (global.get $ctor-eval$global_16) - ;; CHECK-NEXT: (global.get $ctor-eval$global_19) + ;; CHECK: (global $ctor-eval$global_16 (ref $A) (struct.new $A + ;; CHECK-NEXT: (global.get $ctor-eval$global_17) + ;; CHECK-NEXT: (global.get $ctor-eval$global_14) + ;; CHECK-NEXT: (global.get $ctor-eval$global_18) ;; CHECK-NEXT: )) - ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_14)) + ;; CHECK: (global $a (mut (ref null $A)) (global.get $ctor-eval$global_16)) (global $a (mut (ref null $A)) (ref.null $A)) (global $b (mut (ref null $B)) (ref.null $B)) @@ -1109,13 +1105,13 @@ ) ) - ;; CHECK: (global $ctor-eval$global_17 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_15 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: )) - ;; CHECK: (global $ctor-eval$global_18 (ref $A) (struct.new $A + ;; CHECK: (global $ctor-eval$global_19 (ref $A) (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) @@ -1141,19 +1137,19 @@ ;; CHECK: (func $start (type $2) ;; CHECK-NEXT: (array.set $B -;; CHECK-NEXT: (global.get $ctor-eval$global_16) +;; CHECK-NEXT: (global.get $ctor-eval$global_14) ;; CHECK-NEXT: (i32.const 0) -;; CHECK-NEXT: (global.get $ctor-eval$global_17) +;; CHECK-NEXT: (global.get $ctor-eval$global_15) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (array.set $B -;; CHECK-NEXT: (global.get $ctor-eval$global_16) -;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: (global.get $ctor-eval$global_14) +;; CHECK-NEXT: (i32.const 1) +;; CHECK-NEXT: (global.get $ctor-eval$global_16) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (array.set $B -;; CHECK-NEXT: (global.get $ctor-eval$global_16) +;; CHECK-NEXT: (global.get $ctor-eval$global_14) ;; CHECK-NEXT: (i32.const 2) -;; CHECK-NEXT: (global.get $ctor-eval$global_18) +;; CHECK-NEXT: (global.get $ctor-eval$global_19) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/gto-mutability.wast b/test/lit/passes/gto-mutability.wast index 47a9e2315..13b416b1b 100644 --- a/test/lit/passes/gto-mutability.wast +++ b/test/lit/passes/gto-mutability.wast @@ -429,10 +429,10 @@ ;; optimize the field to be immutable. ;; CHECK: (rec - ;; CHECK-NEXT: (type $0 (func (param (ref null $super) (ref null $sub)))) - - ;; CHECK: (type $super (sub (struct (field i32)))) + ;; CHECK-NEXT: (type $super (sub (struct (field i32)))) (type $super (sub (struct (field (mut i32))))) + ;; CHECK: (type $1 (func (param (ref null $super) (ref null $sub)))) + ;; CHECK: (type $sub (sub $super (struct (field i32)))) (type $sub (sub $super (struct (field (mut i32))))) @@ -464,7 +464,7 @@ ) ) - ;; CHECK: (func $field-keepalive (type $0) (param $super (ref null $super)) (param $sub (ref null $sub)) + ;; CHECK: (func $field-keepalive (type $1) (param $super (ref null $super)) (param $sub (ref null $sub)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.get $super 0 ;; CHECK-NEXT: (local.get $super) diff --git a/test/lit/passes/signature-pruning.wast b/test/lit/passes/signature-pruning.wast index 8754c8189..57dd78362 100644 --- a/test/lit/passes/signature-pruning.wast +++ b/test/lit/passes/signature-pruning.wast @@ -1161,9 +1161,9 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $much (func)) + ;; CHECK-NEXT: (type $0 (func)) - ;; CHECK: (type $1 (func)) + ;; CHECK: (type $much (func)) ;; CHECK: (rec ;; CHECK-NEXT: (type $none (func)) @@ -1191,7 +1191,7 @@ (func $unused-param (type $much) (param $param i32) ) - ;; CHECK: (func $caller (type $1) + ;; CHECK: (func $caller (type $0) ;; CHECK-NEXT: (call $unused-param) ;; CHECK-NEXT: ) (func $caller diff --git a/test/lit/passes/signature-refining.wast b/test/lit/passes/signature-refining.wast index fdddbe4ed..7a5020e29 100644 --- a/test/lit/passes/signature-refining.wast +++ b/test/lit/passes/signature-refining.wast @@ -1068,11 +1068,11 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $0 (func (param (ref $B)))) - - ;; CHECK: (type $A (sub (struct))) + ;; CHECK-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) + ;; CHECK: (type $1 (func (param (ref $B)))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ) @@ -1108,7 +1108,7 @@ ) ) - ;; CHECK: (func $target (type $0) (param $x (ref $B)) + ;; CHECK: (func $target (type $1) (param $x (ref $B)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $target (param $x (ref $A)) diff --git a/test/lit/passes/type-merging.wast b/test/lit/passes/type-merging.wast index d6d117a05..b8d602863 100644 --- a/test/lit/passes/type-merging.wast +++ b/test/lit/passes/type-merging.wast @@ -234,10 +234,10 @@ (module (rec - ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct (field (ref null $A))))) (type $A (sub (struct (ref null $X)))) (type $B (sub $A (struct (ref null $Y)))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $X (sub (struct (field (ref null $X))))) (type $X (sub (struct (ref null $A)))) (type $Y (sub $X (struct (ref null $B)))) ) @@ -245,10 +245,10 @@ ;; CHECK: (type $1 (func)) ;; CHECK: (func $foo (type $1) - ;; CHECK-NEXT: (local $a (ref null $A)) - ;; CHECK-NEXT: (local $b (ref null $A)) - ;; CHECK-NEXT: (local $x (ref null $A)) - ;; CHECK-NEXT: (local $y (ref null $A)) + ;; CHECK-NEXT: (local $a (ref null $X)) + ;; CHECK-NEXT: (local $b (ref null $X)) + ;; CHECK-NEXT: (local $x (ref null $X)) + ;; CHECK-NEXT: (local $y (ref null $X)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $foo @@ -263,21 +263,21 @@ (module (rec - (type $A (struct (ref null $X) i32)) ;; CHECK: (rec - ;; CHECK-NEXT: (type $B (struct (field (ref null $Y)) (field i32))) + ;; CHECK-NEXT: (type $A (struct (field (ref null $X)) (field i32))) + (type $A (struct (ref null $X) i32)) (type $B (struct (ref null $Y) i32)) + ;; CHECK: (type $X (struct (field (ref null $A)) (field f32))) (type $X (struct (ref null $A) f32)) - ;; CHECK: (type $Y (struct (field (ref null $B)) (field f32))) (type $Y (struct (ref null $B) f32)) ) ;; CHECK: (type $2 (func)) ;; CHECK: (func $foo (type $2) - ;; CHECK-NEXT: (local $a (ref null $B)) - ;; CHECK-NEXT: (local $b (ref null $B)) - ;; CHECK-NEXT: (local $x (ref null $Y)) - ;; CHECK-NEXT: (local $y (ref null $Y)) + ;; CHECK-NEXT: (local $a (ref null $A)) + ;; CHECK-NEXT: (local $b (ref null $A)) + ;; CHECK-NEXT: (local $x (ref null $X)) + ;; CHECK-NEXT: (local $y (ref null $X)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $foo @@ -293,19 +293,19 @@ (module (rec (type $A (struct (ref null $X))) - ;; CHECK: (rec - ;; CHECK-NEXT: (type $B (struct (field (ref null $B)))) (type $B (struct (ref null $Y))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $X (struct (field (ref null $X)))) (type $X (struct (ref null $A))) (type $Y (struct (ref null $B))) ) ;; CHECK: (type $1 (func)) ;; CHECK: (func $foo (type $1) - ;; CHECK-NEXT: (local $a (ref null $B)) - ;; CHECK-NEXT: (local $b (ref null $B)) - ;; CHECK-NEXT: (local $x (ref null $B)) - ;; CHECK-NEXT: (local $y (ref null $B)) + ;; CHECK-NEXT: (local $a (ref null $X)) + ;; CHECK-NEXT: (local $b (ref null $X)) + ;; CHECK-NEXT: (local $x (ref null $X)) + ;; CHECK-NEXT: (local $y (ref null $X)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $foo @@ -495,8 +495,8 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $A (sub (struct (field anyref)))) (type $A (sub (struct anyref))) + ;; CHECK: (type $B (sub $A (struct (field eqref)))) (type $B (sub $A (struct eqref))) - ;; CHECK: (type $C (sub $A (struct (field eqref)))) (type $C (sub $A (struct eqref))) ) @@ -504,8 +504,8 @@ ;; CHECK: (func $foo (type $2) ;; CHECK-NEXT: (local $a (ref null $A)) - ;; CHECK-NEXT: (local $b (ref null $C)) - ;; CHECK-NEXT: (local $c (ref null $C)) + ;; CHECK-NEXT: (local $b (ref null $B)) + ;; CHECK-NEXT: (local $c (ref null $B)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $foo @@ -524,8 +524,8 @@ (type $A (sub (struct anyref))) (type $B (sub $A (struct anyref))) (type $C (sub $A (struct anyref))) + ;; CHECK: (type $D (sub $A (struct (field eqref)))) (type $D (sub $B (struct eqref))) - ;; CHECK: (type $E (sub $A (struct (field eqref)))) (type $E (sub $C (struct eqref))) ) @@ -535,8 +535,8 @@ ;; CHECK-NEXT: (local $a (ref null $A)) ;; CHECK-NEXT: (local $b (ref null $A)) ;; CHECK-NEXT: (local $c (ref null $A)) - ;; CHECK-NEXT: (local $d (ref null $E)) - ;; CHECK-NEXT: (local $e (ref null $E)) + ;; CHECK-NEXT: (local $d (ref null $D)) + ;; CHECK-NEXT: (local $e (ref null $D)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $foo @@ -561,18 +561,18 @@ (type $A' (sub $A (struct))) ;; These siblings will be merged only after $a and $a' are merged. + ;; CHECK: (type $B (sub (struct (field (ref $A))))) (type $B (sub (struct (ref $A)))) - ;; CHECK: (type $B' (sub (struct (field (ref $A))))) (type $B' (sub (struct (ref $A')))) ;; These will get merged only after $b and $b' are merged. - ;; CHECK: (type $C (sub $B' (struct (field (ref $A)) (field i32)))) + ;; CHECK: (type $C (sub $B (struct (field (ref $A)) (field i32)))) (type $C (sub $B (struct (ref $A) i32))) (type $C' (sub $B' (struct (ref $A') i32))) ;; These will get merged only after $c and $c' are merged. + ;; CHECK: (type $D (sub $C (struct (field (ref $A)) (field i32) (field i32)))) (type $D (sub $C (struct (ref $A) i32 i32))) - ;; CHECK: (type $D' (sub $C (struct (field (ref $A)) (field i32) (field i32)))) (type $D' (sub $C' (struct (ref $A') i32 i32))) ) @@ -581,12 +581,12 @@ ;; CHECK: (func $foo (type $4) ;; CHECK-NEXT: (local $a (ref null $A)) ;; CHECK-NEXT: (local $a' (ref null $A)) - ;; CHECK-NEXT: (local $b (ref null $B')) - ;; CHECK-NEXT: (local $b' (ref null $B')) + ;; CHECK-NEXT: (local $b (ref null $B)) + ;; CHECK-NEXT: (local $b' (ref null $B)) ;; CHECK-NEXT: (local $c (ref null $C)) ;; CHECK-NEXT: (local $c' (ref null $C)) - ;; CHECK-NEXT: (local $d (ref null $D')) - ;; CHECK-NEXT: (local $d' (ref null $D')) + ;; CHECK-NEXT: (local $d (ref null $D)) + ;; CHECK-NEXT: (local $d' (ref null $D)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $foo diff --git a/test/lit/passes/type-ssa_and_merging.wast b/test/lit/passes/type-ssa_and_merging.wast index 8e84cf5c4..4a772763b 100644 --- a/test/lit/passes/type-ssa_and_merging.wast +++ b/test/lit/passes/type-ssa_and_merging.wast @@ -14,14 +14,14 @@ ;; YES: (type $0 (func (result i32))) ;; YES: (rec - ;; YES-NEXT: (type $1 (func (param (ref $A)))) - - ;; YES: (type $A (sub (struct))) + ;; YES-NEXT: (type $A (sub (struct))) (type $A (sub (struct (field (mut i32))))) ;; NOP: (type $2 (func (result i32))) ;; NOP: (import "a" "b" (func $import (type $2) (result i32))) + ;; YES: (type $2 (func (param (ref $A)))) + ;; YES: (type $A_2 (sub $A (struct))) ;; YES: (type $A_1 (sub $A (struct))) @@ -92,7 +92,7 @@ ;; NOP-NEXT: (local.get $0) ;; NOP-NEXT: ) ;; NOP-NEXT: ) - ;; YES: (func $get-a-1 (type $1) (param $0 (ref $A)) + ;; YES: (func $get-a-1 (type $2) (param $0 (ref $A)) ;; YES-NEXT: (if ;; YES-NEXT: (call $import) ;; YES-NEXT: (then @@ -134,7 +134,7 @@ ;; NOP-NEXT: (local.get $0) ;; NOP-NEXT: ) ;; NOP-NEXT: ) - ;; YES: (func $get-a-2 (type $1) (param $0 (ref $A)) + ;; YES: (func $get-a-2 (type $2) (param $0 (ref $A)) ;; YES-NEXT: (if ;; YES-NEXT: (call $import) ;; YES-NEXT: (then |