xref: /aosp_15_r20/external/llvm/lib/IR/ModuleSummaryIndex.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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