summaryrefslogtreecommitdiff
path: root/src/passes/Asyncify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/Asyncify.cpp')
-rw-r--r--src/passes/Asyncify.cpp52
1 files changed, 50 insertions, 2 deletions
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp
index 342cd013d..365891db4 100644
--- a/src/passes/Asyncify.cpp
+++ b/src/passes/Asyncify.cpp
@@ -848,6 +848,54 @@ public:
}
};
+// Proxy that runs wrapped pass for instrumented functions only
+struct InstrumentedProxy : public Pass {
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<InstrumentedProxy>(analyzer, pass->create());
+ }
+
+ InstrumentedProxy(ModuleAnalyzer* analyzer, std::unique_ptr<Pass> pass)
+ : analyzer(analyzer), pass(std::move(pass)) {}
+
+ bool isFunctionParallel() override { return pass->isFunctionParallel(); }
+
+ void runOnFunction(Module* module, Function* func) override {
+ if (!analyzer->needsInstrumentation(func)) {
+ return;
+ }
+ if (pass->getPassRunner() == nullptr) {
+ pass->setPassRunner(getPassRunner());
+ }
+ pass->runOnFunction(module, func);
+ }
+
+ bool modifiesBinaryenIR() override { return pass->modifiesBinaryenIR(); }
+
+ bool invalidatesDWARF() override { return pass->invalidatesDWARF(); }
+
+ bool requiresNonNullableLocalFixups() override {
+ return pass->requiresNonNullableLocalFixups();
+ }
+
+private:
+ ModuleAnalyzer* analyzer;
+ std::unique_ptr<Pass> pass;
+};
+
+struct InstrumentedPassRunner : public PassRunner {
+ InstrumentedPassRunner(Module* wasm, ModuleAnalyzer* analyzer)
+ : PassRunner(wasm), analyzer(analyzer) {}
+
+protected:
+ void doAdd(std::unique_ptr<Pass> pass) override {
+ PassRunner::doAdd(
+ std::unique_ptr<Pass>(new InstrumentedProxy(analyzer, std::move(pass))));
+ }
+
+private:
+ ModuleAnalyzer* analyzer;
+};
+
// Instrument control flow, around calls and adding skips for rewinding.
struct AsyncifyFlow : public Pass {
bool isFunctionParallel() override { return true; }
@@ -1616,7 +1664,7 @@ struct Asyncify : public Pass {
// practical to add code around each call, without affecting
// anything else.
{
- PassRunner runner(module);
+ InstrumentedPassRunner runner(module, &analyzer);
runner.add("flatten");
// Dce is useful here, since AsyncifyFlow makes control flow conditional,
// which may make unreachable code look reachable. It also lets us ignore
@@ -1647,7 +1695,7 @@ struct Asyncify : public Pass {
// restore those locals). We also and optimize after as well to simplify
// the code as much as possible.
{
- PassRunner runner(module);
+ InstrumentedPassRunner runner(module, &analyzer);
if (optimize) {
runner.addDefaultFunctionOptimizationPasses();
}