diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-09-08 17:20:23 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-09-09 11:16:54 -0700 |
commit | 1775473f735f40412899676469f3d7e8fbba93dc (patch) | |
tree | 68df0944925eeecd08ec4d78a677c9bb8faf3272 /src/ast_utils.h | |
parent | 2065ecbe1ad951dc7263f76040b085019423ada9 (diff) | |
download | binaryen-1775473f735f40412899676469f3d7e8fbba93dc.tar.gz binaryen-1775473f735f40412899676469f3d7e8fbba93dc.tar.bz2 binaryen-1775473f735f40412899676469f3d7e8fbba93dc.zip |
optimize loop endings in RemoveUnusedBrs
* rotate an if near the end of a loop as it can let a break out flow naturally and be removable
* turn a br_if into an if it allows such an optimization in cases where it helps remove other structures
Diffstat (limited to 'src/ast_utils.h')
-rw-r--r-- | src/ast_utils.h | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h index 5deaa6a2c..6b76dd61d 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -27,7 +27,7 @@ namespace wasm { struct BreakSeeker : public PostWalker<BreakSeeker, Visitor<BreakSeeker>> { Name target; // look for this one XXX looking by name may fall prey to duplicate names - size_t found; + Index found; BreakSeeker(Name target) : target(target), found(false) {} @@ -47,6 +47,12 @@ struct BreakSeeker : public PostWalker<BreakSeeker, Visitor<BreakSeeker>> { breakSeeker.walk(tree); return breakSeeker.found > 0; } + + static Index count(Expression* tree, Name target) { + BreakSeeker breakSeeker(target); + breakSeeker.walk(tree); + return breakSeeker.found; + } }; // Finds all functions that are reachable via direct calls. @@ -391,6 +397,25 @@ struct ExpressionAnalyzer { return func->result != none; } + // Checks if a break is a simple - no condition, no value, just a plain branching + static bool isSimple(Break* curr) { + return !curr->condition && !curr->value; + } + + // Checks if an expression ends with a simple break, + // and returns a pointer to it if so. + // (It might also have other internal branches.) + static Expression* getEndingSimpleBreak(Expression* curr) { + if (auto* br = curr->dynCast<Break>()) { + if (isSimple(br)) return br; + return nullptr; + } + if (auto* block = curr->dynCast<Block>()) { + if (block->list.size() > 0) return getEndingSimpleBreak(block->list.back()); + } + return nullptr; + } + template<typename T> static bool flexibleEqual(Expression* left, Expression* right, T& comparer) { std::vector<Name> nameStack; |