From ab8dbae1d1a27e4de24fd9ee09d45785a414922d Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Fri, 21 Jul 2017 08:46:23 -0700 Subject: 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 --- src/passes/DeadCodeElimination.cpp | 98 +++++++++++++++----------------------- 1 file changed, 38 insertions(+), 60 deletions(-) (limited to 'src/passes/DeadCodeElimination.cpp') 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 #include #include #include @@ -321,84 +322,62 @@ struct DeadCodeElimination : public WalkerPass> } } - 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&& 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(); + 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->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->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->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->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 - -- cgit v1.2.3