/*
 * 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) {
    // Copy the pass's name, for debugging and for --skip-pass support.
    name = pass->name;
  }

  bool isFunctionParallel() override {
    assert(pass->isFunctionParallel());
    return true;
  }

  void runOnFunction(Module* module, Function* func) override {
    if (!relevantFuncs.contains(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
