summaryrefslogtreecommitdiff
path: root/test/lit/passes/remove-unused-module-elements_all-features.wast
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2023-04-04 13:00:24 -0700
committerGitHub <noreply@github.com>2023-04-04 13:00:24 -0700
commitce2fc9c7cd5158a64631baeda53dac2571038d5f (patch)
tree9797f2e1d05efd87881564573d54270b828c05b2 /test/lit/passes/remove-unused-module-elements_all-features.wast
parentdb23ac7f02396dfcf13a1ef6a7c5665f19d91c35 (diff)
downloadbinaryen-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.wast195
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)
+ )
+ )
+ )
+)