summaryrefslogtreecommitdiff
path: root/src/passes/opt-utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/opt-utils.h')
-rw-r--r--src/passes/opt-utils.h51
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