/* * 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 #include #include namespace wasm::PassUtils { using FuncSet = std::unordered_set; // A wrapper around a parallel pass that filters it to run run only on select // functions. struct FilteredPass : public Pass { std::unique_ptr 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(pass->create(), relevantFuncs); } FilteredPass(std::unique_ptr&& 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; 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) override { PassRunner::doAdd( std::make_unique(std::move(pass), relevantFuncs)); } private: const FuncSet& relevantFuncs; }; } // namespace wasm::PassUtils #endif // wasm_passes_pass_utils_h