diff options
Diffstat (limited to 'src/passes/Vacuum.cpp')
-rw-r--r-- | src/passes/Vacuum.cpp | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp index f9aba7051..10d04f160 100644 --- a/src/passes/Vacuum.cpp +++ b/src/passes/Vacuum.cpp @@ -28,14 +28,24 @@ namespace wasm { struct Vacuum : public WalkerPass<PostWalker<Vacuum, Visitor<Vacuum>>> { bool isFunctionParallel() { return true; } + std::vector<Expression*> expressionStack; + + bool isDead(Expression* curr, bool resultMayBeUsed) { + if (curr->is<Nop>()) return true; + // dead get_locals may be generated from coalesce-locals + if (curr->is<GetLocal>() && (!resultMayBeUsed || !ExpressionAnalyzer::isResultUsed(expressionStack, getFunction()))) return true; + // TODO: more dead code + return false; + } + void visitBlock(Block *curr) { - // compress out nops + // compress out nops and other dead code int skip = 0; auto& list = curr->list; size_t size = list.size(); bool needResize = false; for (size_t z = 0; z < size; z++) { - if (list[z]->is<Nop>()) { + if (isDead(list[z], z == size - 1)) { skip++; needResize = true; } else { @@ -82,6 +92,23 @@ struct Vacuum : public WalkerPass<PostWalker<Vacuum, Visitor<Vacuum>>> { } } } + + static void visitPre(Vacuum* self, Expression** currp) { + self->expressionStack.push_back(*currp); + } + + static void visitPost(Vacuum* self, Expression** currp) { + self->expressionStack.pop_back(); + } + + // override scan to add a pre and a post check task to all nodes + static void scan(Vacuum* self, Expression** currp) { + self->pushTask(visitPost, currp); + + WalkerPass<PostWalker<Vacuum, Visitor<Vacuum>>>::scan(self, currp); + + self->pushTask(visitPre, currp); + } }; static RegisterPass<Vacuum> registerPass("vacuum", "removes obviously unneeded code"); |