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 &OtherGlobalValInfoLists : *Other) {
26     GlobalValue::GUID ValueGUID = OtherGlobalValInfoLists.first;
27     GlobalValueInfoList &List = OtherGlobalValInfoLists.second;
28 
29     // Assert that the value info 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<GlobalValueInfo> Info = std::move(List.front());
33 
34     // Skip if there was no summary section.
35     if (!Info->summary())
36       continue;
37 
38     // Add the module path string ref for this module if we haven't already
39     // saved a reference to it.
40     if (ModPath.empty()) {
41       auto Path = Info->summary()->modulePath();
42       ModPath = addModulePath(Path, NextModuleId, Other->getModuleHash(Path))
43                     ->first();
44     } else
45       assert(ModPath == Info->summary()->modulePath() &&
46              "Each module in the combined map should have a unique ID");
47 
48     // Note the module path string ref was copied above and is still owned by
49     // the original per-module index. Reset it to the new module path
50     // string reference owned by the combined index.
51     Info->summary()->setModulePath(ModPath);
52 
53     // Add new value info to existing list. There may be duplicates when
54     // combining GlobalValueMap entries, due to COMDAT values. Any local
55     // values were given unique global IDs.
56     addGlobalValueInfo(ValueGUID, std::move(Info));
57   }
58 }
59 
60 void ModuleSummaryIndex::removeEmptySummaryEntries() {
61   for (auto MI = begin(), MIE = end(); MI != MIE;) {
62     // Only expect this to be called on a per-module index, which has a single
63     // entry per value entry list.
64     assert(MI->second.size() == 1);
65     if (!MI->second[0]->summary())
66       MI = GlobalValueMap.erase(MI);
67     else
68       ++MI;
69   }
70 }
71 
72 // Collect for the given module the list of function it defines
73 // (GUID -> Summary).
74 void ModuleSummaryIndex::collectDefinedFunctionsForModule(
75     StringRef ModulePath,
76     std::map<GlobalValue::GUID, GlobalValueSummary *> &FunctionInfoMap) const {
77   for (auto &GlobalList : *this) {
78     auto GUID = GlobalList.first;
79     for (auto &GlobInfo : GlobalList.second) {
80       auto *Summary = dyn_cast_or_null<FunctionSummary>(GlobInfo->summary());
81       if (!Summary)
82         // Ignore global variable, focus on functions
83         continue;
84       // Ignore summaries from other modules.
85       if (Summary->modulePath() != ModulePath)
86         continue;
87       FunctionInfoMap[GUID] = Summary;
88     }
89   }
90 }
91 
92 // Collect for each module the list of function it defines (GUID -> Summary).
93 void ModuleSummaryIndex::collectDefinedGVSummariesPerModule(
94     StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>> &
95         Module2FunctionInfoMap) const {
96   for (auto &GlobalList : *this) {
97     auto GUID = GlobalList.first;
98     for (auto &GlobInfo : GlobalList.second) {
99       auto *Summary = GlobInfo->summary();
100       Module2FunctionInfoMap[Summary->modulePath()][GUID] = Summary;
101     }
102   }
103 }
104 
105 GlobalValueInfo *
106 ModuleSummaryIndex::getGlobalValueInfo(uint64_t ValueGUID,
107                                        bool PerModuleIndex) const {
108   auto InfoList = findGlobalValueInfoList(ValueGUID);
109   assert(InfoList != end() && "GlobalValue not found in index");
110   assert((!PerModuleIndex || InfoList->second.size() == 1) &&
111          "Expected a single entry per global value in per-module index");
112   auto &Info = InfoList->second[0];
113   return Info.get();
114 }
115