summaryrefslogtreecommitdiff
path: root/src/passes/pass-utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/pass-utils.h')
-rw-r--r--src/passes/pass-utils.h95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/passes/pass-utils.h b/src/passes/pass-utils.h
new file mode 100644
index 000000000..1db4f5614
--- /dev/null
+++ b/src/passes/pass-utils.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2023 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef wasm_passes_pass_utils_h
+#define wasm_passes_pass_utils_h
+
+#include <unordered_set>
+
+#include <pass.h>
+#include <wasm.h>
+
+namespace wasm::PassUtils {
+
+using FuncSet = std::unordered_set<Function*>;
+
+// A wrapper around a parallel pass that filters it to run run only on select
+// functions.
+struct FilteredPass : public Pass {
+ std::unique_ptr<Pass> create() override {
+ // Function-parallel passes get a new instance per function. Create a copy
+ // of the wrapped pass along with ourselves.
+ return std::make_unique<FilteredPass>(pass->create(), relevantFuncs);
+ }
+
+ FilteredPass(std::unique_ptr<Pass>&& pass, const FuncSet& relevantFuncs)
+ : pass(std::move(pass)), relevantFuncs(relevantFuncs) {}
+
+ bool isFunctionParallel() override {
+ assert(pass->isFunctionParallel());
+ return true;
+ }
+
+ void runOnFunction(Module* module, Function* func) override {
+ if (!relevantFuncs.count(func)) {
+ return;
+ }
+
+ // The pass runner calling us set our pass runner, which we must do for the
+ // wrapped pass.
+ pass->setPassRunner(getPassRunner());
+ pass->runOnFunction(module, func);
+ }
+
+ bool modifiesBinaryenIR() override { return pass->modifiesBinaryenIR(); }
+
+ bool invalidatesDWARF() override { return pass->invalidatesDWARF(); }
+
+ bool addsEffects() override { return pass->addsEffects(); }
+
+ bool requiresNonNullableLocalFixups() override {
+ return pass->requiresNonNullableLocalFixups();
+ }
+
+private:
+ std::unique_ptr<Pass> pass;
+ const FuncSet& relevantFuncs;
+};
+
+// A pass runner that wraps all passes, filtering so that they only run on
+// select functions.
+struct FilteredPassRunner : public PassRunner {
+ FilteredPassRunner(Module* wasm, const FuncSet& relevantFuncs)
+ : PassRunner(wasm), relevantFuncs(relevantFuncs) {}
+
+ FilteredPassRunner(Module* wasm,
+ const FuncSet& relevantFuncs,
+ const PassOptions& options)
+ : PassRunner(wasm, options), relevantFuncs(relevantFuncs) {}
+
+protected:
+ void doAdd(std::unique_ptr<Pass> pass) override {
+ PassRunner::doAdd(
+ std::make_unique<FilteredPass>(std::move(pass), relevantFuncs));
+ }
+
+private:
+ const FuncSet& relevantFuncs;
+};
+
+} // namespace wasm::PassUtils
+
+#endif // wasm_passes_pass_utils_h