diff options
-rw-r--r-- | src/passes/Vacuum.cpp | 19 | ||||
-rw-r--r-- | test/passes/vacuum.txt | 20 | ||||
-rw-r--r-- | test/passes/vacuum.wast | 17 | ||||
-rw-r--r-- | test/unit.fromasm | 30 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise | 30 |
5 files changed, 82 insertions, 34 deletions
diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp index 89ef7359e..db42a994a 100644 --- a/src/passes/Vacuum.cpp +++ b/src/passes/Vacuum.cpp @@ -203,6 +203,25 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum, Visitor<Vacuum>> // if the drop input has no side effects, it can be wiped out if (!EffectAnalyzer(curr->value).hasSideEffects()) { ExpressionManipulator::nop(curr); + return; + } + // sink a drop into an arm of an if-else if the other arm ends in an unreachable, as it if is a branch, this can make that branch optimizable and more vaccuming possible + auto* iff = curr->value->dynCast<If>(); + if (iff && iff->ifFalse && isConcreteWasmType(iff->type)) { + // reuse the drop in both cases + if (iff->ifTrue->type == unreachable) { + assert(isConcreteWasmType(iff->ifFalse->type)); + curr->value = iff->ifFalse; + iff->ifFalse = curr; + iff->type = none; + replaceCurrent(iff); + } else if (iff->ifFalse->type == unreachable) { + assert(isConcreteWasmType(iff->ifTrue->type)); + curr->value = iff->ifTrue; + iff->ifTrue = curr; + iff->type = none; + replaceCurrent(iff); + } } } diff --git a/test/passes/vacuum.txt b/test/passes/vacuum.txt index c4004dd28..678c18cfa 100644 --- a/test/passes/vacuum.txt +++ b/test/passes/vacuum.txt @@ -5,6 +5,8 @@ (type $2 (func (result f32))) (type $3 (func (result i32))) (type $4 (func (param i32 f64 i32 i32))) + (type $FUNCSIG$i (func (result i32))) + (import $int "env" "int" (result i32)) (func $b (type $0) (nop) ) @@ -158,4 +160,22 @@ (unreachable) ) ) + (func $if-drop (type $0) + (block $out + (if + (i32.const 0) + (drop + (call_import $int) + ) + (br $out) + ) + (if + (i32.const 1) + (br $out) + (drop + (call_import $int) + ) + ) + ) + ) ) diff --git a/test/passes/vacuum.wast b/test/passes/vacuum.wast index 7b8d6a08a..3630512b4 100644 --- a/test/passes/vacuum.wast +++ b/test/passes/vacuum.wast @@ -5,6 +5,7 @@ (type $2 (func (result f32))) (type $3 (func (result i32))) (type $4 (func (param i32 f64 i32 i32))) + (import $int "env" "int" (result i32)) (func $b (type $0) (drop (i32.const 50) @@ -297,4 +298,20 @@ (unreachable) ) ) + (func $if-drop + (block $out + (drop + (if (i32.const 0) + (call_import $int) + (br $out) + ) + ) + (drop + (if (i32.const 1) + (br $out) + (call_import $int) + ) + ) + ) + ) ) diff --git a/test/unit.fromasm b/test/unit.fromasm index f48dfcdb2..049b4dc8a 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -492,13 +492,12 @@ ) (func $smallIf (block $do-once$0 - (drop - (if - (i32.const 2) + (if + (i32.const 2) + (drop (call $lb (i32.const 3) ) - (br $do-once$0) ) ) ) @@ -544,21 +543,18 @@ ) (func $breakThroughMany (param $0 i32) (block $label$break$L1 - (drop - (if - (get_local $0) - (loop $while-in$2 - (br_if $label$break$L1 - (i32.eqz - (get_local $0) - ) - ) - (call $zeroInit - (i32.const 0) + (if + (get_local $0) + (loop $while-in$2 + (br_if $label$break$L1 + (i32.eqz + (get_local $0) ) - (br $while-in$2) ) - (i32.const 1337) + (call $zeroInit + (i32.const 0) + ) + (br $while-in$2) ) ) ) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index 06ab40915..d0d98452f 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -474,13 +474,12 @@ ) (func $smallIf (block $do-once$0 - (drop - (if - (i32.const 2) + (if + (i32.const 2) + (drop (call $lb (i32.const 3) ) - (br $do-once$0) ) ) ) @@ -526,21 +525,18 @@ ) (func $breakThroughMany (param $0 i32) (block $label$break$L1 - (drop - (if - (get_local $0) - (loop $while-in$2 - (br_if $label$break$L1 - (i32.eqz - (get_local $0) - ) - ) - (call $zeroInit - (i32.const 0) + (if + (get_local $0) + (loop $while-in$2 + (br_if $label$break$L1 + (i32.eqz + (get_local $0) ) - (br $while-in$2) ) - (i32.const 1337) + (call $zeroInit + (i32.const 0) + ) + (br $while-in$2) ) ) ) |