diff options
-rw-r--r-- | src/passes/Vacuum.cpp | 25 | ||||
-rw-r--r-- | test/passes/vacuum.txt | 4 | ||||
-rw-r--r-- | test/passes/vacuum.wast | 9 | ||||
-rw-r--r-- | test/unit.fromasm | 6 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise | 6 |
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) |