summaryrefslogtreecommitdiff
path: root/src/passes
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes')
-rw-r--r--src/passes/DeadCodeElimination.cpp98
-rw-r--r--src/passes/InstrumentMemory.cpp1
-rw-r--r--src/passes/MergeBlocks.cpp27
-rw-r--r--src/passes/Precompute.cpp6
4 files changed, 63 insertions, 69 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
-
diff --git a/src/passes/InstrumentMemory.cpp b/src/passes/InstrumentMemory.cpp
index 536031064..d9a5a4316 100644
--- a/src/passes/InstrumentMemory.cpp
+++ b/src/passes/InstrumentMemory.cpp
@@ -66,6 +66,7 @@ namespace wasm {
Name load("load");
Name store("store");
+// TODO: Add support for atomicRMW/cmpxchg
struct InstrumentMemory : public WalkerPass<PostWalker<InstrumentMemory>> {
void visitLoad(Load* curr) {
diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp
index bc5fea6fb..455e54971 100644
--- a/src/passes/MergeBlocks.cpp
+++ b/src/passes/MergeBlocks.cpp
@@ -286,17 +286,27 @@ struct MergeBlocks : public WalkerPass<PostWalker<MergeBlocks>> {
void visitStore(Store* curr) {
optimize(curr, curr->value, optimize(curr, curr->ptr), &curr->ptr);
}
-
- void visitSelect(Select* curr) {
+ void visitAtomicRMW(AtomicRMW* curr) {
+ optimize(curr, curr->value, optimize(curr, curr->ptr), &curr->ptr);
+ }
+ void optimizeTernary(Expression* curr,
+ Expression*& first, Expression*& second, Expression*& third) {
// TODO: for now, just stop when we see any side effect. instead, we could
// check effects carefully for reordering
Block* outer = nullptr;
- if (EffectAnalyzer(getPassOptions(), curr->ifTrue).hasSideEffects()) return;
- outer = optimize(curr, curr->ifTrue, outer);
- if (EffectAnalyzer(getPassOptions(), curr->ifFalse).hasSideEffects()) return;
- outer = optimize(curr, curr->ifFalse, outer);
- if (EffectAnalyzer(getPassOptions(), curr->condition).hasSideEffects()) return;
- optimize(curr, curr->condition, outer);
+ if (EffectAnalyzer(getPassOptions(), first).hasSideEffects()) return;
+ outer = optimize(curr, first, outer);
+ if (EffectAnalyzer(getPassOptions(), second).hasSideEffects()) return;
+ outer = optimize(curr, second, outer);
+ if (EffectAnalyzer(getPassOptions(), third).hasSideEffects()) return;
+ optimize(curr, third, outer);
+ }
+ void visitAtomicCmpxchg(AtomicCmpxchg* curr) {
+ optimizeTernary(curr, curr->ptr, curr->expected, curr->replacement);
+ }
+
+ void visitSelect(Select* curr) {
+ optimizeTernary(curr, curr->ifTrue, curr->ifFalse, curr->condition);
}
void visitDrop(Drop* curr) {
@@ -344,4 +354,3 @@ Pass *createMergeBlocksPass() {
}
} // namespace wasm
-
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index 122501de9..c4702fdeb 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -67,6 +67,12 @@ public:
Flow visitStore(Store *curr) {
return Flow(NONSTANDALONE_FLOW);
}
+ Flow visitAtomicRMW(AtomicRMW *curr) {
+ return Flow(NONSTANDALONE_FLOW);
+ }
+ Flow visitAtomicCmpxchg(AtomicCmpxchg *curr) {
+ return Flow(NONSTANDALONE_FLOW);
+ }
Flow visitHost(Host *curr) {
return Flow(NONSTANDALONE_FLOW);
}