diff options
Diffstat (limited to 'src/passes')
-rw-r--r-- | src/passes/DeadCodeElimination.cpp | 98 | ||||
-rw-r--r-- | src/passes/InstrumentMemory.cpp | 1 | ||||
-rw-r--r-- | src/passes/MergeBlocks.cpp | 27 | ||||
-rw-r--r-- | src/passes/Precompute.cpp | 6 |
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); } |