diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/RemoveUnusedModuleElements.cpp | 62 | ||||
-rw-r--r-- | src/passes/pass.cpp | 1 | ||||
-rw-r--r-- | src/passes/passes.h | 1 | ||||
-rw-r--r-- | src/tools/wasm-reduce.cpp | 1 |
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", |