summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-08-16 18:24:35 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-09-07 09:55:00 -0700
commit15a264ee9c67816693d92a5454ad7469f1f255ff (patch)
tree1df8a7f611e6f3a3e370a37598cac1497195c21f /src
parentfbd3c89390220d304a93640664f7b8351523ca99 (diff)
downloadbinaryen-15a264ee9c67816693d92a5454ad7469f1f255ff.tar.gz
binaryen-15a264ee9c67816693d92a5454ad7469f1f255ff.tar.bz2
binaryen-15a264ee9c67816693d92a5454ad7469f1f255ff.zip
add an ExpressionStack traversal
Diffstat (limited to 'src')
-rw-r--r--src/passes/Vacuum.cpp21
-rw-r--r--src/wasm-traversal.h43
2 files changed, 44 insertions, 20 deletions
diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp
index 1b0887181..bb005e36c 100644
--- a/src/passes/Vacuum.cpp
+++ b/src/passes/Vacuum.cpp
@@ -25,13 +25,11 @@
namespace wasm {
-struct Vacuum : public WalkerPass<PostWalker<Vacuum, Visitor<Vacuum>>> {
+struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum, Visitor<Vacuum>>> {
bool isFunctionParallel() override { return true; }
Pass* create() override { return new Vacuum; }
- std::vector<Expression*> expressionStack;
-
// returns nullptr if curr is dead, curr if it must stay as is, or another node if it can be replaced
Expression* optimize(Expression* curr, bool resultUsed) {
while (1) {
@@ -206,23 +204,6 @@ 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);
- }
-
void visitFunction(Function* curr) {
auto* optimized = optimize(curr->body, curr->result != none);
if (optimized) {
diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h
index b69db1ea2..a345a7f4b 100644
--- a/src/wasm-traversal.h
+++ b/src/wasm-traversal.h
@@ -508,6 +508,49 @@ struct ControlFlowWalker : public PostWalker<SubType, VisitorType> {
}
};
+// Traversal with an expression stack.
+
+template<typename SubType, typename VisitorType>
+struct ExpressionStackWalker : public PostWalker<SubType, VisitorType> {
+ ExpressionStackWalker() {}
+
+ std::vector<Expression*> expressionStack;
+
+ // Uses the control flow stack to find the target of a break to a name
+ Expression* findBreakTarget(Name name) {
+ assert(!expressionStack.empty());
+ Index i = expressionStack.size() - 1;
+ while (1) {
+ auto* curr = expressionStack[i];
+ if (Block* block = curr->template dynCast<Block>()) {
+ if (name == block->name) return curr;
+ } else if (Loop* loop = curr->template dynCast<Loop>()) {
+ if (name == loop->name) return curr;
+ } else {
+ WASM_UNREACHABLE();
+ }
+ if (i == 0) return nullptr;
+ i--;
+ }
+ }
+
+ static void doPreVisit(SubType* self, Expression** currp) {
+ self->expressionStack.push_back(*currp);
+ }
+
+ static void doPostVisit(SubType* self, Expression** currp) {
+ self->expressionStack.pop_back();
+ }
+
+ static void scan(SubType* self, Expression** currp) {
+ self->pushTask(SubType::doPostVisit, currp);
+
+ PostWalker<SubType, VisitorType>::scan(self, currp);
+
+ self->pushTask(SubType::doPreVisit, currp);
+ }
+};
+
// Traversal in the order of execution. This is quick and simple, but
// does not provide the same comprehensive information that a full
// conversion to basic blocks would. What it does give is a quick