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 if (Other->modulePaths().empty()) 24 return; 25 26 assert(Other->modulePaths().size() == 1 && 27 "Can only merge from an single-module index at that time"); 28 29 StringRef OtherModPath = Other->modulePaths().begin()->first(); 30 StringRef ModPath = addModulePath(OtherModPath, NextModuleId, 31 Other->getModuleHash(OtherModPath)) 32 ->first(); 33 34 for (auto &OtherGlobalValSummaryLists : *Other) { 35 GlobalValue::GUID ValueGUID = OtherGlobalValSummaryLists.first; 36 GlobalValueSummaryList &List = OtherGlobalValSummaryLists.second; 37 38 // Assert that the value summary list only has one entry, since we shouldn't 39 // have duplicate names within a single per-module index. 40 assert(List.size() == 1); 41 std::unique_ptr<GlobalValueSummary> Summary = std::move(List.front()); 42 43 // Note the module path string ref was copied above and is still owned by 44 // the original per-module index. Reset it to the new module path 45 // string reference owned by the combined index. 46 Summary->setModulePath(ModPath); 47 48 // Add new value summary to existing list. There may be duplicates when 49 // combining GlobalValueMap entries, due to COMDAT values. Any local 50 // values were given unique global IDs. 51 addGlobalValueSummary(ValueGUID, std::move(Summary)); 52 } 53 } 54 55 void ModuleSummaryIndex::removeEmptySummaryEntries() { 56 for (auto MI = begin(), MIE = end(); MI != MIE;) { 57 // Only expect this to be called on a per-module index, which has a single 58 // entry per value entry list. 59 assert(MI->second.size() == 1); 60 if (!MI->second[0]) 61 MI = GlobalValueMap.erase(MI); 62 else 63 ++MI; 64 } 65 } 66 67 // Collect for the given module the list of function it defines 68 // (GUID -> Summary). 69 void ModuleSummaryIndex::collectDefinedFunctionsForModule( 70 StringRef ModulePath, GVSummaryMapTy &GVSummaryMap) const { 71 for (auto &GlobalList : *this) { 72 auto GUID = GlobalList.first; 73 for (auto &GlobSummary : GlobalList.second) { 74 auto *Summary = dyn_cast_or_null<FunctionSummary>(GlobSummary.get()); 75 if (!Summary) 76 // Ignore global variable, focus on functions 77 continue; 78 // Ignore summaries from other modules. 79 if (Summary->modulePath() != ModulePath) 80 continue; 81 GVSummaryMap[GUID] = Summary; 82 } 83 } 84 } 85 86 // Collect for each module the list of function it defines (GUID -> Summary). 87 void ModuleSummaryIndex::collectDefinedGVSummariesPerModule( 88 StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const { 89 for (auto &GlobalList : *this) { 90 auto GUID = GlobalList.first; 91 for (auto &Summary : GlobalList.second) { 92 ModuleToDefinedGVSummaries[Summary->modulePath()][GUID] = Summary.get(); 93 } 94 } 95 } 96 97 GlobalValueSummary * 98 ModuleSummaryIndex::getGlobalValueSummary(uint64_t ValueGUID, 99 bool PerModuleIndex) const { 100 auto SummaryList = findGlobalValueSummaryList(ValueGUID); 101 assert(SummaryList != end() && "GlobalValue not found in index"); 102 assert((!PerModuleIndex || SummaryList->second.size() == 1) && 103 "Expected a single entry per global value in per-module index"); 104 auto &Summary = SummaryList->second[0]; 105 return Summary.get(); 106 } 107