diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-05-19 19:57:14 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-05-19 19:57:14 -0700 |
commit | 244da920eedafec42da4e91b83c09d0021a36a7f (patch) | |
tree | cb3afcad11617e0fc7100c85ecb083f24c88fdde /src | |
parent | 373cfe3a4364d657b04ea9c35e84324e9edec097 (diff) | |
download | binaryen-244da920eedafec42da4e91b83c09d0021a36a7f.tar.gz binaryen-244da920eedafec42da4e91b83c09d0021a36a7f.tar.bz2 binaryen-244da920eedafec42da4e91b83c09d0021a36a7f.zip |
notice only branches out in EffectAnalyzer, internal control flow can be ignored (#530)
Diffstat (limited to 'src')
-rw-r--r-- | src/ast_utils.h | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h index 96c6a9319..07db4806b 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -53,9 +53,11 @@ struct EffectAnalyzer : public PostWalker<EffectAnalyzer, Visitor<EffectAnalyzer EffectAnalyzer() {} EffectAnalyzer(Expression *ast) { walk(ast); + // if we are left with breaks, they are external + if (breakNames.size() > 0) branches = true; } - bool branches = false; + bool branches = false; // branches out of this expression bool calls = false; std::set<Index> localsRead; std::set<Index> localsWritten; @@ -101,9 +103,25 @@ struct EffectAnalyzer : public PostWalker<EffectAnalyzer, Visitor<EffectAnalyzer return hasAnything(); } - void visitIf(If *curr) { branches = true; } - void visitBreak(Break *curr) { branches = true; } - void visitSwitch(Switch *curr) { branches = true; } + std::set<Name> breakNames; + + void visitBreak(Break *curr) { + breakNames.insert(curr->name); + } + void visitSwitch(Switch *curr) { + for (auto name : curr->targets) { + breakNames.insert(name); + } + breakNames.insert(curr->default_); + } + void visitBlock(Block* curr) { + if (curr->name.is()) breakNames.erase(curr->name); // these were internal breaks + } + void visitLoop(Loop* curr) { + if (curr->in.is()) breakNames.erase(curr->in); // these were internal breaks + if (curr->out.is()) breakNames.erase(curr->out); // these were internal breaks + } + void visitCall(Call *curr) { calls = true; } void visitCallImport(CallImport *curr) { calls = true; } void visitCallIndirect(CallIndirect *curr) { calls = true; } |