diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp index 401d2e6291b..12f67329d4b 100644 --- a/src/passes/MergeBlocks.cpp +++ b/src/passes/MergeBlocks.cpp @@ -434,6 +434,15 @@ struct MergeBlocks optimizeBlock(curr, getModule(), getPassOptions(), branchInfo); } + void visitDrop(Drop* curr) { + if (auto* block = curr->value->dynCast()) { + if (optimizeDroppedBlock( + curr, block, *getModule(), getPassOptions(), branchInfo)) { + replaceCurrent(block); + } + } + } + // given // (curr // (block=child diff --git a/test/lit/passes/merge-blocks.wast b/test/lit/passes/merge-blocks.wast index e1ac88dd83e..86181f7a488 100644 --- a/test/lit/passes/merge-blocks.wast +++ b/test/lit/passes/merge-blocks.wast @@ -405,17 +405,16 @@ ) ;; CHECK: (func $toplevel (type $4) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $label (result i32) - ;; CHECK-NEXT: (br $label - ;; CHECK-NEXT: (i32.const 42) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $label + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $toplevel ;; Test we can remove a block value even when the drop is at the toplevel of - ;; a function. This is not done yet TODO + ;; a function. (drop (block $label (result i32) (br $label diff --git a/test/lit/passes/merge-blocks_names.wast b/test/lit/passes/merge-blocks_names.wast new file mode 100644 index 00000000000..c6e08b83ab3 --- /dev/null +++ b/test/lit/passes/merge-blocks_names.wast @@ -0,0 +1,28 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --merge-blocks -all -S -o - | filecheck %s +;; +;; Similar to merge-blocks.wast, but without --remove-unused-names. This tests +;; the pass entirely by itself. + +(module + ;; CHECK: (func $nested-dropped-blocks (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $nested-dropped-blocks + ;; Fully removing unneeded blocks here requires multiple operations to happen. + ;; Specifically, we remove all the outer blocks first, and only then get to + ;; the inner named block, which we can then infer is not needed either. + (block + (drop + (block (result i32) + (block $named (result i32) + (i32.const 42) + ) + ) + ) + ) + ) +) + diff --git a/test/lit/passes/monomorphize-drop.wast b/test/lit/passes/monomorphize-drop.wast index a9f0e1f06df..2c683420408 100644 --- a/test/lit/passes/monomorphize-drop.wast +++ b/test/lit/passes/monomorphize-drop.wast @@ -672,12 +672,7 @@ ;; CAREFUL: (func $return-normal_4 (type $1) ;; CAREFUL-NEXT: (drop -;; CAREFUL-NEXT: (block -;; CAREFUL-NEXT: (drop -;; CAREFUL-NEXT: (call $import) -;; CAREFUL-NEXT: ) -;; CAREFUL-NEXT: (return) -;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: (call $import) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) diff --git a/test/passes/Oz_fuzz-exec_all-features.txt b/test/passes/Oz_fuzz-exec_all-features.txt index b69b9728cca..d1a80c3182b 100644 --- a/test/passes/Oz_fuzz-exec_all-features.txt +++ b/test/passes/Oz_fuzz-exec_all-features.txt @@ -183,14 +183,10 @@ (nop) ) (func $br-on_non_null-2 (type $void_func) - (drop - (block - (call $log - (i32.const 1) - ) - (unreachable) - ) + (call $log + (i32.const 1) ) + (unreachable) ) (func $cast-on-func (type $void_func) (call $log diff --git a/test/passes/merge-blocks.txt b/test/passes/merge-blocks.txt index 86d97af4b01..96e62170443 100644 --- a/test/passes/merge-blocks.txt +++ b/test/passes/merge-blocks.txt @@ -10,11 +10,12 @@ ) ) (func $drop-block-br - (drop - (block $x (result i32) - (br $x - (i32.const 1) - ) + (block $x + (drop + (i32.const 1) + ) + (br $x) + (drop (i32.const 0) ) ) @@ -77,15 +78,9 @@ ) ) (func $drop-block-squared-iloop - (drop - (block $label$0 (result i32) - (drop - (block $label$1 - (loop $label$2 - (br $label$2) - ) - ) - ) + (block $label$0 + (loop $label$2 + (br $label$2) ) ) ) @@ -109,11 +104,7 @@ (func $loop-block-drop-block-return (loop $label$4 (block $label$5 - (drop - (block $label$6 (result i32) - (return) - ) - ) + (return) ) ) ) diff --git a/test/passes/remove-unused-names_merge-blocks_all-features.txt b/test/passes/remove-unused-names_merge-blocks_all-features.txt index c1c803af5dd..17ba2bd4d12 100644 --- a/test/passes/remove-unused-names_merge-blocks_all-features.txt +++ b/test/passes/remove-unused-names_merge-blocks_all-features.txt @@ -286,15 +286,11 @@ (i32.const 30) ) (drop - (block - (drop - (i32.const 10) - ) - (i32.add - (unreachable) - (i32.const 20) - ) - ) + (i32.const 10) + ) + (i32.add + (unreachable) + (i32.const 20) ) (drop (i32.const 20) @@ -822,17 +818,13 @@ ) (func $drop-unreachable (type $2) (result i32) (local $0 i32) - (drop - (block (result i32) - (unreachable) - ) - ) + (unreachable) (unreachable) ) (func $concrete_finale_in_unreachable (type $5) (result f64) - (drop - (block (result f64) - (unreachable) + (block + (unreachable) + (drop (f64.const 6.322092475576799e-96) ) ) @@ -840,22 +832,16 @@ ) (func $dont-move-unreachable (type $3) (loop $label$0 + (br $label$0) (drop - (block (result i32) - (br $label$0) - (i32.const 1) - ) + (i32.const 1) ) ) ) (func $dont-move-unreachable-last (type $3) (loop $label$0 - (drop - (block (result i32) - (call $dont-move-unreachable-last) - (br $label$0) - ) - ) + (call $dont-move-unreachable-last) + (br $label$0) ) ) (func $move-around-unreachable-in-middle (type $3) @@ -876,16 +862,10 @@ ) (func $drop-unreachable-block-with-concrete-final (type $3) (drop - (block (result i32) - (drop - (block - (drop - (return) - ) - ) - ) - (i32.const -452) - ) + (return) + ) + (drop + (i32.const -452) ) ) (func $merging-with-unreachable-in-middle (type $2) (result i32) @@ -901,13 +881,9 @@ ) (func $remove-br-after-unreachable (type $3) (block $label$9 - (drop - (block - (block - (return) - (br $label$9) - ) - ) + (block + (return) + (br $label$9) ) ) )