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" 17using namespace llvm; 18 19// Create the combined module index/summary from multiple 20// per-module instances. 21void 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 56void 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). 70void 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). 88void 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 98GlobalValueSummary * 99ModuleSummaryIndex::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