summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-12-07 12:11:03 -0800
committerGitHub <noreply@github.com>2022-12-07 12:11:03 -0800
commit5a8d09bfe725f321b022187e294991db3ffaa417 (patch)
tree384c057d10ef266b1084d324e501f3d5dc253e64
parent4957d29fab26d235ed035a59441d74c9e4a4f561 (diff)
downloadbinaryen-5a8d09bfe725f321b022187e294991db3ffaa417.tar.gz
binaryen-5a8d09bfe725f321b022187e294991db3ffaa417.tar.bz2
binaryen-5a8d09bfe725f321b022187e294991db3ffaa417.zip
[Wasm GC] Add array support to TypeMerging (#5329)
-rw-r--r--src/passes/TypeMerging.cpp29
-rw-r--r--test/lit/passes/type-merging.wast41
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))
+ )
+)