#ifndef wasm_passes_opt_utils_h
#define wasm_passes_opt_utils_h
#include <functional>
#include <unordered_set>
#include <pass.h>
#include <wasm.h>
namespace wasm {
namespace OptUtils {
inline void optimizeAfterInlining(std::unordered_set<Function*>& funcs,
Module* module,
PassRunner* parentRunner) {
std::vector<std::unique_ptr<Function>> all;
all.swap(module->functions);
module->updateMaps();
for (auto& func : funcs) {
module->addFunction(func);
}
PassRunner runner(module, parentRunner->options);
runner.setIsNested(true);
runner.setValidateGlobally(false); runner.add("precompute-propagate");
runner.addDefaultFunctionOptimizationPasses(); runner.run();
for (auto& func : module->functions) {
func.release();
}
all.swap(module->functions);
module->updateMaps();
}
struct FunctionRefReplacer
: public WalkerPass<PostWalker<FunctionRefReplacer>> {
bool isFunctionParallel() override { return true; }
using MaybeReplace = std::function<void(Name&)>;
FunctionRefReplacer(MaybeReplace maybeReplace) : maybeReplace(maybeReplace) {}
FunctionRefReplacer* create() override {
return new 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(maybeReplace).run(runner, &module);
for (auto& segment : module.table.segments) {
for (auto& name : segment.data) {
maybeReplace(name);
}
}
if (module.start.is()) {
maybeReplace(module.start);
}
for (auto& exp : module.exports) {
if (exp->kind == ExternalKind::Function) {
maybeReplace(exp->value);
}
}
}
} }
#endif