summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pass.h23
-rw-r--r--src/passes/pass.cpp25
-rw-r--r--src/wasm-traversal.h4
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