summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/RemoveUnusedModuleElements.cpp62
-rw-r--r--src/passes/pass.cpp1
-rw-r--r--src/passes/passes.h1
-rw-r--r--src/tools/wasm-reduce.cpp1
4 files changed, 52 insertions, 13 deletions
diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp
index 05e80af0d..6cd050da9 100644
--- a/src/passes/RemoveUnusedModuleElements.cpp
+++ b/src/passes/RemoveUnusedModuleElements.cpp
@@ -153,6 +153,10 @@ struct FunctionTypeAnalyzer : public PostWalker<FunctionTypeAnalyzer> {
};
struct RemoveUnusedModuleElements : public Pass {
+ bool rootAllFunctions;
+
+ RemoveUnusedModuleElements(bool rootAllFunctions) : rootAllFunctions(rootAllFunctions) {}
+
void run(PassRunner* runner, Module* module) override {
optimizeGlobalsAndFunctions(module);
optimizeFunctionTypes(module);
@@ -170,6 +174,12 @@ struct RemoveUnusedModuleElements : public Pass {
roots.emplace_back(ModuleElementKind::Function, module->start);
}
}
+ // If told to, root all the functions
+ if (rootAllFunctions) {
+ for (auto& func : module->functions) {
+ roots.emplace_back(ModuleElementKind::Function, func->name);
+ }
+ }
// Exports are roots.
bool exportsMemory = false;
bool exportsTable = false;
@@ -184,6 +194,16 @@ struct RemoveUnusedModuleElements : public Pass {
exportsTable = true;
}
}
+ // Check for special imports are roots.
+ bool importsMemory = false;
+ bool importsTable = false;
+ for (auto& curr : module->imports) {
+ if (curr->kind == ExternalKind::Memory) {
+ importsMemory = true;
+ } else if (curr->kind == ExternalKind::Table) {
+ importsTable = true;
+ }
+ }
// For now, all functions that can be called indirectly are marked as roots.
for (auto& segment : module->table.segments) {
for (auto& curr : segment.data) {
@@ -218,19 +238,31 @@ struct RemoveUnusedModuleElements : public Pass {
}
module->updateMaps();
// Handle the memory and table
- if (!exportsMemory && !analyzer.usesMemory && module->memory.segments.empty()) {
- module->memory.exists = false;
- module->memory.imported = false;
- module->memory.initial = 0;
- module->memory.max = 0;
- removeImport(ExternalKind::Memory, module);
+ if (!exportsMemory && !analyzer.usesMemory) {
+ if (!importsMemory) {
+ // The memory is unobservable to the outside, we can remove the contents.
+ module->memory.segments.clear();
+ }
+ if (module->memory.segments.empty()) {
+ module->memory.exists = false;
+ module->memory.imported = false;
+ module->memory.initial = 0;
+ module->memory.max = 0;
+ removeImport(ExternalKind::Memory, module);
+ }
}
- if (!exportsTable && !analyzer.usesTable && module->table.segments.empty()) {
- module->table.exists = false;
- module->table.imported = false;
- module->table.initial = 0;
- module->table.max = 0;
- removeImport(ExternalKind::Table, module);
+ if (!exportsTable && !analyzer.usesTable) {
+ if (!importsTable) {
+ // The table is unobservable to the outside, we can remove the contents.
+ module->table.segments.clear();
+ }
+ if (module->table.segments.empty()) {
+ module->table.exists = false;
+ module->table.imported = false;
+ module->table.initial = 0;
+ module->table.max = 0;
+ removeImport(ExternalKind::Table, module);
+ }
}
}
@@ -279,7 +311,11 @@ struct RemoveUnusedModuleElements : public Pass {
};
Pass* createRemoveUnusedModuleElementsPass() {
- return new RemoveUnusedModuleElements();
+ return new RemoveUnusedModuleElements(false);
+}
+
+Pass* createRemoveUnusedNonFunctionModuleElementsPass() {
+ return new RemoveUnusedModuleElements(true);
}
} // namespace wasm
diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp
index ae9484d29..2d93d99ae 100644
--- a/src/passes/pass.cpp
+++ b/src/passes/pass.cpp
@@ -103,6 +103,7 @@ void PassRegistry::registerPasses() {
registerPass("remove-memory", "removes memory segments", createRemoveMemoryPass);
registerPass("remove-unused-brs", "removes breaks from locations that are not needed", createRemoveUnusedBrsPass);
registerPass("remove-unused-module-elements", "removes unused module elements", createRemoveUnusedModuleElementsPass);
+ registerPass("remove-unused-nonfunction-module-elements", "removes unused module elements that are not functions", createRemoveUnusedNonFunctionModuleElementsPass);
registerPass("remove-unused-names", "removes names from locations that are never branched to", createRemoveUnusedNamesPass);
registerPass("reorder-functions", "sorts functions by access frequency", createReorderFunctionsPass);
registerPass("reorder-locals", "sorts locals by access frequency", createReorderLocalsPass);
diff --git a/src/passes/passes.h b/src/passes/passes.h
index 5ab03a439..cf77f9fac 100644
--- a/src/passes/passes.h
+++ b/src/passes/passes.h
@@ -60,6 +60,7 @@ Pass* createRemoveImportsPass();
Pass* createRemoveMemoryPass();
Pass* createRemoveUnusedBrsPass();
Pass* createRemoveUnusedModuleElementsPass();
+Pass* createRemoveUnusedNonFunctionModuleElementsPass();
Pass* createRemoveUnusedNamesPass();
Pass* createReorderFunctionsPass();
Pass* createReorderLocalsPass();
diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp
index 6b8d93f97..7b7ff9da3 100644
--- a/src/tools/wasm-reduce.cpp
+++ b/src/tools/wasm-reduce.cpp
@@ -249,6 +249,7 @@ struct Reducer : public WalkerPass<PostWalker<Reducer, UnifiedExpressionVisitor<
"--remove-memory",
"--remove-unused-names --remove-unused-brs",
"--remove-unused-module-elements",
+ "--remove-unused-nonfunction-module-elements",
"--reorder-functions",
"--reorder-locals",
"--simplify-locals --vacuum",