summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/Vacuum.cpp25
-rw-r--r--test/passes/vacuum.txt4
-rw-r--r--test/passes/vacuum.wast9
-rw-r--r--test/unit.fromasm6
-rw-r--r--test/unit.fromasm.imprecise6
5 files changed, 39 insertions, 11 deletions
diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp
index 53b9eb397..592f5a063 100644
--- a/src/passes/Vacuum.cpp
+++ b/src/passes/Vacuum.cpp
@@ -137,13 +137,12 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum, Visitor<Vacuum>>
void visitBlock(Block *curr) {
// compress out nops and other dead code
- bool resultUsed = ExpressionAnalyzer::isResultUsed(expressionStack, getFunction());
int skip = 0;
auto& list = curr->list;
size_t size = list.size();
bool needResize = false;
for (size_t z = 0; z < size; z++) {
- auto* optimized = optimize(list[z], z == size - 1 && resultUsed);
+ auto* optimized = optimize(list[z], z == size - 1 && isConcreteWasmType(curr->type));
if (!optimized) {
skip++;
needResize = true;
@@ -170,7 +169,7 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum, Visitor<Vacuum>>
if (!curr->name.is()) {
if (list.size() == 1) {
// just one element. replace the block, either with it or with a nop if it's not needed
- if (resultUsed || EffectAnalyzer(list[0]).hasSideEffects()) {
+ if (isConcreteWasmType(curr->type) || EffectAnalyzer(list[0]).hasSideEffects()) {
replaceCurrent(list[0]);
} else {
ExpressionManipulator::nop(curr);
@@ -218,6 +217,26 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum, Visitor<Vacuum>>
replaceCurrent(set);
return;
}
+ // if we are dropping a block's return value, we might be able to remove it entirely
+ if (auto* block = curr->value->dynCast<Block>()) {
+ auto* last = block->list.back();
+ if (isConcreteWasmType(last->type)) {
+ assert(block->type == last->type);
+ block->list.back() = last = optimize(last, false);
+ if (!last) {
+ block->list.pop_back();
+ // we don't need the drop anymore, let's see what we have left in the block
+ if (block->list.size() > 1) {
+ replaceCurrent(block);
+ } else if (block->list.size() == 1) {
+ replaceCurrent(block->list[0]);
+ } else {
+ 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)) {
diff --git a/test/passes/vacuum.txt b/test/passes/vacuum.txt
index f64db152f..2d274a6d7 100644
--- a/test/passes/vacuum.txt
+++ b/test/passes/vacuum.txt
@@ -7,6 +7,7 @@
(type $4 (func (param i32 f64 i32 i32)))
(type $FUNCSIG$i (func (result i32)))
(import "env" "int" (func $int (result i32)))
+ (global $Int i32 (i32.const 0))
(func $b (type $0)
(nop)
)
@@ -177,4 +178,7 @@
)
)
)
+ (func $drop-get-global (type $0)
+ (call $drop-get-global)
+ )
)
diff --git a/test/passes/vacuum.wast b/test/passes/vacuum.wast
index 9da5fe6bc..5d443380f 100644
--- a/test/passes/vacuum.wast
+++ b/test/passes/vacuum.wast
@@ -6,6 +6,7 @@
(type $3 (func (result i32)))
(type $4 (func (param i32 f64 i32 i32)))
(import $int "env" "int" (result i32))
+ (global $Int i32 (i32.const 0))
(func $b (type $0)
(drop
(i32.const 50)
@@ -354,4 +355,12 @@
)
)
)
+ (func $drop-get-global
+ (drop
+ (block
+ (call $drop-get-global)
+ (get_global $Int) ;; this is not needed due to the block being drop'd, but make sure the call is not then dropped either
+ )
+ )
+ )
)
diff --git a/test/unit.fromasm b/test/unit.fromasm
index 42b67a72c..a1103f064 100644
--- a/test/unit.fromasm
+++ b/test/unit.fromasm
@@ -534,10 +534,8 @@
(call $phi)
)
(func $useSetGlobal (result i32)
- (drop
- (set_global $Int
- (i32.const 10)
- )
+ (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 634356f9f..db854cac0 100644
--- a/test/unit.fromasm.imprecise
+++ b/test/unit.fromasm.imprecise
@@ -515,10 +515,8 @@
(call $phi)
)
(func $useSetGlobal (result i32)
- (drop
- (set_global $Int
- (i32.const 10)
- )
+ (set_global $Int
+ (i32.const 10)
)
(set_global $Int
(i32.const 20)