diff options
Diffstat (limited to 'src/passes/pass-utils.h')
-rw-r--r-- | src/passes/pass-utils.h | 95 |
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 |