/* * Copyright 2016 WebAssembly Community Group participants * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // // Removes functions that are never used. // #include #include "wasm.h" #include "pass.h" #include "ast_utils.h" namespace wasm { struct RemoveUnusedFunctions : public Pass { void run(PassRunner* runner, Module* module) override { std::vector root; // Module start is a root. if (module->start.is()) { root.push_back(module->getFunction(module->start)); } // Exports are roots. for (auto& curr : module->exports) { root.push_back(module->getFunction(curr->value)); } // For now, all functions that can be called indirectly are marked as roots. for (auto& segment : module->table.segments) { for (auto& curr : segment.data) { root.push_back(module->getFunction(curr)); } } // Compute function reachability starting from the root set. DirectCallGraphAnalyzer analyzer(module, root); // Remove unreachable functions. auto& v = module->functions; v.erase(std::remove_if(v.begin(), v.end(), [&](const std::unique_ptr& curr) { return analyzer.reachable.count(curr.get()) == 0; }), v.end()); assert(module->functions.size() == analyzer.reachable.size()); module->updateFunctionsMap(); } }; Pass *createRemoveUnusedFunctionsPass() { return new RemoveUnusedFunctions(); } } // namespace wasm