diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/lubs.cpp | 1 | ||||
-rw-r--r-- | src/ir/module-utils.cpp | 206 | ||||
-rw-r--r-- | src/ir/module-utils.h | 200 | ||||
-rw-r--r-- | src/ir/struct-utils.h | 1 | ||||
-rw-r--r-- | src/passes/Directize.cpp | 1 | ||||
-rw-r--r-- | src/passes/GlobalEffects.cpp | 1 | ||||
-rw-r--r-- | src/passes/GlobalStructInference.cpp | 1 | ||||
-rw-r--r-- | src/passes/Inlining.cpp | 1 | ||||
-rw-r--r-- | src/passes/MultiMemoryLowering.cpp | 1 | ||||
-rw-r--r-- | src/tools/wasm-merge.cpp | 1 | ||||
-rw-r--r-- | src/tools/wasm-split/instrumenter.cpp | 1 |
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 { |