summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast/type-updating.h13
-rw-r--r--src/passes/DeadCodeElimination.cpp6
-rw-r--r--test/passes/dce.txt53
-rw-r--r--test/passes/dce.wast26
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)
+ )
+ )
+ )
+)
+