summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ir/lubs.cpp1
-rw-r--r--src/ir/module-utils.cpp206
-rw-r--r--src/ir/module-utils.h200
-rw-r--r--src/ir/struct-utils.h1
-rw-r--r--src/passes/Directize.cpp1
-rw-r--r--src/passes/GlobalEffects.cpp1
-rw-r--r--src/passes/GlobalStructInference.cpp1
-rw-r--r--src/passes/Inlining.cpp1
-rw-r--r--src/passes/MultiMemoryLowering.cpp1
-rw-r--r--src/tools/wasm-merge.cpp1
-rw-r--r--src/tools/wasm-split/instrumenter.cpp1
11 files changed, 227 insertions, 188 deletions
diff --git a/src/ir/lubs.cpp b/src/ir/lubs.cpp
index 1f844c244..f9c04cb36 100644
--- a/src/ir/lubs.cpp
+++ b/src/ir/lubs.cpp
@@ -15,6 +15,7 @@
*/
#include "ir/lubs.h"
+#include "ir/find_all.h"
#include "ir/utils.h"
#include "wasm-type.h"
#include "wasm.h"
diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp
index 7e202a5da..2b2f51323 100644
--- a/src/ir/module-utils.cpp
+++ b/src/ir/module-utils.cpp
@@ -16,11 +16,217 @@
#include "module-utils.h"
#include "ir/intrinsics.h"
+#include "ir/manipulation.h"
+#include "ir/properties.h"
#include "support/insert_ordered.h"
#include "support/topological_sort.h"
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).
+Function* copyFunction(Function* func, Module& out, Name newName) {
+ 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));
+}
+
+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;
+}
+
+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;
+}
+
+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));
+ }
+}
+
+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;
+
+ ret->initial = table->initial;
+ ret->max = table->max;
+
+ return out.addTable(std::move(ret));
+}
+
+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));
+}
+
+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;
+
+ return out.addDataSegment(std::move(ret));
+}
+
+// Copies named toplevel module items (things of kind ModuleItemKind). See
+// copyModule() for something that also copies exports, the start function, etc.
+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 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 clearModule(Module& wasm) {
+ wasm.~Module();
+ new (&wasm) Module;
+}
+
+// Renaming
+
+// Rename functions along with all their uses.
+// 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> 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); }
+
+ 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);
+}
+
+void renameFunction(Module& wasm, Name oldName, Name newName) {
+ std::map<Name, Name> map;
+ map[oldName] = newName;
+ renameFunctions(wasm, map);
+}
+
namespace {
// Helper for collecting HeapTypes and their frequencies.
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
diff --git a/src/ir/struct-utils.h b/src/ir/struct-utils.h
index eb5ee5d2d..667c9ed55 100644
--- a/src/ir/struct-utils.h
+++ b/src/ir/struct-utils.h
@@ -17,6 +17,7 @@
#ifndef wasm_ir_struct_utils_h
#define wasm_ir_struct_utils_h
+#include "ir/properties.h"
#include "ir/subtypes.h"
#include "wasm.h"
diff --git a/src/passes/Directize.cpp b/src/passes/Directize.cpp
index 3fc7d6c41..0bb5aebd9 100644
--- a/src/passes/Directize.cpp
+++ b/src/passes/Directize.cpp
@@ -34,6 +34,7 @@
#include "call-utils.h"
#include "ir/drop.h"
+#include "ir/find_all.h"
#include "ir/table-utils.h"
#include "ir/utils.h"
#include "pass.h"
diff --git a/src/passes/GlobalEffects.cpp b/src/passes/GlobalEffects.cpp
index 6ed2d413a..a2c34b644 100644
--- a/src/passes/GlobalEffects.cpp
+++ b/src/passes/GlobalEffects.cpp
@@ -19,6 +19,7 @@
// PassOptions structure; see more details there.
//
+#include "ir/effects.h"
#include "ir/module-utils.h"
#include "pass.h"
#include "wasm.h"
diff --git a/src/passes/GlobalStructInference.cpp b/src/passes/GlobalStructInference.cpp
index 89ab155f8..6a917596f 100644
--- a/src/passes/GlobalStructInference.cpp
+++ b/src/passes/GlobalStructInference.cpp
@@ -50,6 +50,7 @@
#include "ir/find_all.h"
#include "ir/module-utils.h"
+#include "ir/properties.h"
#include "ir/subtypes.h"
#include "pass.h"
#include "wasm-builder.h"
diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp
index 3326b7370..26ebcf566 100644
--- a/src/passes/Inlining.cpp
+++ b/src/passes/Inlining.cpp
@@ -35,6 +35,7 @@
#include "ir/drop.h"
#include "ir/eh-utils.h"
#include "ir/element-utils.h"
+#include "ir/find_all.h"
#include "ir/literal-utils.h"
#include "ir/module-utils.h"
#include "ir/names.h"
diff --git a/src/passes/MultiMemoryLowering.cpp b/src/passes/MultiMemoryLowering.cpp
index f0a4be112..2b3aedb2c 100644
--- a/src/passes/MultiMemoryLowering.cpp
+++ b/src/passes/MultiMemoryLowering.cpp
@@ -40,6 +40,7 @@
// the same semantics as v8, which is to bounds check all Atomic instructions
// the same way and trap for out-of-bounds.
+#include "ir/abstract.h"
#include "ir/module-utils.h"
#include "ir/names.h"
#include "wasm-builder.h"
diff --git a/src/tools/wasm-merge.cpp b/src/tools/wasm-merge.cpp
index 8df93196f..d3269e8fd 100644
--- a/src/tools/wasm-merge.cpp
+++ b/src/tools/wasm-merge.cpp
@@ -96,6 +96,7 @@
#include "ir/names.h"
#include "support/colors.h"
#include "support/file.h"
+#include "wasm-builder.h"
#include "wasm-io.h"
#include "wasm-validator.h"
#include "wasm.h"
diff --git a/src/tools/wasm-split/instrumenter.cpp b/src/tools/wasm-split/instrumenter.cpp
index 22940a5f2..a2d6340f0 100644
--- a/src/tools/wasm-split/instrumenter.cpp
+++ b/src/tools/wasm-split/instrumenter.cpp
@@ -18,6 +18,7 @@
#include "ir/module-utils.h"
#include "ir/names.h"
#include "support/name.h"
+#include "wasm-builder.h"
#include "wasm-type.h"
namespace wasm {