diff options
Diffstat (limited to 'src/passes/opt-utils.h')
-rw-r--r-- | src/passes/opt-utils.h | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/passes/opt-utils.h b/src/passes/opt-utils.h index 9ac6da4a2..e9141c4f1 100644 --- a/src/passes/opt-utils.h +++ b/src/passes/opt-utils.h @@ -53,6 +53,57 @@ inline void optimizeAfterInlining(std::unordered_set<Function*>& funcs, module->updateMaps(); } +struct CallTargetReplacer : public WalkerPass<PostWalker<CallTargetReplacer>> { + bool isFunctionParallel() override { return true; } + + CallTargetReplacer(std::map<Name, Name>* replacements) + : replacements(replacements) {} + + CallTargetReplacer* create() override { + return new CallTargetReplacer(replacements); + } + + void visitCall(Call* curr) { + auto iter = replacements->find(curr->target); + if (iter != replacements->end()) { + curr->target = iter->second; + } + } + +private: + std::map<Name, Name>* replacements; +}; + +inline void replaceFunctions(PassRunner* runner, + Module& module, + std::map<Name, Name>& replacements) { + // replace direct calls + CallTargetReplacer(&replacements).run(runner, &module); + // replace in table + for (auto& segment : module.table.segments) { + for (auto& name : segment.data) { + auto iter = replacements.find(name); + if (iter != replacements.end()) { + name = iter->second; + } + } + } + // replace in start + if (module.start.is()) { + auto iter = replacements.find(module.start); + if (iter != replacements.end()) { + module.start = iter->second; + } + } + // replace in exports + for (auto& exp : module.exports) { + auto iter = replacements.find(exp->value); + if (iter != replacements.end()) { + exp->value = iter->second; + } + } +} + } // namespace OptUtils } // namespace wasm |