diff options
author | Alon Zakai <alonzakai@gmail.com> | 2019-04-16 10:00:19 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-16 10:00:19 -0700 |
commit | 324238cc44e51c65637d29a938c435248d384154 (patch) | |
tree | fcd7a35442c720385ff5746a3de83a7123e04be8 /src/passes/Flatten.cpp | |
parent | cb2d63586c08a3dd194d2b733ceb3f5051c081f8 (diff) | |
download | binaryen-324238cc44e51c65637d29a938c435248d384154.tar.gz binaryen-324238cc44e51c65637d29a938c435248d384154.tar.bz2 binaryen-324238cc44e51c65637d29a938c435248d384154.zip |
Verify flat IR where it is expected, and give a nice error (#2009)
Fixes #2007 #2008
Diffstat (limited to 'src/passes/Flatten.cpp')
-rw-r--r-- | src/passes/Flatten.cpp | 43 |
1 files changed, 4 insertions, 39 deletions
diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp index 61fc60b2b..df6be947d 100644 --- a/src/passes/Flatten.cpp +++ b/src/passes/Flatten.cpp @@ -15,39 +15,7 @@ */ // -// Flattens code, removing nesting.e.g. an if return value would be -// converted to a local -// -// (i32.add -// (if (..condition..) -// (..if true..) -// (..if false..) -// ) -// (i32.const 1) -// ) -// => -// (if (..condition..) -// (local.set $temp -// (..if true..) -// ) -// (local.set $temp -// (..if false..) -// ) -// ) -// (i32.add -// (local.get $temp) -// (i32.const 1) -// ) -// -// Formally, this pass flattens in the precise sense of -// making the AST have these properties: -// -// 1. The operands of an instruction must be a local.get or a const. -// anything else is written to a local earlier. -// 2. Disallow block, loop, and if return values, i.e., do not use -// control flow to pass around values. -// 3. Disallow local.tee, setting a local is always done in a local.set -// on a non-nested-expression location. +// Flattens code into "Flat IR" form. See ir/flat.h. // #include <wasm.h> @@ -55,6 +23,7 @@ #include <wasm-builder.h> #include <ir/branch-utils.h> #include <ir/effects.h> +#include <ir/flat.h> #include <ir/utils.h> namespace wasm { @@ -89,7 +58,7 @@ struct Flatten : public WalkerPass<ExpressionStackWalker<Flatten, UnifiedExpress std::vector<Expression*> ourPreludes; Builder builder(*getModule()); - if (isControlFlowStructure(curr)) { + if (Flat::isControlFlowStructure(curr)) { // handle control flow explicitly. our children do not have control flow, // but they do have preludes which we need to set up in the right place assert(preludes.find(curr) == preludes.end()); // no one should have given us preludes, they are on the children @@ -275,7 +244,7 @@ struct Flatten : public WalkerPass<ExpressionStackWalker<Flatten, UnifiedExpress // next, finish up: migrate our preludes if we can if (!ourPreludes.empty()) { auto* parent = getParent(); - if (parent && !isControlFlowStructure(parent)) { + if (parent && !Flat::isControlFlowStructure(parent)) { auto& parentPreludes = preludes[parent]; for (auto* prelude : ourPreludes) { parentPreludes.push_back(prelude); @@ -298,10 +267,6 @@ struct Flatten : public WalkerPass<ExpressionStackWalker<Flatten, UnifiedExpress } private: - bool isControlFlowStructure(Expression* curr) { - return curr->is<Block>() || curr->is<If>() || curr->is<Loop>(); - } - // gets an expression, either by itself, or in a block with its // preludes (which we use up) before it Expression* getPreludesWithExpression(Expression* curr) { |