diff options
author | Thomas Lively <tlively@google.com> | 2023-04-04 13:00:24 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-04 13:00:24 -0700 |
commit | ce2fc9c7cd5158a64631baeda53dac2571038d5f (patch) | |
tree | 9797f2e1d05efd87881564573d54270b828c05b2 /test/lit/passes/remove-unused-module-elements_all-features.wast | |
parent | db23ac7f02396dfcf13a1ef6a7c5665f19d91c35 (diff) | |
download | binaryen-ce2fc9c7cd5158a64631baeda53dac2571038d5f.tar.gz binaryen-ce2fc9c7cd5158a64631baeda53dac2571038d5f.tar.bz2 binaryen-ce2fc9c7cd5158a64631baeda53dac2571038d5f.zip |
Support multiple memories in RemoveUnusedModuleElements (#5604)
Add support for memory and data segment module elements and treat them uniformly
with other module elements rather than as special cases. There is a cyclic
dependency between memories (or tables) and their active segments because
exported or accessed memories (or tables) keep their active segments alive, but
active segments for imported memories (or tables) keep their memories (or
tables) alive as well.
Diffstat (limited to 'test/lit/passes/remove-unused-module-elements_all-features.wast')
-rw-r--r-- | test/lit/passes/remove-unused-module-elements_all-features.wast | 195 |
1 files changed, 167 insertions, 28 deletions
diff --git a/test/lit/passes/remove-unused-module-elements_all-features.wast b/test/lit/passes/remove-unused-module-elements_all-features.wast index 00a9d8f14..d5c394e30 100644 --- a/test/lit/passes/remove-unused-module-elements_all-features.wast +++ b/test/lit/passes/remove-unused-module-elements_all-features.wast @@ -351,63 +351,89 @@ (memory.atomic.notify (i32.const 0) (i32.const 0)) ) ) -(module ;; atomic.fence does not use a memory, so should not keep the memory alive. +(module ;; atomic.fence and data.drop do not use a memory, so should not keep the memory alive. (memory $0 (shared 1 1)) + (data "") ;; CHECK: (type $none_=>_none (func)) + ;; CHECK: (data $0 "") + ;; CHECK: (export "fake-user" (func $user)) (export "fake-user" $user) ;; CHECK: (func $user (type $none_=>_none) ;; CHECK-NEXT: (atomic.fence) + ;; CHECK-NEXT: (data.drop $0) ;; CHECK-NEXT: ) (func $user (atomic.fence) + (data.drop 0) ) ) (module ;; more use checks - ;; CHECK: (type $none_=>_i32 (func (result i32))) + ;; CHECK: (type $none_=>_none (func)) + + ;; CHECK: (import "env" "mem" (memory $0 256)) + (import "env" "mem" (memory $0 256)) + ;; CHECK: (memory $1 23 256) + (memory $1 23 256) + (memory $unused 1 1) - ;; CHECK: (memory $0 23 256) - (memory $0 23 256) ;; CHECK: (export "user" (func $user)) (export "user" $user) - ;; CHECK: (func $user (type $none_=>_i32) (result i32) - ;; CHECK-NEXT: (memory.grow - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK: (func $user (type $none_=>_none) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (memory.grow $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (memory.grow $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $user (result i32) - (memory.grow (i32.const 0)) + (func $user + (drop (memory.grow $0 (i32.const 0))) + (drop (memory.grow $1 (i32.const 0))) ) ) (module ;; more use checks ;; CHECK: (type $none_=>_i32 (func (result i32))) - ;; CHECK: (import "env" "memory" (memory $0 256)) - (import "env" "memory" (memory $0 256)) + ;; CHECK: (memory $0 23 256) + (memory $0 23 256) ;; CHECK: (export "user" (func $user)) (export "user" $user) ;; CHECK: (func $user (type $none_=>_i32) (result i32) - ;; CHECK-NEXT: (memory.grow - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.size) ;; CHECK-NEXT: ) (func $user (result i32) - (memory.grow (i32.const 0)) + (memory.size) ) ) -(module ;; more use checks - ;; CHECK: (type $none_=>_i32 (func (result i32))) +(module ;; memory.copy should keep both memories alive + ;; CHECK: (type $none_=>_none (func)) - ;; CHECK: (memory $0 23 256) - (memory $0 23 256) + ;; CHECK: (memory $0 1 1) + (memory $0 1 1) + ;; CHECK: (memory $1 1 1) + (memory $1 1 1) + (memory $unused 1 1) ;; CHECK: (export "user" (func $user)) (export "user" $user) - ;; CHECK: (func $user (type $none_=>_i32) (result i32) - ;; CHECK-NEXT: (memory.size) + ;; CHECK: (func $user (type $none_=>_none) + ;; CHECK-NEXT: (memory.copy $0 $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $user (result i32) - (memory.size) + (func $user + (memory.copy $0 $1 + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) ) ) (module @@ -554,15 +580,40 @@ ) ) ) -(module ;; the table is imported - we can't remove it +(module + ;; We import two tables and have an active segment that writes to one of them. + ;; We must keep that table and the segment, but we can remove the other table. ;; CHECK: (type $0 (func (param f64) (result f64))) (type $0 (func (param f64) (result f64))) - ;; CHECK: (import "env" "table" (table $timport$0 6 6 funcref)) - (import "env" "table" (table 6 6 funcref)) - (elem (i32.const 0) $0) - ;; CHECK: (elem $0 (i32.const 0) $0) + ;; CHECK: (import "env" "written" (table $written 6 6 funcref)) + (import "env" "written" (table $written 6 6 funcref)) + + (import "env" "unwritten" (table $unwritten 6 6 funcref)) + + (table $defined-unused 6 6 funcref) + + ;; CHECK: (table $defined-used 6 6 funcref) + (table $defined-used 6 6 funcref) + + ;; CHECK: (elem $active1 (table $written) (i32.const 0) func $0) + (elem $active1 (table $written) (i32.const 0) $0) + + ;; This empty active segment doesn't keep the unwritten table alive. + (elem $active2 (table $unwritten) (i32.const 0)) + + (elem $active3 (table $defined-unused) (i32.const 0) $0) + + ;; CHECK: (elem $active4 (table $defined-used) (i32.const 0) func $0) + (elem $active4 (table $defined-used) (i32.const 0) $0) + + (elem $active5 (table $defined-used) (i32.const 0)) ;; CHECK: (func $0 (type $0) (param $var$0 f64) (result f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (table.get $defined-used + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if (result f64) ;; CHECK-NEXT: (f64.eq ;; CHECK-NEXT: (f64.const 1) @@ -573,6 +624,11 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $0 (; 0 ;) (type $0) (param $var$0 f64) (result f64) + (drop + (table.get $defined-used + (i32.const 0) + ) + ) (if (result f64) (f64.eq (f64.const 1) @@ -583,3 +639,86 @@ ) ) ) +(module + ;; The same thing works for memories with active segments. + ;; CHECK: (type $none_=>_none (func)) + + ;; CHECK: (import "env" "written" (memory $written 1 1)) + (import "env" "written" (memory $written 1 1)) + + (import "env" "unwritten" (memory $unwritten 1 1)) + + (memory $defined-unused 1 1) + + ;; CHECK: (memory $defined-used 1 1) + (memory $defined-used 1 1) + + ;; CHECK: (data $active1 (i32.const 0) "foobar") + (data $active1 (memory $written) (i32.const 0) "foobar") + + (data $active2 (memory $unwritten) (i32.const 0) "") + + (data $active3 (memory $defined-unused) (i32.const 0) "hello") + + ;; CHECK: (data $active4 (memory $defined-used) (i32.const 0) "hello") + (data $active4 (memory $defined-used) (i32.const 0) "hello") + + (data $active5 (memory $defined-used) (i32.const 0) "") + + ;; CHECK: (export "user" (func $user)) + + ;; CHECK: (func $user (type $none_=>_none) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load $defined-used + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $user (export "user") + (drop + (i32.load $defined-used + (i32.const 0) + ) + ) + ) +) +(module + ;; Nothing should break if the unused segments precede the used segments. + ;; CHECK: (type $none_=>_none (func)) + + ;; CHECK: (type $array (array funcref)) + (type $array (array funcref)) + + (memory $mem 1 1) + (table $tab 1 1 funcref) + + (data $unused "") + (elem $unused func) + + ;; CHECK: (data $used "") + (data $used "") + ;; CHECK: (elem $used func) + (elem $used func) + + ;; CHECK: (export "user" (func $user)) + + ;; CHECK: (func $user (type $none_=>_none) + ;; CHECK-NEXT: (data.drop $used) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_elem $array $used + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $user (export "user") + (data.drop 1) + (drop + (array.new_elem $array 1 + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + ) + ) +) |