diff options
author | Alon Zakai <azakai@google.com> | 2022-12-07 12:11:03 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-07 12:11:03 -0800 |
commit | 5a8d09bfe725f321b022187e294991db3ffaa417 (patch) | |
tree | 384c057d10ef266b1084d324e501f3d5dc253e64 | |
parent | 4957d29fab26d235ed035a59441d74c9e4a4f561 (diff) | |
download | binaryen-5a8d09bfe725f321b022187e294991db3ffaa417.tar.gz binaryen-5a8d09bfe725f321b022187e294991db3ffaa417.tar.bz2 binaryen-5a8d09bfe725f321b022187e294991db3ffaa417.zip |
[Wasm GC] Add array support to TypeMerging (#5329)
-rw-r--r-- | src/passes/TypeMerging.cpp | 29 | ||||
-rw-r--r-- | test/lit/passes/type-merging.wast | 41 |
2 files changed, 55 insertions, 15 deletions
diff --git a/src/passes/TypeMerging.cpp b/src/passes/TypeMerging.cpp index 94a198adf..0fc766f4e 100644 --- a/src/passes/TypeMerging.cpp +++ b/src/passes/TypeMerging.cpp @@ -149,22 +149,21 @@ struct TypeMerging : public Pass { continue; } - // TODO: arrays - if (!type.isStruct()) { - continue; - } - - auto& fields = type.getStruct().fields; - auto& superFields = super->getStruct().fields; - if (fields != superFields) { - // This adds a field, or refines one, so it differs from the super, and - // we cannot merge it with the super. - continue; + if (type.isStruct()) { + auto& fields = type.getStruct().fields; + auto& superFields = super->getStruct().fields; + if (fields == superFields) { + // We can merge! This is identical structurally to the super, and also + // not distinguishable nominally. + merges[type] = *super; + } + } else if (type.isArray()) { + auto element = type.getArray().element; + auto superElement = super->getArray().element; + if (element == superElement) { + merges[type] = *super; + } } - - // We can merge! This is identical structurally to the super, and also not - // distinguishable nominally. - merges[type] = *super; } if (merges.empty()) { diff --git a/test/lit/passes/type-merging.wast b/test/lit/passes/type-merging.wast index 4df8d7e88..f28cf0e1d 100644 --- a/test/lit/passes/type-merging.wast +++ b/test/lit/passes/type-merging.wast @@ -235,3 +235,44 @@ ) ) ) + +;; Arrays +(module + ;; CHECK: (type $none_=>_none (func)) + + ;; CHECK: (type $intarray (array (mut i32))) + (type $intarray (array (mut i32))) + (type $sub-intarray (array_subtype (mut i32) $intarray)) + + ;; CHECK: (type $refarray (array anyref)) + (type $refarray (array (ref null any))) + (type $sub-refarray (array_subtype (ref null any) $refarray)) + ;; CHECK: (type $sub-refarray-nn (array_subtype (ref any) $refarray)) + (type $sub-refarray-nn (array_subtype (ref any) $refarray)) + + ;; CHECK: (func $foo (type $none_=>_none) + ;; CHECK-NEXT: (local $a (ref null $intarray)) + ;; CHECK-NEXT: (local $b (ref null $intarray)) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $foo + ;; $A will remain the same. + (local $a (ref null $intarray)) + ;; $B can be merged into $A. + (local $b (ref null $sub-intarray)) + ) + + ;; CHECK: (func $bar (type $none_=>_none) + ;; CHECK-NEXT: (local $a (ref null $refarray)) + ;; CHECK-NEXT: (local $b (ref null $refarray)) + ;; CHECK-NEXT: (local $c (ref null $sub-refarray-nn)) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $bar + (local $a (ref null $refarray)) + ;; $B can be merged into $A. + (local $b (ref null $sub-refarray)) + ;; $C cannot be merged as the element type is more refined. + (local $c (ref null $sub-refarray-nn)) + ) +) |