1 //===-- ModuleSummaryIndex.cpp - Module Summary Index ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the module index and summary classes for the 11 // IR library. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/IR/ModuleSummaryIndex.h" 16 #include "llvm/ADT/StringMap.h" 17 using namespace llvm; 18 19 // Create the combined module index/summary from multiple 20 // per-module instances. 21 void ModuleSummaryIndex::mergeFrom(std::unique_ptr<ModuleSummaryIndex> Other, 22 uint64_t NextModuleId) { 23 24 StringRef ModPath; 25 for (auto &OtherGlobalValSummaryLists : *Other) { 26 GlobalValue::GUID ValueGUID = OtherGlobalValSummaryLists.first; 27 GlobalValueSummaryList &List = OtherGlobalValSummaryLists.second; 28 29 // Assert that the value summary list only has one entry, since we shouldn't 30 // have duplicate names within a single per-module index. 31 assert(List.size() == 1); 32 std::unique_ptr<GlobalValueSummary> Summary = std::move(List.front()); 33 34 // Add the module path string ref for this module if we haven't already 35 // saved a reference to it. 36 if (ModPath.empty()) { 37 auto Path = Summary->modulePath(); 38 ModPath = addModulePath(Path, NextModuleId, Other->getModuleHash(Path)) 39 ->first(); 40 } else 41 assert(ModPath == Summary->modulePath() && 42 "Each module in the combined map should have a unique ID"); 43 44 // Note the module path string ref was copied above and is still owned by 45 // the original per-module index. Reset it to the new module path 46 // string reference owned by the combined index. 47 Summary->setModulePath(ModPath); 48 49 // Add new value summary to existing list. There may be duplicates when 50 // combining GlobalValueMap entries, due to COMDAT values. Any local 51 // values were given unique global IDs. 52 addGlobalValueSummary(ValueGUID, std::move(Summary)); 53 } 54 } 55 56 void ModuleSummaryIndex::removeEmptySummaryEntries() { 57 for (auto MI = begin(), MIE = end(); MI != MIE;) { 58 // Only expect this to be called on a per-module index, which has a single 59 // entry per value entry list. 60 assert(MI->second.size() == 1); 61 if (!MI->second[0]) 62 MI = GlobalValueMap.erase(MI); 63 else 64 ++MI; 65 } 66 } 67 68 // Collect for the given module the list of function it defines 69 // (GUID -> Summary). 70 void ModuleSummaryIndex::collectDefinedFunctionsForModule( 71 StringRef ModulePath, GVSummaryMapTy &GVSummaryMap) const { 72 for (auto &GlobalList : *this) { 73 auto GUID = GlobalList.first; 74 for (auto &GlobSummary : GlobalList.second) { 75 auto *Summary = dyn_cast_or_null<FunctionSummary>(GlobSummary.get()); 76 if (!Summary) 77 // Ignore global variable, focus on functions 78 continue; 79 // Ignore summaries from other modules. 80 if (Summary->modulePath() != ModulePath) 81 continue; 82 GVSummaryMap[GUID] = Summary; 83 } 84 } 85 } 86 87 // Collect for each module the list of function it defines (GUID -> Summary). 88 void ModuleSummaryIndex::collectDefinedGVSummariesPerModule( 89 StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const { 90 for (auto &GlobalList : *this) { 91 auto GUID = GlobalList.first; 92 for (auto &Summary : GlobalList.second) { 93 ModuleToDefinedGVSummaries[Summary->modulePath()][GUID] = Summary.get(); 94 } 95 } 96 } 97 98 GlobalValueSummary * 99 ModuleSummaryIndex::getGlobalValueSummary(uint64_t ValueGUID, 100 bool PerModuleIndex) const { 101 auto SummaryList = findGlobalValueSummaryList(ValueGUID); 102 assert(SummaryList != end() && "GlobalValue not found in index"); 103 assert((!PerModuleIndex || SummaryList->second.size() == 1) && 104 "Expected a single entry per global value in per-module index"); 105 auto &Summary = SummaryList->second[0]; 106 return Summary.get(); 107 } 108