summaryrefslogtreecommitdiff
path: root/src/ast_utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast_utils.h')
-rw-r--r--src/ast_utils.h27
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;