summaryrefslogtreecommitdiff
path: root/src/passes/DeadCodeElimination.cpp
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-05-02 13:46:53 -0700
committerGitHub <noreply@github.com>2017-05-02 13:46:53 -0700
commit5de55af88eaac818f86eaaec3f686eaede01397e (patch)
treeed896c1336272efa7e191e3675f883ad85ae3a6f /src/passes/DeadCodeElimination.cpp
parent1f1018564c472b75335bf4bddbf65cfebb226fb0 (diff)
downloadbinaryen-5de55af88eaac818f86eaaec3f686eaede01397e.tar.gz
binaryen-5de55af88eaac818f86eaaec3f686eaede01397e.tar.bz2
binaryen-5de55af88eaac818f86eaaec3f686eaede01397e.zip
improve dce to handle more cases of nested unreachable code (#989)
* improve dce to handle more cases of nested unreachable code, in particular, when the child is unreachable in type but not an actual Unreachable node, e.g. if it's a br. in that case, we just need to verify that the br is not to us where we are a block or loop * handle unreachable switch conditions in dce * handle dce of br condition which is unreachable, and host arguments * handle dce of block i32 etc. which is actually unreachable
Diffstat (limited to 'src/passes/DeadCodeElimination.cpp')
-rw-r--r--src/passes/DeadCodeElimination.cpp48
1 files changed, 41 insertions, 7 deletions
diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp
index 41012fccb..33a52a09a 100644
--- a/src/passes/DeadCodeElimination.cpp
+++ b/src/passes/DeadCodeElimination.cpp
@@ -51,12 +51,20 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>>
std::set<Name> reachableBreaks;
void addBreak(Name name) {
- assert(reachable);
- reachableBreaks.insert(name);
+ // we normally have already reduced unreachable code into (unreachable)
+ // nodes, so we would not get to this function at all anyhow, the breaking
+ // instruction itself would be removed. However, an exception are things
+ // like (block i32 (call $x) (unreachable)) , which has type i32
+ // despite not being exited.
+ // TODO: optimize such cases
+ if (reachable) {
+ reachableBreaks.insert(name);
+ }
}
- bool isDead(Expression* curr) {
- return curr && curr->is<Unreachable>();
+ // if a child is unreachable, we can replace ourselves with it
+ bool isDead(Expression* child) {
+ return child && child->type == unreachable;
}
// things that stop control flow
@@ -67,6 +75,19 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>>
replaceCurrent(curr->value);
return;
}
+ if (isDead(curr->condition)) {
+ if (curr->value) {
+ auto* block = getModule()->allocator.alloc<Block>();
+ block->list.resize(2);
+ block->list[0] = drop(curr->value);
+ block->list[1] = curr->condition;
+ block->finalize();
+ replaceCurrent(block);
+ } else {
+ replaceCurrent(curr->condition);
+ }
+ return;
+ }
addBreak(curr->name);
if (!curr->condition) {
reachable = false;
@@ -78,6 +99,19 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>>
replaceCurrent(curr->value);
return;
}
+ if (isDead(curr->condition)) {
+ if (curr->value) {
+ auto* block = getModule()->allocator.alloc<Block>();
+ block->list.resize(2);
+ block->list[0] = drop(curr->value);
+ block->list[1] = curr->condition;
+ block->finalize();
+ replaceCurrent(block);
+ } else {
+ replaceCurrent(curr->condition);
+ }
+ return;
+ }
for (auto target : curr->targets) {
addBreak(target);
}
@@ -137,7 +171,7 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>>
reachable = reachable || reachableBreaks.count(curr->name);
reachableBreaks.erase(curr->name);
}
- if (curr->list.size() == 1 && isDead(curr->list[0])) {
+ if (curr->list.size() == 1 && isDead(curr->list[0]) && !BreakSeeker::has(curr->list[0], curr->name)) {
replaceCurrent(curr->list[0]);
}
}
@@ -146,7 +180,7 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>>
if (curr->name.is()) {
reachableBreaks.erase(curr->name);
}
- if (isDead(curr->body)) {
+ if (isDead(curr->body) && !BreakSeeker::has(curr->body, curr->name)) {
replaceCurrent(curr->body);
return;
}
@@ -360,7 +394,7 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>>
}
void visitHost(Host* curr) {
- // TODO
+ handleCall(curr);
}
void visitFunction(Function* curr) {