diff options
author | Michael Bebenita <mbebenita@gmail.com> | 2016-01-11 20:51:27 -0800 |
---|---|---|
committer | Michael Bebenita <mbebenita@gmail.com> | 2016-01-13 20:09:10 -0800 |
commit | 7e3bdd00f9b390c36461291fa5b884ace55e82d6 (patch) | |
tree | d282aedbd7d08efdb1383ae22c4b2db6937bc713 | |
parent | ab3b76b29488ca8f85c39491c5ac96d6274fac7c (diff) | |
download | binaryen-7e3bdd00f9b390c36461291fa5b884ace55e82d6.tar.gz binaryen-7e3bdd00f9b390c36461291fa5b884ace55e82d6.tar.bz2 binaryen-7e3bdd00f9b390c36461291fa5b884ace55e82d6.zip |
A more generic compiler pass system.
-rw-r--r-- | src/pass.h | 18 | ||||
-rw-r--r-- | src/passes/LowerIfElse.cpp | 2 | ||||
-rw-r--r-- | src/passes/MergeBlocks.cpp | 2 | ||||
-rw-r--r-- | src/passes/RemoveImports.cpp | 2 | ||||
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 2 | ||||
-rw-r--r-- | src/passes/RemoveUnusedNames.cpp | 2 | ||||
-rw-r--r-- | src/passes/SimplifyLocals.cpp | 2 | ||||
-rw-r--r-- | src/wasm.h | 178 |
8 files changed, 112 insertions, 96 deletions
diff --git a/src/pass.h b/src/pass.h index d3f1d9edb..691583f2b 100644 --- a/src/pass.h +++ b/src/pass.h @@ -88,14 +88,24 @@ struct PassRunner { // // Core pass class // -class Pass : public WasmWalker { +class Pass { public: // Override this to perform preparation work before the pass runs virtual void prepare(PassRunner* runner, Module* module) {} + virtual void run(PassRunner* runner, Module* module) { abort(); } + virtual ~Pass() {} +}; - void run(PassRunner* runner, Module* module) { +// +// Core pass class that uses AST walking. This class can be parameterized by +// different types of AST walkers. +// +template <class WalkerType> +class WalkerPass : public Pass, public WalkerType { + public: + void run(PassRunner* runner, Module* module) override { prepare(runner, module); - startWalk(module); + WalkerType::startWalk(module); } }; @@ -104,7 +114,7 @@ class Pass : public WasmWalker { // e.g. through PassRunner::getLast // Handles names in a module, in particular adding names without duplicates -class NameManager : public Pass { +class NameManager : public WalkerPass<WasmWalker> { public: Name getUnique(std::string prefix); // TODO: getUniqueInFunction diff --git a/src/passes/LowerIfElse.cpp b/src/passes/LowerIfElse.cpp index 711f5469c..26ae321e6 100644 --- a/src/passes/LowerIfElse.cpp +++ b/src/passes/LowerIfElse.cpp @@ -32,7 +32,7 @@ namespace wasm { -struct LowerIfElse : public Pass { +struct LowerIfElse : public WalkerPass<WasmWalker> { MixedArena* allocator; std::unique_ptr<NameManager> namer; diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp index 3d7afc4cb..5543c407b 100644 --- a/src/passes/MergeBlocks.cpp +++ b/src/passes/MergeBlocks.cpp @@ -23,7 +23,7 @@ namespace wasm { -struct MergeBlocks : public Pass { +struct MergeBlocks : public WalkerPass<WasmWalker> { void visitBlock(Block *curr) override { bool more = true; while (more) { diff --git a/src/passes/RemoveImports.cpp b/src/passes/RemoveImports.cpp index 0c4924a45..0938bbed3 100644 --- a/src/passes/RemoveImports.cpp +++ b/src/passes/RemoveImports.cpp @@ -27,7 +27,7 @@ namespace wasm { -struct RemoveImports : public Pass { +struct RemoveImports : public WalkerPass<WasmWalker> { MixedArena* allocator; std::map<Name, Import*> importsMap; diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index 395b0f1ba..f01add24c 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -23,7 +23,7 @@ namespace wasm { -struct RemoveUnusedBrs : public Pass { +struct RemoveUnusedBrs : public WalkerPass<WasmWalker> { // preparation: try to unify branches, as the fewer there are, the higher a chance we can remove them // specifically for if-else, turn an if-else with branches to the same target at the end of each // child, and with a value, to a branch to that target containing the if-else diff --git a/src/passes/RemoveUnusedNames.cpp b/src/passes/RemoveUnusedNames.cpp index 62de48567..d3057c78a 100644 --- a/src/passes/RemoveUnusedNames.cpp +++ b/src/passes/RemoveUnusedNames.cpp @@ -23,7 +23,7 @@ namespace wasm { -struct RemoveUnusedNames : public Pass { +struct RemoveUnusedNames : public WalkerPass<WasmWalker> { // We maintain a list of branches that we saw in children, then when we reach // a parent block, we know if it was branched to std::set<Name> branchesSeen; diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp index b1adf5c26..bf3775445 100644 --- a/src/passes/SimplifyLocals.cpp +++ b/src/passes/SimplifyLocals.cpp @@ -23,7 +23,7 @@ namespace wasm { -struct SimplifyLocals : public Pass { +struct SimplifyLocals : public WalkerPass<WasmWalker> { void visitBlock(Block *curr) override { // look for pairs of setlocal-getlocal, which can be just a setlocal (since it returns a value) if (curr->list.size() == 0) return; diff --git a/src/wasm.h b/src/wasm.h index 306804c66..c6942acfe 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1233,13 +1233,101 @@ std::ostream& Expression::print(std::ostream &o, unsigned indent) { return o; } +struct WasmWalkerBase : public WasmVisitor<void> { + virtual void walk(Expression*& curr) { abort(); } + virtual void startWalk(Function *func) { abort(); } + virtual void startWalk(Module *module) { abort(); } +}; + +struct ChildWalker : public WasmWalkerBase { + WasmWalkerBase& parent; + + ChildWalker(WasmWalkerBase& parent) : parent(parent) {} + + void visitBlock(Block *curr) override { + ExpressionList& list = curr->list; + for (size_t z = 0; z < list.size(); z++) { + parent.walk(list[z]); + } + } + void visitIf(If *curr) override { + parent.walk(curr->condition); + parent.walk(curr->ifTrue); + parent.walk(curr->ifFalse); + } + void visitLoop(Loop *curr) override { + parent.walk(curr->body); + } + void visitBreak(Break *curr) override { + parent.walk(curr->condition); + parent.walk(curr->value); + } + void visitSwitch(Switch *curr) override { + parent.walk(curr->value); + for (auto& case_ : curr->cases) { + parent.walk(case_.body); + } + } + void visitCall(Call *curr) override { + ExpressionList& list = curr->operands; + for (size_t z = 0; z < list.size(); z++) { + parent.walk(list[z]); + } + } + void visitCallImport(CallImport *curr) override { + ExpressionList& list = curr->operands; + for (size_t z = 0; z < list.size(); z++) { + parent.walk(list[z]); + } + } + void visitCallIndirect(CallIndirect *curr) override { + parent.walk(curr->target); + ExpressionList& list = curr->operands; + for (size_t z = 0; z < list.size(); z++) { + parent.walk(list[z]); + } + } + void visitGetLocal(GetLocal *curr) override {} + void visitSetLocal(SetLocal *curr) override { + parent.walk(curr->value); + } + void visitLoad(Load *curr) override { + parent.walk(curr->ptr); + } + void visitStore(Store *curr) override { + parent.walk(curr->ptr); + parent.walk(curr->value); + } + void visitConst(Const *curr) override {} + void visitUnary(Unary *curr) override { + parent.walk(curr->value); + } + void visitBinary(Binary *curr) override { + parent.walk(curr->left); + parent.walk(curr->right); + } + void visitSelect(Select *curr) override { + parent.walk(curr->condition); + parent.walk(curr->ifTrue); + parent.walk(curr->ifFalse); + } + void visitHost(Host *curr) override { + ExpressionList& list = curr->operands; + for (size_t z = 0; z < list.size(); z++) { + parent.walk(list[z]); + } + } + void visitNop(Nop *curr) override {} + void visitUnreachable(Unreachable *curr) override {} +}; + // // Simple WebAssembly children-first walking (i.e., post-order, if you look // at the children as subtrees of the current node), with the ability to replace // the current expression node. Useful for writing optimization passes. // -struct WasmWalker : public WasmVisitor<void> { +struct WasmWalker : public WasmWalkerBase { Expression* replace; WasmWalker() : replace(nullptr) {} @@ -1279,91 +1367,9 @@ struct WasmWalker : public WasmVisitor<void> { void visitModule(Module *curr) override {} // children-first - void walk(Expression*& curr) { + void walk(Expression*& curr) override { if (!curr) return; - struct ChildWalker : public WasmVisitor { - WasmWalker& parent; - - ChildWalker(WasmWalker& parent) : parent(parent) {} - - void visitBlock(Block *curr) override { - ExpressionList& list = curr->list; - for (size_t z = 0; z < list.size(); z++) { - parent.walk(list[z]); - } - } - void visitIf(If *curr) override { - parent.walk(curr->condition); - parent.walk(curr->ifTrue); - parent.walk(curr->ifFalse); - } - void visitLoop(Loop *curr) override { - parent.walk(curr->body); - } - void visitBreak(Break *curr) override { - parent.walk(curr->condition); - parent.walk(curr->value); - } - void visitSwitch(Switch *curr) override { - parent.walk(curr->value); - for (auto& case_ : curr->cases) { - parent.walk(case_.body); - } - } - void visitCall(Call *curr) override { - ExpressionList& list = curr->operands; - for (size_t z = 0; z < list.size(); z++) { - parent.walk(list[z]); - } - } - void visitCallImport(CallImport *curr) override { - ExpressionList& list = curr->operands; - for (size_t z = 0; z < list.size(); z++) { - parent.walk(list[z]); - } - } - void visitCallIndirect(CallIndirect *curr) override { - parent.walk(curr->target); - ExpressionList& list = curr->operands; - for (size_t z = 0; z < list.size(); z++) { - parent.walk(list[z]); - } - } - void visitGetLocal(GetLocal *curr) override {} - void visitSetLocal(SetLocal *curr) override { - parent.walk(curr->value); - } - void visitLoad(Load *curr) override { - parent.walk(curr->ptr); - } - void visitStore(Store *curr) override { - parent.walk(curr->ptr); - parent.walk(curr->value); - } - void visitConst(Const *curr) override {} - void visitUnary(Unary *curr) override { - parent.walk(curr->value); - } - void visitBinary(Binary *curr) override { - parent.walk(curr->left); - parent.walk(curr->right); - } - void visitSelect(Select *curr) override { - parent.walk(curr->condition); - parent.walk(curr->ifTrue); - parent.walk(curr->ifFalse); - } - void visitHost(Host *curr) override { - ExpressionList& list = curr->operands; - for (size_t z = 0; z < list.size(); z++) { - parent.walk(list[z]); - } - } - void visitNop(Nop *curr) override {} - void visitUnreachable(Unreachable *curr) override {} - }; - ChildWalker(*this).visit(curr); visit(curr); @@ -1374,11 +1380,11 @@ struct WasmWalker : public WasmVisitor<void> { } } - void startWalk(Function *func) { + void startWalk(Function *func) override { walk(func->body); } - void startWalk(Module *module) { + void startWalk(Module *module) override { for (auto curr : module->functionTypes) { visitFunctionType(curr); assert(!replace); |