summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/Vacuum.cpp19
-rw-r--r--test/passes/vacuum.txt20
-rw-r--r--test/passes/vacuum.wast17
-rw-r--r--test/unit.fromasm30
-rw-r--r--test/unit.fromasm.imprecise30
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)
)
)
)