summaryrefslogtreecommitdiff
path: root/src/passes/DeadCodeElimination.cpp
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2017-07-21 08:46:23 -0700
committerGitHub <noreply@github.com>2017-07-21 08:46:23 -0700
commitab8dbae1d1a27e4de24fd9ee09d45785a414922d (patch)
treeac337117d973464a16d597fc7a5c29550a93a489 /src/passes/DeadCodeElimination.cpp
parentda680fdbcb7eaad1c692369c7c826fc02b00c877 (diff)
downloadbinaryen-ab8dbae1d1a27e4de24fd9ee09d45785a414922d.tar.gz
binaryen-ab8dbae1d1a27e4de24fd9ee09d45785a414922d.tar.bz2
binaryen-ab8dbae1d1a27e4de24fd9ee09d45785a414922d.zip
Optimizer support for atomic instructions (#1094)
* Teach EffectAnalyzer not to reorder atomics wrt other memory operations. * Teach EffectAnalyzer not to reorder host operations with memory operations * Teach various passes about the operands of AtomicRMW and AtomicCmpxchg * Factor out some functions in DeadCodeElimination and MergeBlocks
Diffstat (limited to 'src/passes/DeadCodeElimination.cpp')
-rw-r--r--src/passes/DeadCodeElimination.cpp98
1 files changed, 38 insertions, 60 deletions
diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp
index 321bc0f9a..5017569aa 100644
--- a/src/passes/DeadCodeElimination.cpp
+++ b/src/passes/DeadCodeElimination.cpp
@@ -28,6 +28,7 @@
// have no side effects.
//
+#include <vector>
#include <wasm.h>
#include <pass.h>
#include <wasm-builder.h>
@@ -321,84 +322,62 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>>
}
}
- void visitSetLocal(SetLocal* curr) {
- if (isUnreachable(curr->value)) {
- replaceCurrent(curr->value);
+ // Append the reachable operands of the current node to a block, and replace
+ // it with the block
+ void blockifyReachableOperands(std::vector<Expression*>&& list, WasmType type) {
+ for (size_t i = 0; i < list.size(); ++i) {
+ auto* elem = list[i];
+ if (isUnreachable(elem)) {
+ auto* replacement = elem;
+ if (i > 0) {
+ auto* block = getModule()->allocator.alloc<Block>();
+ for (size_t j = 0; j < i; ++j) {
+ block->list.push_back(drop(list[j]));
+ }
+ block->list.push_back(list[i]);
+ block->finalize(type);
+ replacement = block;
+ }
+ replaceCurrent(replacement);
+ return;
+ }
}
}
+ void visitSetLocal(SetLocal* curr) {
+ blockifyReachableOperands({ curr->value }, curr->type);
+ }
+
void visitLoad(Load* curr) {
- if (isUnreachable(curr->ptr)) {
- replaceCurrent(curr->ptr);
- }
+ blockifyReachableOperands({ curr->ptr}, curr->type);
}
void visitStore(Store* curr) {
- if (isUnreachable(curr->ptr)) {
- replaceCurrent(curr->ptr);
- return;
- }
- if (isUnreachable(curr->value)) {
- auto* block = getModule()->allocator.alloc<Block>();
- block->list.resize(2);
- block->list[0] = drop(curr->ptr);
- block->list[1] = curr->value;
- block->finalize(curr->type);
- replaceCurrent(block);
- }
+ blockifyReachableOperands({ curr->ptr, curr->value }, curr->type);
+ }
+
+ void visitAtomicRMW(AtomicRMW* curr) {
+ blockifyReachableOperands({ curr->ptr, curr->value }, curr->type);
+ }
+
+ void visitAtomicCmpxchg(AtomicCmpxchg* curr) {
+ blockifyReachableOperands({ curr->ptr, curr->expected, curr->replacement }, curr->type);
}
void visitUnary(Unary* curr) {
- if (isUnreachable(curr->value)) {
- replaceCurrent(curr->value);
- }
+ blockifyReachableOperands({ curr->value }, curr->type);
}
void visitBinary(Binary* curr) {
- if (isUnreachable(curr->left)) {
- replaceCurrent(curr->left);
- return;
- }
- if (isUnreachable(curr->right)) {
- auto* block = getModule()->allocator.alloc<Block>();
- block->list.resize(2);
- block->list[0] = drop(curr->left);
- block->list[1] = curr->right;
- block->finalize(curr->type);
- replaceCurrent(block);
- }
+ blockifyReachableOperands({ curr->left, curr->right}, curr->type);
}
void visitSelect(Select* curr) {
- if (isUnreachable(curr->ifTrue)) {
- replaceCurrent(curr->ifTrue);
- return;
- }
- if (isUnreachable(curr->ifFalse)) {
- auto* block = getModule()->allocator.alloc<Block>();
- block->list.resize(2);
- block->list[0] = drop(curr->ifTrue);
- block->list[1] = curr->ifFalse;
- block->finalize(curr->type);
- replaceCurrent(block);
- return;
- }
- if (isUnreachable(curr->condition)) {
- auto* block = getModule()->allocator.alloc<Block>();
- block->list.resize(3);
- block->list[0] = drop(curr->ifTrue);
- block->list[1] = drop(curr->ifFalse);
- block->list[2] = curr->condition;
- block->finalize(curr->type);
- replaceCurrent(block);
- return;
- }
+ blockifyReachableOperands({ curr->ifTrue, curr->ifFalse, curr->condition}, curr->type);
}
void visitDrop(Drop* curr) {
- if (isUnreachable(curr->value)) {
- replaceCurrent(curr->value);
- }
+ blockifyReachableOperands({ curr->value }, curr->type);
}
void visitHost(Host* curr) {
@@ -415,4 +394,3 @@ Pass *createDeadCodeEliminationPass() {
}
} // namespace wasm
-