diff options
-rw-r--r-- | src/ast/type-updating.h | 13 | ||||
-rw-r--r-- | src/passes/DeadCodeElimination.cpp | 6 | ||||
-rw-r--r-- | test/passes/dce.txt | 53 | ||||
-rw-r--r-- | test/passes/dce.wast | 26 |
4 files changed, 78 insertions, 20 deletions
diff --git a/src/ast/type-updating.h b/src/ast/type-updating.h index 8063b3e59..c5f1d5344 100644 --- a/src/ast/type-updating.h +++ b/src/ast/type-updating.h @@ -266,6 +266,19 @@ struct TypeUpdater : public ExpressionStackWalker<TypeUpdater, UnifiedExpression } } } + + // efficiently update the type of an if, given the data we know. this + // can remove a concrete type and turn the if unreachable when it is + // unreachable + void maybeUpdateTypeToUnreachable(If* curr) { + if (!isConcreteWasmType(curr->type)) { + return; // nothing concrete to change to unreachable + } + curr->finalize(); + if (curr->type == unreachable) { + propagateTypesUp(curr); + } + } }; } // namespace wasm diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp index e5673a0cc..48fc4a91c 100644 --- a/src/passes/DeadCodeElimination.cpp +++ b/src/passes/DeadCodeElimination.cpp @@ -216,7 +216,7 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>> replaceCurrent(curr->condition); } // the if may have had a type, but can now be unreachable, which allows more reduction outside - curr->finalize(); + typeUpdater.maybeUpdateTypeToUnreachable(curr); } static void scan(DeadCodeElimination* self, Expression** currp) { @@ -351,6 +351,10 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>> blockifyReachableOperands({ curr->value }, curr->type); } + void visitSetGlobal(SetGlobal* curr) { + blockifyReachableOperands({ curr->value }, curr->type); + } + void visitLoad(Load* curr) { blockifyReachableOperands({ curr->ptr }, curr->type); } diff --git a/test/passes/dce.txt b/test/passes/dce.txt index d93e1251b..ec5343986 100644 --- a/test/passes/dce.txt +++ b/test/passes/dce.txt @@ -444,28 +444,19 @@ ) ) (func $replace-with-unreachable-affects-parent (type $5) (param $var$0 f32) (param $var$1 i64) - (block $top - (drop - (f32.load offset=4 - (block (result i32) - (drop - (i64.const 0) - ) - (if - (block $block (result i32) - (call $replace-with-unreachable-affects-parent - (f32.const 1) - (i64.const -15917430362925035) - ) - (i32.const 1) - ) - (unreachable) - (unreachable) - ) - ) + (drop + (i64.const 0) + ) + (if + (block $block (result i32) + (call $replace-with-unreachable-affects-parent + (f32.const 1) + (i64.const -15917430362925035) ) + (i32.const 1) ) (unreachable) + (unreachable) ) ) (func $replace-block-changes-later-when-if-goes (type $1) @@ -488,3 +479,27 @@ (i32.const 0) ) ) +(module + (type $0 (func)) + (global $global (mut f64) (f64.const 0)) + (memory $0 0) + (func $0 (type $0) + (if + (i32.const 0) + (unreachable) + (unreachable) + ) + ) +) +(module + (type $0 (func)) + (memory $0 0) + (func $0 (type $0) + (local $local f64) + (if + (i32.const 0) + (unreachable) + (unreachable) + ) + ) +) diff --git a/test/passes/dce.wast b/test/passes/dce.wast index 7a4816196..acabf6ca5 100644 --- a/test/passes/dce.wast +++ b/test/passes/dce.wast @@ -708,3 +708,29 @@ (i32.const 0) ) ) +;; if goes to unreachable, need to propagate that up to the set_global +(module + (global $global (mut f64) (f64.const 0)) + (func $0 + (set_global $global + (if (result f64) + (i32.const 0) + (unreachable) + (unreachable) + ) + ) + ) +) +(module + (func $0 + (local $local f64) + (set_local $local + (if (result f64) + (i32.const 0) + (unreachable) + (unreachable) + ) + ) + ) +) + |