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