diff options
Diffstat (limited to 'src/passes/RemoveUnusedModuleElements.cpp')
-rw-r--r-- | src/passes/RemoveUnusedModuleElements.cpp | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp index c96ce1a8c..20c30d271 100644 --- a/src/passes/RemoveUnusedModuleElements.cpp +++ b/src/passes/RemoveUnusedModuleElements.cpp @@ -15,9 +15,9 @@ */ // -// Removes module elements that are are never used: functions and globals, -// which may be imported or not, and function types (which we merge -// and remove if unneeded) +// Removes module elements that are are never used: functions, globals, and +// events, which may be imported or not, and function types (which we merge and +// remove if unneeded) // #include <memory> @@ -30,7 +30,7 @@ namespace wasm { -enum class ModuleElementKind { Function, Global }; +enum class ModuleElementKind { Function, Global, Event }; typedef std::pair<ModuleElementKind, Name> ModuleElement; @@ -68,7 +68,7 @@ struct ReachabilityAnalyzer : public PostWalker<ReachabilityAnalyzer> { if (!func->imported()) { walk(func->body); } - } else { + } else if (curr.first == ModuleElementKind::Global) { // if not imported, it has an init expression we need to walk auto* global = module->getGlobal(curr.second); if (!global->imported()) { @@ -122,6 +122,7 @@ struct ReachabilityAnalyzer : public PostWalker<ReachabilityAnalyzer> { struct FunctionTypeAnalyzer : public PostWalker<FunctionTypeAnalyzer> { std::vector<Function*> functions; std::vector<CallIndirect*> indirectCalls; + std::vector<Event*> events; void visitFunction(Function* curr) { if (curr->type.is()) { @@ -129,6 +130,8 @@ struct FunctionTypeAnalyzer : public PostWalker<FunctionTypeAnalyzer> { } } + void visitEvent(Event* curr) { events.push_back(curr); } + void visitCallIndirect(CallIndirect* curr) { indirectCalls.push_back(curr); } }; @@ -139,11 +142,11 @@ struct RemoveUnusedModuleElements : public Pass { : rootAllFunctions(rootAllFunctions) {} void run(PassRunner* runner, Module* module) override { - optimizeGlobalsAndFunctions(module); + optimizeGlobalsAndFunctionsAndEvents(module); optimizeFunctionTypes(module); } - void optimizeGlobalsAndFunctions(Module* module) { + void optimizeGlobalsAndFunctionsAndEvents(Module* module) { std::vector<ModuleElement> roots; // Module start is a root. if (module->start.is()) { @@ -169,6 +172,8 @@ struct RemoveUnusedModuleElements : public Pass { roots.emplace_back(ModuleElementKind::Function, curr->value); } else if (curr->kind == ExternalKind::Global) { roots.emplace_back(ModuleElementKind::Global, curr->value); + } else if (curr->kind == ExternalKind::Event) { + roots.emplace_back(ModuleElementKind::Event, curr->value); } else if (curr->kind == ExternalKind::Memory) { exportsMemory = true; } else if (curr->kind == ExternalKind::Table) { @@ -215,6 +220,17 @@ struct RemoveUnusedModuleElements : public Pass { }), v.end()); } + { + auto& v = module->events; + v.erase(std::remove_if(v.begin(), + v.end(), + [&](const std::unique_ptr<Event>& curr) { + return analyzer.reachable.count( + ModuleElement(ModuleElementKind::Event, + curr->name)) == 0; + }), + v.end()); + } module->updateMaps(); // Handle the memory and table if (!exportsMemory && !analyzer.usesMemory) { @@ -272,6 +288,9 @@ struct RemoveUnusedModuleElements : public Pass { for (auto* call : analyzer.indirectCalls) { call->fullType = canonicalize(call->fullType); } + for (auto* event : analyzer.events) { + event->type = canonicalize(event->type); + } // remove no-longer used types module->functionTypes.erase( std::remove_if(module->functionTypes.begin(), |