diff options
Diffstat (limited to 'src/tools/wasm-reduce.cpp')
-rw-r--r-- | src/tools/wasm-reduce.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp index 4a941156d..6b8d93f97 100644 --- a/src/tools/wasm-reduce.cpp +++ b/src/tools/wasm-reduce.cpp @@ -34,6 +34,7 @@ #include "support/timing.h" #include "wasm-io.h" #include "wasm-builder.h" +#include "ir/branch-utils.h" #include "ir/literal-utils.h" #include "wasm-validator.h" #ifdef _WIN32 @@ -417,6 +418,8 @@ struct Reducer : public WalkerPass<PostWalker<Reducer, UnifiedExpressionVisitor< return; } } + if (tryToReplaceCurrent(iff->ifTrue)) return; + if (iff->ifFalse && tryToReplaceCurrent(iff->ifFalse)) return; handleCondition(iff->condition); } else if (auto* br = curr->dynCast<Break>()) { handleCondition(br->condition); @@ -444,6 +447,55 @@ struct Reducer : public WalkerPass<PostWalker<Reducer, UnifiedExpressionVisitor< } else if (auto* call = curr->dynCast<CallIndirect>()) { if (tryToReplaceCurrent(call->target)) return; handleCall(call); + } else if (auto* block = curr->dynCast<Block>()) { + if (!shouldTryToReduce()) return; + // replace a singleton + auto& list = block->list; + if (list.size() == 1 && !BranchUtils::BranchSeeker::hasNamed(block, block->name)) { + if (tryToReplaceCurrent(block->list[0])) return; + } + // try to get rid of nops + Index i = 0; + while (list.size() > 1 && i < list.size()) { + auto* curr = list[i]; + if (curr->is<Nop>() && shouldTryToReduce()) { + // try to remove it + for (Index j = i; j < list.size() - 1; j++) { + list[j] = list[j + 1]; + } + list.resize(list.size() - 1); + if (writeAndTestReduction()) { + std::cerr << "| block-nop removed\n"; + noteReduction(); + return; + } + list.resize(list.size() + 1); + // we failed; undo + for (Index j = list.size() - 1; j > i; j--) { + list[j] = list[j - 1]; + } + list[i] = curr; + } + i++; + } + } else if (auto* loop = curr->dynCast<Loop>()) { + if (shouldTryToReduce() && !BranchUtils::BranchSeeker::hasNamed(loop, loop->name)) { + tryToReplaceCurrent(loop->body); + } + } else if (auto* rmw = curr->dynCast<AtomicRMW>()) { + if (tryToReplaceCurrent(rmw->ptr)) return; + if (tryToReplaceCurrent(rmw->value)) return; + } else if (auto* cmpx = curr->dynCast<AtomicCmpxchg>()) { + if (tryToReplaceCurrent(cmpx->ptr)) return; + if (tryToReplaceCurrent(cmpx->expected)) return; + if (tryToReplaceCurrent(cmpx->replacement)) return; + } else if (auto* wait = curr->dynCast<AtomicWait>()) { + if (tryToReplaceCurrent(wait->ptr)) return; + if (tryToReplaceCurrent(wait->expected)) return; + if (tryToReplaceCurrent(wait->timeout)) return; + } else if (auto* wake = curr->dynCast<AtomicWake>()) { + if (tryToReplaceCurrent(wake->ptr)) return; + if (tryToReplaceCurrent(wake->wakeCount)) return; } } |