summaryrefslogtreecommitdiff
path: root/src/ir/module-utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/module-utils.h')
-rw-r--r--src/ir/module-utils.h200
1 files changed, 12 insertions, 188 deletions
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h
index f4c8c51c4..a1ecfdf84 100644
--- a/src/ir/module-utils.h
+++ b/src/ir/module-utils.h
@@ -17,10 +17,6 @@
#ifndef wasm_ir_module_h
#define wasm_ir_module_h
-#include "ir/element-utils.h"
-#include "ir/find_all.h"
-#include "ir/manipulation.h"
-#include "ir/properties.h"
#include "pass.h"
#include "support/unique_deferring_queue.h"
#include "wasm.h"
@@ -29,157 +25,27 @@ namespace wasm::ModuleUtils {
// Copies a function into a module. If newName is provided it is used as the
// name of the function (otherwise the original name is copied).
-inline Function*
-copyFunction(Function* func, Module& out, Name newName = Name()) {
- auto ret = std::make_unique<Function>();
- ret->name = newName.is() ? newName : func->name;
- ret->type = func->type;
- ret->vars = func->vars;
- ret->localNames = func->localNames;
- ret->localIndices = func->localIndices;
- ret->debugLocations = func->debugLocations;
- ret->body = ExpressionManipulator::copy(func->body, out);
- ret->module = func->module;
- ret->base = func->base;
- // TODO: copy Stack IR
- assert(!func->stackIR);
- return out.addFunction(std::move(ret));
-}
-
-inline Global* copyGlobal(Global* global, Module& out) {
- auto* ret = new Global();
- ret->name = global->name;
- ret->type = global->type;
- ret->mutable_ = global->mutable_;
- ret->module = global->module;
- ret->base = global->base;
- if (global->imported()) {
- ret->init = nullptr;
- } else {
- ret->init = ExpressionManipulator::copy(global->init, out);
- }
- out.addGlobal(ret);
- return ret;
-}
-
-inline Tag* copyTag(Tag* tag, Module& out) {
- auto* ret = new Tag();
- ret->name = tag->name;
- ret->sig = tag->sig;
- ret->module = tag->module;
- ret->base = tag->base;
- out.addTag(ret);
- return ret;
-}
-
-inline ElementSegment* copyElementSegment(const ElementSegment* segment,
- Module& out) {
- auto copy = [&](std::unique_ptr<ElementSegment>&& ret) {
- ret->name = segment->name;
- ret->hasExplicitName = segment->hasExplicitName;
- ret->type = segment->type;
- ret->data.reserve(segment->data.size());
- for (auto* item : segment->data) {
- ret->data.push_back(ExpressionManipulator::copy(item, out));
- }
-
- return out.addElementSegment(std::move(ret));
- };
-
- if (segment->table.isNull()) {
- return copy(std::make_unique<ElementSegment>());
- } else {
- auto offset = ExpressionManipulator::copy(segment->offset, out);
- return copy(std::make_unique<ElementSegment>(segment->table, offset));
- }
-}
+Function* copyFunction(Function* func, Module& out, Name newName = Name());
-inline Table* copyTable(const Table* table, Module& out) {
- auto ret = std::make_unique<Table>();
- ret->name = table->name;
- ret->hasExplicitName = table->hasExplicitName;
- ret->type = table->type;
- ret->module = table->module;
- ret->base = table->base;
+Global* copyGlobal(Global* global, Module& out);
- ret->initial = table->initial;
- ret->max = table->max;
+Tag* copyTag(Tag* tag, Module& out);
- return out.addTable(std::move(ret));
-}
+ElementSegment* copyElementSegment(const ElementSegment* segment, Module& out);
-inline Memory* copyMemory(const Memory* memory, Module& out) {
- auto ret = Builder::makeMemory(memory->name);
- ret->hasExplicitName = memory->hasExplicitName;
- ret->initial = memory->initial;
- ret->max = memory->max;
- ret->shared = memory->shared;
- ret->indexType = memory->indexType;
- ret->module = memory->module;
- ret->base = memory->base;
-
- return out.addMemory(std::move(ret));
-}
+Table* copyTable(const Table* table, Module& out);
-inline DataSegment* copyDataSegment(const DataSegment* segment, Module& out) {
- auto ret = Builder::makeDataSegment();
- ret->name = segment->name;
- ret->hasExplicitName = segment->hasExplicitName;
- ret->memory = segment->memory;
- ret->isPassive = segment->isPassive;
- if (!segment->isPassive) {
- auto offset = ExpressionManipulator::copy(segment->offset, out);
- ret->offset = offset;
- }
- ret->data = segment->data;
+Memory* copyMemory(const Memory* memory, Module& out);
- return out.addDataSegment(std::move(ret));
-}
+DataSegment* copyDataSegment(const DataSegment* segment, Module& out);
// Copies named toplevel module items (things of kind ModuleItemKind). See
// copyModule() for something that also copies exports, the start function, etc.
-inline void copyModuleItems(const Module& in, Module& out) {
- for (auto& curr : in.functions) {
- copyFunction(curr.get(), out);
- }
- for (auto& curr : in.globals) {
- copyGlobal(curr.get(), out);
- }
- for (auto& curr : in.tags) {
- copyTag(curr.get(), out);
- }
- for (auto& curr : in.elementSegments) {
- copyElementSegment(curr.get(), out);
- }
- for (auto& curr : in.tables) {
- copyTable(curr.get(), out);
- }
- for (auto& curr : in.memories) {
- copyMemory(curr.get(), out);
- }
- for (auto& curr : in.dataSegments) {
- copyDataSegment(curr.get(), out);
- }
-}
+void copyModuleItems(const Module& in, Module& out);
-inline void copyModule(const Module& in, Module& out) {
- // we use names throughout, not raw pointers, so simple copying is fine
- // for everything *but* expressions
- for (auto& curr : in.exports) {
- out.addExport(std::make_unique<Export>(*curr));
- }
- copyModuleItems(in, out);
- out.start = in.start;
- out.customSections = in.customSections;
- out.debugInfoFileNames = in.debugInfoFileNames;
- out.features = in.features;
- out.typeNames = in.typeNames;
-}
+void copyModule(const Module& in, Module& out);
-inline void clearModule(Module& wasm) {
- wasm.~Module();
- new (&wasm) Module;
-}
+void clearModule(Module& wasm);
// Renaming
@@ -187,51 +53,9 @@ inline void clearModule(Module& wasm) {
// Note that for this to work the functions themselves don't necessarily need
// to exist. For example, it is possible to remove a given function and then
// call this to redirect all of its uses.
-template<typename T> inline void renameFunctions(Module& wasm, T& map) {
- // Update the function itself.
- for (auto& [oldName, newName] : map) {
- if (Function* func = wasm.getFunctionOrNull(oldName)) {
- assert(!wasm.getFunctionOrNull(newName) || func->name == newName);
- func->name = newName;
- }
- }
- wasm.updateMaps();
-
- // Update all references to it.
- struct Updater : public WalkerPass<PostWalker<Updater>> {
- bool isFunctionParallel() override { return true; }
-
- T& map;
-
- void maybeUpdate(Name& name) {
- if (auto iter = map.find(name); iter != map.end()) {
- name = iter->second;
- }
- }
-
- Updater(T& map) : map(map) {}
-
- std::unique_ptr<Pass> create() override {
- return std::make_unique<Updater>(map);
- }
-
- void visitCall(Call* curr) { maybeUpdate(curr->target); }
+template<typename T> void renameFunctions(Module& wasm, T& map);
- void visitRefFunc(RefFunc* curr) { maybeUpdate(curr->func); }
- };
-
- Updater updater(map);
- updater.maybeUpdate(wasm.start);
- PassRunner runner(&wasm);
- updater.run(&runner, &wasm);
- updater.runOnModuleCode(&runner, &wasm);
-}
-
-inline void renameFunction(Module& wasm, Name oldName, Name newName) {
- std::map<Name, Name> map;
- map[oldName] = newName;
- renameFunctions(wasm, map);
-}
+void renameFunction(Module& wasm, Name oldName, Name newName);
// Convenient iteration over imported/non-imported module elements