summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2022-11-08 15:43:22 -0800
committerGitHub <noreply@github.com>2022-11-08 15:43:22 -0800
commitd7920cb9dc07a2efee8abf44d7c1a6a654a88593 (patch)
treec1d8dd9ebfb1c81edddfd156edc0c366135d200c
parent85ba74c8162ebf4e659a3450de0fb48a4a7141b0 (diff)
downloadbinaryen-d7920cb9dc07a2efee8abf44d7c1a6a654a88593.tar.gz
binaryen-d7920cb9dc07a2efee8abf44d7c1a6a654a88593.tar.bz2
binaryen-d7920cb9dc07a2efee8abf44d7c1a6a654a88593.zip
Fix possible-contents.h for `array.new_{data,elem}` (#5232)
* Update MemoryPacking for array.new_data The MemoryPacking pass looks at all instructions that reference memory segments to determine how they can be optimized. #5214 introduced a new instruction that references memory segments, array.new_data, but did not update MemoryPacking accordingly. This omission meant that MemoryPacking could produce invalid or misoptimized modules in the presence of array.new_data. Fix the problem by making MemoryPacking aware of array.new_data. Consider array.new_data when determining whether a segment is used and update array.new_data to reflect the new, optimized segment numberings afterward. To keep things simple, do not try to split any segment that is referred to by a array.new_data instruction. * fix * Add test explanations * Fix possible-contents.h for `array.new_{data,elem}` This code was not properly updated in #5214, so GUFA would incorrectly optimize out `array.new_data` and `array.new_elem` instructions. Fix the problem by making these instructions data flow roots. * fix * move tests
-rw-r--r--src/ir/possible-contents.cpp1
-rw-r--r--test/lit/passes/gufa-refs.wast70
2 files changed, 71 insertions, 0 deletions
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp
index 0c4e28568..35e87175a 100644
--- a/src/ir/possible-contents.cpp
+++ b/src/ir/possible-contents.cpp
@@ -900,6 +900,7 @@ struct InfoCollector
if (curr->type == Type::unreachable) {
return;
}
+ addRoot(curr, PossibleContents::exactType(curr->type));
auto heapType = curr->type.getHeapType();
switch (curr->op) {
case NewData: {
diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast
index e5df2afd4..fc01dd481 100644
--- a/test/lit/passes/gufa-refs.wast
+++ b/test/lit/passes/gufa-refs.wast
@@ -5393,3 +5393,73 @@
)
)
)
+
+
+;; Check that array.new_data and array.new_seg are handled properly.
+(module
+ ;; CHECK: (type $array-i8 (array_subtype i8 data))
+ (type $array-i8 (array i8))
+ ;; CHECK: (type $array-funcref (array_subtype funcref data))
+ (type $array-funcref (array funcref))
+ ;; CHECK: (type $ref|$array-i8|_ref|$array-funcref|_=>_none (func_subtype (param (ref $array-i8) (ref $array-funcref)) func))
+
+ ;; CHECK: (data "hello")
+ (data "hello")
+ ;; CHECK: (elem func $test)
+ (elem func $test)
+
+ ;; CHECK: (export "test" (func $test))
+
+ ;; CHECK: (func $test (type $ref|$array-i8|_ref|$array-funcref|_=>_none) (param $array-i8 (ref $array-i8)) (param $array-funcref (ref $array-funcref))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (array.new_data $array-i8 0
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (i32.const 5)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (array.new_elem $array-funcref 0
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (array.get_u $array-i8
+ ;; CHECK-NEXT: (local.get $array-i8)
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (array.get $array-funcref
+ ;; CHECK-NEXT: (local.get $array-funcref)
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $test (export "test") (param $array-i8 (ref $array-i8)) (param $array-funcref (ref $array-funcref))
+ (drop
+ (array.new_data $array-i8 0
+ (i32.const 0)
+ (i32.const 5)
+ )
+ )
+ (drop
+ (array.new_elem $array-funcref 0
+ (i32.const 0)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (array.get $array-i8
+ (local.get $array-i8)
+ (i32.const 0)
+ )
+ )
+ (drop
+ (array.get $array-funcref
+ (local.get $array-funcref)
+ (i32.const 0)
+ )
+ )
+ )
+)