#ifndef wasm_passes_opt_utils_h
#define wasm_passes_opt_utils_h
#include <functional>
#include <unordered_set>
#include <ir/element-utils.h>
#include <ir/module-utils.h>
#include <pass.h>
#include <passes/pass-utils.h>
#include <wasm.h>
namespace wasm::OptUtils {
inline void optimizeAfterInlining(const PassUtils::FuncSet& funcs,
Module* module,
PassRunner* parentRunner) {
PassUtils::FilteredPassRunner runner(module, funcs, parentRunner->options);
runner.setIsNested(true);
runner.add("precompute-propagate");
runner.addDefaultFunctionOptimizationPasses(); runner.run();
}
struct FunctionRefReplacer
: public WalkerPass<PostWalker<FunctionRefReplacer>> {
bool isFunctionParallel() override { return true; }
using MaybeReplace = std::function<void(Name&)>;
FunctionRefReplacer(MaybeReplace maybeReplace) : maybeReplace(maybeReplace) {}
std::unique_ptr<Pass> create() override {
return std::make_unique<FunctionRefReplacer>(maybeReplace);
}
void visitCall(Call* curr) { maybeReplace(curr->target); }
void visitRefFunc(RefFunc* curr) { maybeReplace(curr->func); }
private:
MaybeReplace maybeReplace;
};
inline void replaceFunctions(PassRunner* runner,
Module& module,
const std::map<Name, Name>& replacements) {
auto maybeReplace = [&](Name& name) {
auto iter = replacements.find(name);
if (iter != replacements.end()) {
name = iter->second;
}
};
FunctionRefReplacer replacer(maybeReplace);
replacer.run(runner, &module);
replacer.runOnModuleCode(runner, &module);
if (module.start.is()) {
maybeReplace(module.start);
}
for (auto& exp : module.exports) {
if (exp->kind == ExternalKind::Function) {
maybeReplace(exp->value);
}
}
}
}
#endif