summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/Vacuum.cpp29
-rw-r--r--test/emcc_hello_world.fromasm56
-rw-r--r--test/emcc_hello_world.fromasm.imprecise56
-rw-r--r--test/passes/vacuum.txt45
-rw-r--r--test/passes/vacuum.wast40
-rw-r--r--test/unit.fromasm18
-rw-r--r--test/unit.fromasm.imprecise16
7 files changed, 138 insertions, 122 deletions
diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp
index db42a994a..53b9eb397 100644
--- a/src/passes/Vacuum.cpp
+++ b/src/passes/Vacuum.cpp
@@ -47,26 +47,31 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum, Visitor<Vacuum>>
case Expression::Id::CallImportId:
case Expression::Id::CallIndirectId:
case Expression::Id::SetLocalId:
- case Expression::Id::LoadId:
case Expression::Id::StoreId:
case Expression::Id::ReturnId:
- case Expression::Id::GetGlobalId:
case Expression::Id::SetGlobalId:
case Expression::Id::HostId:
case Expression::Id::UnreachableId: return curr; // always needed
+ case Expression::Id::LoadId: {
+ if (!resultUsed) {
+ return curr->cast<Load>()->ptr;
+ }
+ return curr;
+ }
case Expression::Id::ConstId:
case Expression::Id::GetLocalId:
+ case Expression::Id::GetGlobalId: {
+ if (!resultUsed) return nullptr;
+ return curr;
+ }
+
case Expression::Id::UnaryId:
case Expression::Id::BinaryId:
case Expression::Id::SelectId: {
if (resultUsed) {
return curr; // used, keep it
}
- // result is not used, perhaps it is dead
- if (curr->is<Const>() || curr->is<GetLocal>()) {
- return nullptr;
- }
// for unary, binary, and select, we need to check their arguments for side effects
if (auto* unary = curr->dynCast<Unary>()) {
if (EffectAnalyzer(unary->value).hasSideEffects()) {
@@ -200,11 +205,19 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum, Visitor<Vacuum>>
}
void visitDrop(Drop* curr) {
- // if the drop input has no side effects, it can be wiped out
- if (!EffectAnalyzer(curr->value).hasSideEffects()) {
+ // optimize the dropped value, maybe leaving nothing
+ curr->value = optimize(curr->value, false);
+ if (curr->value == nullptr) {
ExpressionManipulator::nop(curr);
return;
}
+ // a drop of a tee is a set
+ if (auto* set = curr->value->dynCast<SetLocal>()) {
+ assert(set->isTee());
+ set->setTee(false);
+ replaceCurrent(set);
+ 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)) {
diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm
index 4c032627d..3b93c26fd 100644
--- a/test/emcc_hello_world.fromasm
+++ b/test/emcc_hello_world.fromasm
@@ -3325,21 +3325,17 @@
)
(i32.const 10)
)
- (drop
- (i32.load offset=4
- (tee_local $1
+ (set_local $1
+ (i32.add
+ (get_local $3)
+ (i32.shl
(i32.add
- (get_local $3)
- (i32.shl
- (i32.add
- (i32.load8_s
- (get_local $6)
- )
- (i32.const -48)
- )
- (i32.const 3)
+ (i32.load8_s
+ (get_local $6)
)
+ (i32.const -48)
)
+ (i32.const 3)
)
)
)
@@ -3702,21 +3698,17 @@
)
(i32.const 10)
)
- (drop
- (i32.load offset=4
- (tee_local $1
+ (set_local $1
+ (i32.add
+ (get_local $3)
+ (i32.shl
(i32.add
- (get_local $3)
- (i32.shl
- (i32.add
- (i32.load8_s
- (get_local $6)
- )
- (i32.const -48)
- )
- (i32.const 3)
+ (i32.load8_s
+ (get_local $6)
)
+ (i32.const -48)
)
+ (i32.const 3)
)
)
)
@@ -4539,12 +4531,8 @@
)
(br $switch$24)
)
- (drop
- (i32.load offset=4
- (tee_local $1
- (get_local $18)
- )
- )
+ (set_local $1
+ (get_local $18)
)
(i32.store8
(get_local $71)
@@ -4606,12 +4594,8 @@
)
(br $switch$24)
)
- (drop
- (i32.load offset=4
- (tee_local $1
- (get_local $18)
- )
- )
+ (set_local $1
+ (get_local $18)
)
(i32.store
(get_local $72)
diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise
index d5dd39c95..0d1653a62 100644
--- a/test/emcc_hello_world.fromasm.imprecise
+++ b/test/emcc_hello_world.fromasm.imprecise
@@ -3318,21 +3318,17 @@
)
(i32.const 10)
)
- (drop
- (i32.load offset=4
- (tee_local $1
+ (set_local $1
+ (i32.add
+ (get_local $3)
+ (i32.shl
(i32.add
- (get_local $3)
- (i32.shl
- (i32.add
- (i32.load8_s
- (get_local $6)
- )
- (i32.const -48)
- )
- (i32.const 3)
+ (i32.load8_s
+ (get_local $6)
)
+ (i32.const -48)
)
+ (i32.const 3)
)
)
)
@@ -3695,21 +3691,17 @@
)
(i32.const 10)
)
- (drop
- (i32.load offset=4
- (tee_local $1
+ (set_local $1
+ (i32.add
+ (get_local $3)
+ (i32.shl
(i32.add
- (get_local $3)
- (i32.shl
- (i32.add
- (i32.load8_s
- (get_local $6)
- )
- (i32.const -48)
- )
- (i32.const 3)
+ (i32.load8_s
+ (get_local $6)
)
+ (i32.const -48)
)
+ (i32.const 3)
)
)
)
@@ -4532,12 +4524,8 @@
)
(br $switch$24)
)
- (drop
- (i32.load offset=4
- (tee_local $1
- (get_local $18)
- )
- )
+ (set_local $1
+ (get_local $18)
)
(i32.store8
(get_local $71)
@@ -4599,12 +4587,8 @@
)
(br $switch$24)
)
- (drop
- (i32.load offset=4
- (tee_local $1
- (get_local $18)
- )
- )
+ (set_local $1
+ (get_local $18)
)
(i32.store
(get_local $72)
diff --git a/test/passes/vacuum.txt b/test/passes/vacuum.txt
index 1adcc3e6f..f64db152f 100644
--- a/test/passes/vacuum.txt
+++ b/test/passes/vacuum.txt
@@ -42,16 +42,10 @@
)
(func $binary (type $2) (result f32)
(drop
- (f32.add
- (unreachable)
- (f32.const 3)
- )
+ (unreachable)
)
(drop
- (f32.add
- (f32.const 4)
- (unreachable)
- )
+ (unreachable)
)
(f32.add
(unreachable)
@@ -64,25 +58,13 @@
)
(func $select (type $3) (result i32)
(drop
- (select
- (unreachable)
- (i32.const 4)
- (i32.const 5)
- )
+ (unreachable)
)
(drop
- (select
- (i32.const 6)
- (unreachable)
- (i32.const 7)
- )
+ (unreachable)
)
(drop
- (select
- (i32.const 8)
- (i32.const 9)
- (unreachable)
- )
+ (unreachable)
)
(select
(unreachable)
@@ -178,4 +160,21 @@
)
)
)
+ (func $drop-silly (type $0)
+ (drop
+ (call_import $int)
+ )
+ (drop
+ (call_import $int)
+ )
+ (drop
+ (call_import $int)
+ )
+ (drop
+ (i32.add
+ (call_import $int)
+ (call_import $int)
+ )
+ )
+ )
)
diff --git a/test/passes/vacuum.wast b/test/passes/vacuum.wast
index 3630512b4..9da5fe6bc 100644
--- a/test/passes/vacuum.wast
+++ b/test/passes/vacuum.wast
@@ -314,4 +314,44 @@
)
)
)
+ (func $drop-silly
+ (drop
+ (i32.eqz
+ (i32.eqz
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (i32.eqz
+ (i32.eqz
+ (call_import $int)
+ )
+ )
+ )
+ (drop
+ (i32.add
+ (i32.const 2)
+ (i32.const 3)
+ )
+ )
+ (drop
+ (i32.add
+ (i32.const 4)
+ (call_import $int)
+ )
+ )
+ (drop
+ (i32.add
+ (call_import $int)
+ (i32.const 5)
+ )
+ )
+ (drop
+ (i32.add
+ (call_import $int)
+ (call_import $int)
+ )
+ )
+ )
)
diff --git a/test/unit.fromasm b/test/unit.fromasm
index c6e11e0ef..42b67a72c 100644
--- a/test/unit.fromasm
+++ b/test/unit.fromasm
@@ -109,14 +109,10 @@
(get_local $0)
)
)
- (drop
- (f64.convert_s/i32
- (tee_local $2
- (call_import $f64-to-int
- (f64.promote/f32
- (get_local $1)
- )
- )
+ (set_local $2
+ (call_import $f64-to-int
+ (f64.promote/f32
+ (get_local $1)
)
)
)
@@ -538,8 +534,10 @@
(call $phi)
)
(func $useSetGlobal (result i32)
- (set_global $Int
- (i32.const 10)
+ (drop
+ (set_global $Int
+ (i32.const 10)
+ )
)
(set_global $Int
(i32.const 20)
diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise
index 2715b551b..634356f9f 100644
--- a/test/unit.fromasm.imprecise
+++ b/test/unit.fromasm.imprecise
@@ -98,13 +98,9 @@
(func $conversions
(local $0 f32)
(local $1 i32)
- (drop
- (f64.convert_s/i32
- (tee_local $1
- (i32.trunc_s/f32
- (get_local $0)
- )
- )
+ (set_local $1
+ (i32.trunc_s/f32
+ (get_local $0)
)
)
)
@@ -519,8 +515,10 @@
(call $phi)
)
(func $useSetGlobal (result i32)
- (set_global $Int
- (i32.const 10)
+ (drop
+ (set_global $Int
+ (i32.const 10)
+ )
)
(set_global $Int
(i32.const 20)