diff options
-rw-r--r-- | src/pass.h | 23 | ||||
-rw-r--r-- | src/passes/pass.cpp | 25 | ||||
-rw-r--r-- | src/wasm-traversal.h | 4 |
3 files changed, 50 insertions, 2 deletions
diff --git a/src/pass.h b/src/pass.h index e25809faa..fff2b04eb 100644 --- a/src/pass.h +++ b/src/pass.h @@ -97,8 +97,20 @@ struct PassRunner { // what -O does. void addDefaultOptimizationPasses(); + // Adds the default optimization passes that work on + // individual functions. + void addDefaultFunctionOptimizationPasses(); + + // Adds the default optimization passes that work on + // entire modules as a whole. + void addDefaultGlobalOptimizationPasses(); + + // Run the passes on the module void run(); + // Run the passes on a specific function + void runFunction(Function* func); + // Get the last pass that was already executed of a certain type. template<class P> P* getLast(); @@ -112,12 +124,18 @@ struct PassRunner { class Pass { public: virtual ~Pass() {}; + // Override this to perform preparation work before the pass runs. virtual void prepare(PassRunner* runner, Module* module) {} virtual void run(PassRunner* runner, Module* module) = 0; // Override this to perform finalization work after the pass runs. virtual void finalize(PassRunner* runner, Module* module) {} + // Run on a single function. This has no prepare/finalize calls. + virtual void runFunction(PassRunner* runner, Module* module, Function* function) { + WASM_UNREACHABLE(); // by default, passes cannot be run this way + } + std::string name; protected: @@ -138,6 +156,11 @@ public: WalkerType::walkModule(module); finalize(runner, module); } + + void runFunction(PassRunner* runner, Module* module, Function* func) override { + WalkerType::setModule(module); + WalkerType::walkFunction(func); + } }; // Standard passes. All passes in /passes/ are runnable from the shell, diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index ca9f477a3..e5bbf5866 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -74,6 +74,25 @@ void PassRunner::addDefaultOptimizationPasses() { add("duplicate-function-elimination"); // optimizations show more functions as duplicate } +void PassRunner::addDefaultFunctionOptimizationPasses() { + add("dce"); + add("remove-unused-brs"); + add("remove-unused-names"); + add("optimize-instructions"); + add("simplify-locals"); + add("vacuum"); // previous pass creates garbage + add("coalesce-locals"); + add("vacuum"); // previous pass creates garbage + add("reorder-locals"); + add("merge-blocks"); + add("optimize-instructions"); + add("vacuum"); // should not be needed, last few passes do not create garbage, but just to be safe +} + +void PassRunner::addDefaultGlobalOptimizationPasses() { + add("duplicate-function-elimination"); +} + void PassRunner::run() { std::chrono::high_resolution_clock::time_point beforeEverything; size_t padding = 0; @@ -108,6 +127,12 @@ void PassRunner::run() { } } +void PassRunner::runFunction(Function* func) { + for (auto pass : passes) { + pass->runFunction(this, wasm, func); + } +} + template<class P> P* PassRunner::getLast() { bool found = false; diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h index 9ed02027e..e5da420b0 100644 --- a/src/wasm-traversal.h +++ b/src/wasm-traversal.h @@ -187,6 +187,7 @@ struct Walker : public VisitorType { void walkFunction(Function* func) { setFunction(func); static_cast<SubType*>(this)->doWalkFunction(func); + static_cast<SubType*>(this)->visitFunction(func); } // override this to provide custom functionality @@ -197,6 +198,7 @@ struct Walker : public VisitorType { void walkModule(Module *module) { setModule(module); static_cast<SubType*>(this)->doWalkModule(module); + static_cast<SubType*>(this)->visitModule(module); } // override this to provide custom functionality @@ -223,7 +225,6 @@ struct Walker : public VisitorType { allocated = std::unique_ptr<SubType>(instance); } instance->walkFunction(func); - instance->visitFunction(func); }; // if this is not a function-parallel traversal, run @@ -259,7 +260,6 @@ struct Walker : public VisitorType { } self->visitTable(&module->table); self->visitMemory(&module->memory); - self->visitModule(module); } // Walk implementation. We don't use recursion as ASTs may be highly |