| //===-- ModuleSummaryIndex.cpp - Module Summary Index ---------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements the module index and summary classes for the |
| // IR library. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/IR/ModuleSummaryIndex.h" |
| #include "llvm/ADT/StringMap.h" |
| using namespace llvm; |
| |
| // Create the combined module index/summary from multiple |
| // per-module instances. |
| void ModuleSummaryIndex::mergeFrom(std::unique_ptr<ModuleSummaryIndex> Other, |
| uint64_t NextModuleId) { |
| |
| StringRef ModPath; |
| for (auto &OtherGlobalValSummaryLists : *Other) { |
| GlobalValue::GUID ValueGUID = OtherGlobalValSummaryLists.first; |
| GlobalValueSummaryList &List = OtherGlobalValSummaryLists.second; |
| |
| // Assert that the value summary list only has one entry, since we shouldn't |
| // have duplicate names within a single per-module index. |
| assert(List.size() == 1); |
| std::unique_ptr<GlobalValueSummary> Summary = std::move(List.front()); |
| |
| // Add the module path string ref for this module if we haven't already |
| // saved a reference to it. |
| if (ModPath.empty()) { |
| auto Path = Summary->modulePath(); |
| ModPath = addModulePath(Path, NextModuleId, Other->getModuleHash(Path)) |
| ->first(); |
| } else |
| assert(ModPath == Summary->modulePath() && |
| "Each module in the combined map should have a unique ID"); |
| |
| // Note the module path string ref was copied above and is still owned by |
| // the original per-module index. Reset it to the new module path |
| // string reference owned by the combined index. |
| Summary->setModulePath(ModPath); |
| |
| // Add new value summary to existing list. There may be duplicates when |
| // combining GlobalValueMap entries, due to COMDAT values. Any local |
| // values were given unique global IDs. |
| addGlobalValueSummary(ValueGUID, std::move(Summary)); |
| } |
| } |
| |
| void ModuleSummaryIndex::removeEmptySummaryEntries() { |
| for (auto MI = begin(), MIE = end(); MI != MIE;) { |
| // Only expect this to be called on a per-module index, which has a single |
| // entry per value entry list. |
| assert(MI->second.size() == 1); |
| if (!MI->second[0]) |
| MI = GlobalValueMap.erase(MI); |
| else |
| ++MI; |
| } |
| } |
| |
| // Collect for the given module the list of function it defines |
| // (GUID -> Summary). |
| void ModuleSummaryIndex::collectDefinedFunctionsForModule( |
| StringRef ModulePath, GVSummaryMapTy &GVSummaryMap) const { |
| for (auto &GlobalList : *this) { |
| auto GUID = GlobalList.first; |
| for (auto &GlobSummary : GlobalList.second) { |
| auto *Summary = dyn_cast_or_null<FunctionSummary>(GlobSummary.get()); |
| if (!Summary) |
| // Ignore global variable, focus on functions |
| continue; |
| // Ignore summaries from other modules. |
| if (Summary->modulePath() != ModulePath) |
| continue; |
| GVSummaryMap[GUID] = Summary; |
| } |
| } |
| } |
| |
| // Collect for each module the list of function it defines (GUID -> Summary). |
| void ModuleSummaryIndex::collectDefinedGVSummariesPerModule( |
| StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const { |
| for (auto &GlobalList : *this) { |
| auto GUID = GlobalList.first; |
| for (auto &Summary : GlobalList.second) { |
| ModuleToDefinedGVSummaries[Summary->modulePath()][GUID] = Summary.get(); |
| } |
| } |
| } |
| |
| GlobalValueSummary * |
| ModuleSummaryIndex::getGlobalValueSummary(uint64_t ValueGUID, |
| bool PerModuleIndex) const { |
| auto SummaryList = findGlobalValueSummaryList(ValueGUID); |
| assert(SummaryList != end() && "GlobalValue not found in index"); |
| assert((!PerModuleIndex || SummaryList->second.size() == 1) && |
| "Expected a single entry per global value in per-module index"); |
| auto &Summary = SummaryList->second[0]; |
| return Summary.get(); |
| } |