diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/iteration.h | 24 | ||||
-rw-r--r-- | src/passes/CodeFolding.cpp | 11 |
2 files changed, 35 insertions, 0 deletions
diff --git a/src/ir/iteration.h b/src/ir/iteration.h index 289e5fa01..fd275f749 100644 --- a/src/ir/iteration.h +++ b/src/ir/iteration.h @@ -82,6 +82,30 @@ public: Iterator end() const { return Iterator(*this, children.size()); } }; +// Returns true if the current expression contains a certain kind of expression, +// within the given depth of BFS. If depth is -1, this searches all children. +template<typename T> bool containsChild(Expression* parent, int depth = -1) { + std::vector<Expression*> exprs; + std::vector<Expression*> nextExprs; + exprs.push_back(parent); + while (!exprs.empty() && depth > 0) { + for (auto* expr : exprs) { + for (auto* child : ChildIterator(expr)) { + if (child->is<T>()) { + return true; + } + nextExprs.push_back(child); + } + } + exprs.swap(nextExprs); + nextExprs.clear(); + if (depth > 0) { + depth--; + } + } + return false; +} + } // namespace wasm #endif // wasm_ir_iteration_h diff --git a/src/passes/CodeFolding.cpp b/src/passes/CodeFolding.cpp index e4d24e33d..70a357bbf 100644 --- a/src/passes/CodeFolding.cpp +++ b/src/passes/CodeFolding.cpp @@ -59,6 +59,7 @@ #include "ir/branch-utils.h" #include "ir/effects.h" +#include "ir/find_all.h" #include "ir/label-utils.h" #include "ir/utils.h" #include "pass.h" @@ -154,6 +155,8 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> { unoptimizables.insert(curr->default_); } + void visitBrOnExn(BrOnExn* curr) { unoptimizables.insert(curr->name); } + void visitUnreachable(Unreachable* curr) { // we can only optimize if we are at the end of the parent block if (!controlFlowStack.empty()) { @@ -301,6 +304,14 @@ private: // anything exiting that is in all targets is something bad return false; } + // Currently pop instructions are only used for exnref.pop, which is a + // pseudo instruction following a catch. We check if the current + // expression has a pop child. This can be overly conservative, because + // this can also exclude whole try-catches that contain a pop within them. + if (getModule()->features.hasExceptionHandling() && + !FindAll<Pop>(item).list.empty()) { + return false; + } } return true; } |