llvm.org GIT mirror llvm / 1c442aa
Revert "IR: Use pointers instead of GUIDs to represent edges in the module summary. NFCI." This reverts commit r302108. This causes crash in clang bootstrap with LTO. Contacted the auther in the original commit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302140 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Liu 2 years ago
13 changed file(s) with 232 addition(s) and 219 deletion(s). Raw diff Collapse all Expand all
4444 }
4545 };
4646
47 class GlobalValueSummary;
48
49 typedef std::vector> GlobalValueSummaryList;
50
51 struct GlobalValueSummaryInfo {
52 /// The GlobalValue corresponding to this summary. This is only used in
53 /// per-module summaries.
54 const GlobalValue *GV = nullptr;
55
56 /// List of global value summary structures for a particular value held
57 /// in the GlobalValueMap. Requires a vector in the case of multiple
58 /// COMDAT values of the same name.
59 GlobalValueSummaryList SummaryList;
60 };
61
62 /// Map from global value GUID to corresponding summary structures. Use a
63 /// std::map rather than a DenseMap so that pointers to the map's value_type
64 /// (which are used by ValueInfo) are not invalidated by insertion. Also it will
65 /// likely incur less overhead, as the value type is not very small and the size
66 /// of the map is unknown, resulting in inefficiencies due to repeated
67 /// insertions and resizing.
68 typedef std::map
69 GlobalValueSummaryMapTy;
70
71 /// Struct that holds a reference to a particular GUID in a global value
72 /// summary.
47 /// Struct to hold value either by GUID or GlobalValue*. Values in combined
48 /// indexes as well as indirect calls are GUIDs, all others are GlobalValues.
7349 struct ValueInfo {
74 const GlobalValueSummaryMapTy::value_type *Ref = nullptr;
75 ValueInfo() = default;
76 ValueInfo(const GlobalValueSummaryMapTy::value_type *Ref) : Ref(Ref) {}
77 operator bool() const { return Ref; }
78
79 GlobalValue::GUID getGUID() const { return Ref->first; }
80 const GlobalValue *getValue() const { return Ref->second.GV; }
81 ArrayRef> getSummaryList() const {
82 return Ref->second.SummaryList;
83 }
50 /// The value representation used in this instance.
51 enum ValueInfoKind {
52 VI_GUID,
53 VI_Value,
54 };
55
56 /// Union of the two possible value types.
57 union ValueUnion {
58 GlobalValue::GUID Id;
59 const GlobalValue *GV;
60 ValueUnion(GlobalValue::GUID Id) : Id(Id) {}
61 ValueUnion(const GlobalValue *GV) : GV(GV) {}
62 };
63
64 /// The value being represented.
65 ValueUnion TheValue;
66 /// The value representation.
67 ValueInfoKind Kind;
68 /// Constructor for a GUID value
69 ValueInfo(GlobalValue::GUID Id = 0) : TheValue(Id), Kind(VI_GUID) {}
70 /// Constructor for a GlobalValue* value
71 ValueInfo(const GlobalValue *V) : TheValue(V), Kind(VI_Value) {}
72 /// Accessor for GUID value
73 GlobalValue::GUID getGUID() const {
74 assert(Kind == VI_GUID && "Not a GUID type");
75 return TheValue.Id;
76 }
77 /// Accessor for GlobalValue* value
78 const GlobalValue *getValue() const {
79 assert(Kind == VI_Value && "Not a Value type");
80 return TheValue.GV;
81 }
82 bool isGUID() const { return Kind == VI_GUID; }
8483 };
8584
8685 template <> struct DenseMapInfo {
87 static inline ValueInfo getEmptyKey() {
88 return ValueInfo((GlobalValueSummaryMapTy::value_type *)-1);
89 }
86 static inline ValueInfo getEmptyKey() { return ValueInfo((GlobalValue *)-1); }
9087 static inline ValueInfo getTombstoneKey() {
91 return ValueInfo((GlobalValueSummaryMapTy::value_type *)-2);
92 }
93 static bool isEqual(ValueInfo L, ValueInfo R) { return L.Ref == R.Ref; }
94 static unsigned getHashValue(ValueInfo I) { return (uintptr_t)I.Ref; }
88 return ValueInfo((GlobalValue *)-2);
89 }
90 static bool isEqual(ValueInfo L, ValueInfo R) {
91 if (L.isGUID() != R.isGUID())
92 return false;
93 return L.isGUID() ? (L.getGUID() == R.getGUID())
94 : (L.getValue() == R.getValue());
95 }
96 static unsigned getHashValue(ValueInfo I) {
97 return I.isGUID() ? I.getGUID() : (uintptr_t)I.getValue();
98 }
9599 };
96100
97101 /// \brief Function and variable summary information to aid decisions and
478482 /// 160 bits SHA1
479483 typedef std::array ModuleHash;
480484
485 /// List of global value summary structures for a particular value held
486 /// in the GlobalValueMap. Requires a vector in the case of multiple
487 /// COMDAT values of the same name.
488 typedef std::vector> GlobalValueSummaryList;
489
490 /// Map from global value GUID to corresponding summary structures.
491 /// Use a std::map rather than a DenseMap since it will likely incur
492 /// less overhead, as the value type is not very small and the size
493 /// of the map is unknown, resulting in inefficiencies due to repeated
494 /// insertions and resizing.
495 typedef std::map
496 GlobalValueSummaryMapTy;
497
481498 /// Type used for iterating through the global value summary map.
482499 typedef GlobalValueSummaryMapTy::const_iterator const_gvsummary_iterator;
483500 typedef GlobalValueSummaryMapTy::iterator gvsummary_iterator;
514531 // YAML I/O support.
515532 friend yaml::MappingTraits;
516533
517 GlobalValueSummaryMapTy::value_type *
518 getOrInsertValuePtr(GlobalValue::GUID GUID) {
519 return &*GlobalValueMap.emplace(GUID, GlobalValueSummaryInfo{}).first;
520 }
521
522534 public:
523535 gvsummary_iterator begin() { return GlobalValueMap.begin(); }
524536 const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); }
526538 const_gvsummary_iterator end() const { return GlobalValueMap.end(); }
527539 size_t size() const { return GlobalValueMap.size(); }
528540
529 /// Return a ValueInfo for GUID if it exists, otherwise return ValueInfo().
530 ValueInfo getValueInfo(GlobalValue::GUID GUID) const {
531 auto I = GlobalValueMap.find(GUID);
532 return ValueInfo(I == GlobalValueMap.end() ? nullptr : &*I);
533 }
534
535 /// Return a ValueInfo for \p GUID.
536 ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID) {
537 return ValueInfo(getOrInsertValuePtr(GUID));
538 }
539
540 /// Return a ValueInfo for \p GV and mark it as belonging to GV.
541 ValueInfo getOrInsertValueInfo(const GlobalValue *GV) {
542 auto VP = getOrInsertValuePtr(GV->getGUID());
543 VP->second.GV = GV;
544 return ValueInfo(VP);
541 /// Get the list of global value summary objects for a given value name.
542 const GlobalValueSummaryList &getGlobalValueSummaryList(StringRef ValueName) {
543 return GlobalValueMap[GlobalValue::getGUID(ValueName)];
544 }
545
546 /// Get the list of global value summary objects for a given value name.
547 const const_gvsummary_iterator
548 findGlobalValueSummaryList(StringRef ValueName) const {
549 return GlobalValueMap.find(GlobalValue::getGUID(ValueName));
550 }
551
552 /// Get the list of global value summary objects for a given value GUID.
553 const const_gvsummary_iterator
554 findGlobalValueSummaryList(GlobalValue::GUID ValueGUID) const {
555 return GlobalValueMap.find(ValueGUID);
545556 }
546557
547558 /// Return the GUID for \p OriginalId in the OidGuidMap.
553564 /// Add a global value summary for a value of the given name.
554565 void addGlobalValueSummary(StringRef ValueName,
555566 std::unique_ptr Summary) {
556 addGlobalValueSummary(getOrInsertValueInfo(GlobalValue::getGUID(ValueName)),
557 std::move(Summary));
558 }
559
560 /// Add a global value summary for the given ValueInfo.
561 void addGlobalValueSummary(ValueInfo VI,
567 addOriginalName(GlobalValue::getGUID(ValueName),
568 Summary->getOriginalName());
569 GlobalValueMap[GlobalValue::getGUID(ValueName)].push_back(
570 std::move(Summary));
571 }
572
573 /// Add a global value summary for a value of the given GUID.
574 void addGlobalValueSummary(GlobalValue::GUID ValueGUID,
562575 std::unique_ptr Summary) {
563 addOriginalName(VI.getGUID(), Summary->getOriginalName());
564 // Here we have a notionally const VI, but the value it points to is owned
565 // by the non-const *this.
566 const_cast(VI.Ref)
567 ->second.SummaryList.push_back(std::move(Summary));
576 addOriginalName(ValueGUID, Summary->getOriginalName());
577 GlobalValueMap[ValueGUID].push_back(std::move(Summary));
568578 }
569579
570580 /// Add an original name for the value of the given GUID.
582592 /// not found.
583593 GlobalValueSummary *findSummaryInModule(GlobalValue::GUID ValueGUID,
584594 StringRef ModuleId) const {
585 auto CalleeInfo = getValueInfo(ValueGUID);
586 if (!CalleeInfo) {
595 auto CalleeInfoList = findGlobalValueSummaryList(ValueGUID);
596 if (CalleeInfoList == end()) {
587597 return nullptr; // This function does not have a summary
588598 }
589599 auto Summary =
590 llvm::find_if(CalleeInfo.getSummaryList(),
600 llvm::find_if(CalleeInfoList->second,
591601 [&](const std::unique_ptr &Summary) {
592602 return Summary->modulePath() == ModuleId;
593603 });
594 if (Summary == CalleeInfo.getSummaryList().end())
604 if (Summary == CalleeInfoList->second.end())
595605 return nullptr;
596606 return Summary->get();
597607 }
200200 for (auto &FSum : FSums) {
201201 GlobalValueSummary::GVFlags GVFlags(GlobalValue::ExternalLinkage, false,
202202 false);
203 Elem.SummaryList.push_back(llvm::make_unique(
203 Elem.push_back(llvm::make_unique(
204204 GVFlags, 0, ArrayRef{},
205205 ArrayRef{}, std::move(FSum.TypeTests),
206206 std::move(FSum.TypeTestAssumeVCalls),
212212 static void output(IO &io, GlobalValueSummaryMapTy &V) {
213213 for (auto &P : V) {
214214 std::vector FSums;
215 for (auto &Sum : P.second.SummaryList) {
215 for (auto &Sum : P.second) {
216216 if (auto *FSum = dyn_cast(Sum.get()))
217217 FSums.push_back(FunctionSummaryYaml{
218218 FSum->type_tests(), FSum->type_test_assume_vcalls(),
3636 // Walk through the operands of a given User via worklist iteration and populate
3737 // the set of GlobalValue references encountered. Invoked either on an
3838 // Instruction or a GlobalVariable (which walks its initializer).
39 static void findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
40 SetVector &RefEdges,
39 static void findRefEdges(const User *CurUser, SetVector &RefEdges,
4140 SmallPtrSet &Visited) {
4241 SmallVector Worklist;
4342 Worklist.push_back(CurUser);
6160 // the reference set unless it is a callee. Callees are handled
6261 // specially by WriteFunction and are added to a separate list.
6362 if (!(CS && CS.isCallee(&OI)))
64 RefEdges.insert(Index.getOrInsertValueInfo(GV));
63 RefEdges.insert(GV);
6564 continue;
6665 }
6766 Worklist.push_back(Operand);
198197 if (isa(I))
199198 continue;
200199 ++NumInsts;
201 findRefEdges(Index, &I, RefEdges, Visited);
200 findRefEdges(&I, RefEdges, Visited);
202201 auto CS = ImmutableCallSite(&I);
203202 if (!CS)
204203 continue;
239238 // to record the call edge to the alias in that case. Eventually
240239 // an alias summary will be created to associate the alias and
241240 // aliasee.
242 CallGraphEdges[Index.getOrInsertValueInfo(
243 cast(CalledValue))]
244 .updateHotness(Hotness);
241 CallGraphEdges[cast(CalledValue)].updateHotness(Hotness);
245242 } else {
246243 // Skip inline assembly calls.
247244 if (CI && CI->isInlineAsm())
256253 ICallAnalysis.getPromotionCandidatesForInstruction(
257254 &I, NumVals, TotalCount, NumCandidates);
258255 for (auto &Candidate : CandidateProfileData)
259 CallGraphEdges[Index.getOrInsertValueInfo(Candidate.Value)]
260 .updateHotness(getHotness(Candidate.Count, PSI));
256 CallGraphEdges[Candidate.Value].updateHotness(
257 getHotness(Candidate.Count, PSI));
261258 }
262259 }
263260
264261 // Explicit add hot edges to enforce importing for designated GUIDs for
265262 // sample PGO, to enable the same inlines as the profiled optimized binary.
266263 for (auto &I : F.getImportGUIDs())
267 CallGraphEdges[Index.getOrInsertValueInfo(I)].updateHotness(
268 CalleeInfo::HotnessType::Hot);
264 CallGraphEdges[I].updateHotness(CalleeInfo::HotnessType::Hot);
269265
270266 bool NonRenamableLocal = isNonRenamableLocal(F);
271267 bool NotEligibleForImport =
291287 DenseSet &CantBePromoted) {
292288 SetVector RefEdges;
293289 SmallPtrSet Visited;
294 findRefEdges(Index, &V, RefEdges, Visited);
290 findRefEdges(&V, RefEdges, Visited);
295291 bool NonRenamableLocal = isNonRenamableLocal(V);
296292 GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
297293 /* LiveRoot = */ false);
320316
321317 // Set LiveRoot flag on entries matching the given value name.
322318 static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name) {
323 if (ValueInfo VI = Index.getValueInfo(GlobalValue::getGUID(Name)))
324 for (auto &Summary : VI.getSummaryList())
325 Summary->setLiveRoot();
319 auto SummaryList =
320 Index.findGlobalValueSummaryList(GlobalValue::getGUID(Name));
321 if (SummaryList == Index.end())
322 return;
323 for (auto &Summary : SummaryList->second)
324 Summary->setLiveRoot();
326325 }
327326
328327 ModuleSummaryIndex llvm::buildModuleSummaryIndex(
446445 }
447446
448447 for (auto &GlobalList : Index) {
449 // Ignore entries for references that are undefined in the current module.
450 if (GlobalList.second.SummaryList.empty())
451 continue;
452
453 assert(GlobalList.second.SummaryList.size() == 1 &&
448 assert(GlobalList.second.size() == 1 &&
454449 "Expected module's index to have one summary per GUID");
455 auto &Summary = GlobalList.second.SummaryList[0];
450 auto &Summary = GlobalList.second[0];
456451 bool AllRefsCanBeExternallyReferenced =
457452 llvm::all_of(Summary->refs(), [&](const ValueInfo &VI) {
458 return !CantBePromoted.count(VI.getGUID());
453 return !CantBePromoted.count(VI.getValue()->getGUID());
459454 });
460455 if (!AllRefsCanBeExternallyReferenced) {
461456 Summary->setNotEligibleToImport();
465460 if (auto *FuncSummary = dyn_cast(Summary.get())) {
466461 bool AllCallsCanBeExternallyReferenced = llvm::all_of(
467462 FuncSummary->calls(), [&](const FunctionSummary::EdgeTy &Edge) {
468 return !CantBePromoted.count(Edge.first.getGUID());
463 auto GUID = Edge.first.isGUID() ? Edge.first.getGUID()
464 : Edge.first.getValue()->getGUID();
465 return !CantBePromoted.count(GUID);
469466 });
470467 if (!AllCallsCanBeExternallyReferenced)
471468 Summary->setNotEligibleToImport();
693693 /// Used to enable on-demand parsing of the VST.
694694 uint64_t VSTOffset = 0;
695695
696 // Map to save ValueId to ValueInfo association that was recorded in the
696 // Map to save ValueId to GUID association that was recorded in the
697697 // ValueSymbolTable. It is used after the VST is parsed to convert
698698 // call graph edges read from the function summary from referencing
699 // callees by their ValueId to using the ValueInfo instead, which is how
699 // callees by their ValueId to using the GUID instead, which is how
700700 // they are recorded in the summary index being built.
701 // We save a GUID which refers to the same global as the ValueInfo, but
702 // ignoring the linkage, i.e. for values other than local linkage they are
703 // identical.
704 DenseMap>
705 ValueIdToValueInfoMap;
701 // We save a second GUID which is the same as the first one, but ignoring the
702 // linkage, i.e. for value other than local linkage they are identical.
703 DenseMap>
704 ValueIdToCallGraphGUIDMap;
706705
707706 /// Map populated during module path string table parsing, from the
708707 /// module ID to a string reference owned by the index's module
742741 Error parseEntireSummary();
743742 Error parseModuleStringTable();
744743
745 std::pair
746 getValueInfoFromValueId(unsigned ValueId);
744 std::pair
745 getGUIDFromValueId(unsigned ValueId);
747746
748747 ModulePathStringTableTy::iterator addThisModulePath();
749748 };
46974696 return TheIndex.addModulePath(ModulePath, ModuleId);
46984697 }
46994698
4700 std::pair
4701 ModuleSummaryIndexBitcodeReader::getValueInfoFromValueId(unsigned ValueId) {
4702 auto VGI = ValueIdToValueInfoMap[ValueId];
4703 assert(VGI.first);
4704 return VGI;
4699 std::pair
4700 ModuleSummaryIndexBitcodeReader::getGUIDFromValueId(unsigned ValueId) {
4701 auto VGI = ValueIdToCallGraphGUIDMap.find(ValueId);
4702 assert(VGI != ValueIdToCallGraphGUIDMap.end());
4703 return VGI->second;
47054704 }
47064705
47074706 void ModuleSummaryIndexBitcodeReader::setValueGUID(
47164715 if (PrintSummaryGUIDs)
47174716 dbgs() << "GUID " << ValueGUID << "(" << OriginalNameID << ") is "
47184717 << ValueName << "\n";
4719 ValueIdToValueInfoMap[ValueID] =
4720 std::make_pair(TheIndex.getOrInsertValueInfo(ValueGUID), OriginalNameID);
4718 ValueIdToCallGraphGUIDMap[ValueID] =
4719 std::make_pair(ValueGUID, OriginalNameID);
47214720 }
47224721
47234722 // Specialized value symbol table parser used when reading module index
47954794 GlobalValue::GUID RefGUID = Record[1];
47964795 // The "original name", which is the second value of the pair will be
47974796 // overriden later by a FS_COMBINED_ORIGINAL_NAME in the combined index.
4798 ValueIdToValueInfoMap[ValueID] =
4799 std::make_pair(TheIndex.getOrInsertValueInfo(RefGUID), RefGUID);
4797 ValueIdToCallGraphGUIDMap[ValueID] = std::make_pair(RefGUID, RefGUID);
48004798 break;
48014799 }
48024800 }
49414939 std::vector Ret;
49424940 Ret.reserve(Record.size());
49434941 for (uint64_t RefValueId : Record)
4944 Ret.push_back(getValueInfoFromValueId(RefValueId).first);
4942 Ret.push_back(getGUIDFromValueId(RefValueId).first);
49454943 return Ret;
49464944 }
49474945
49514949 Ret.reserve(Record.size());
49524950 for (unsigned I = 0, E = Record.size(); I != E; ++I) {
49534951 CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown;
4954 ValueInfo Callee = getValueInfoFromValueId(Record[I]).first;
4952 GlobalValue::GUID CalleeGUID = getGUIDFromValueId(Record[I]).first;
49554953 if (IsOldProfileFormat) {
49564954 I += 1; // Skip old callsitecount field
49574955 if (HasProfile)
49584956 I += 1; // Skip old profilecount field
49594957 } else if (HasProfile)
49604958 Hotness = static_cast(Record[++I]);
4961 Ret.push_back(FunctionSummary::EdgeTy{Callee, CalleeInfo{Hotness}});
4959 Ret.push_back(FunctionSummary::EdgeTy{CalleeGUID, CalleeInfo{Hotness}});
49624960 }
49634961 return Ret;
49644962 }
50285026 case bitc::FS_VALUE_GUID: { // [valueid, refguid]
50295027 uint64_t ValueID = Record[0];
50305028 GlobalValue::GUID RefGUID = Record[1];
5031 ValueIdToValueInfoMap[ValueID] =
5032 std::make_pair(TheIndex.getOrInsertValueInfo(RefGUID), RefGUID);
5029 ValueIdToCallGraphGUIDMap[ValueID] = std::make_pair(RefGUID, RefGUID);
50335030 break;
50345031 }
50355032 // FS_PERMODULE: [valueid, flags, instcount, numrefs, numrefs x valueid,
50705067 PendingTypeCheckedLoadVCalls.clear();
50715068 PendingTypeTestAssumeConstVCalls.clear();
50725069 PendingTypeCheckedLoadConstVCalls.clear();
5073 auto VIAndOriginalGUID = getValueInfoFromValueId(ValueID);
5070 auto GUID = getGUIDFromValueId(ValueID);
50745071 FS->setModulePath(addThisModulePath()->first());
5075 FS->setOriginalName(VIAndOriginalGUID.second);
5076 TheIndex.addGlobalValueSummary(VIAndOriginalGUID.first, std::move(FS));
5072 FS->setOriginalName(GUID.second);
5073 TheIndex.addGlobalValueSummary(GUID.first, std::move(FS));
50775074 break;
50785075 }
50795076 // FS_ALIAS: [valueid, flags, valueid]
50935090 // ownership.
50945091 AS->setModulePath(addThisModulePath()->first());
50955092
5096 GlobalValue::GUID AliaseeGUID =
5097 getValueInfoFromValueId(AliaseeID).first.getGUID();
5093 GlobalValue::GUID AliaseeGUID = getGUIDFromValueId(AliaseeID).first;
50985094 auto AliaseeInModule =
50995095 TheIndex.findSummaryInModule(AliaseeGUID, ModulePath);
51005096 if (!AliaseeInModule)
51015097 return error("Alias expects aliasee summary to be parsed");
51025098 AS->setAliasee(AliaseeInModule);
51035099
5104 auto GUID = getValueInfoFromValueId(ValueID);
5100 auto GUID = getGUIDFromValueId(ValueID);
51055101 AS->setOriginalName(GUID.second);
51065102 TheIndex.addGlobalValueSummary(GUID.first, std::move(AS));
51075103 break;
51155111 makeRefList(ArrayRef(Record).slice(2));
51165112 auto FS = llvm::make_unique(Flags, std::move(Refs));
51175113 FS->setModulePath(addThisModulePath()->first());
5118 auto GUID = getValueInfoFromValueId(ValueID);
5114 auto GUID = getGUIDFromValueId(ValueID);
51195115 FS->setOriginalName(GUID.second);
51205116 TheIndex.addGlobalValueSummary(GUID.first, std::move(FS));
51215117 break;
51425138 std::vector Edges = makeCallList(
51435139 ArrayRef(Record).slice(CallGraphEdgeStartIndex),
51445140 IsOldProfileFormat, HasProfile);
5145 ValueInfo VI = getValueInfoFromValueId(ValueID).first;
5141 GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first;
51465142 auto FS = llvm::make_unique(
51475143 Flags, InstCount, std::move(Refs), std::move(Edges),
51485144 std::move(PendingTypeTests), std::move(PendingTypeTestAssumeVCalls),
51555151 PendingTypeTestAssumeConstVCalls.clear();
51565152 PendingTypeCheckedLoadConstVCalls.clear();
51575153 LastSeenSummary = FS.get();
5158 LastSeenGUID = VI.getGUID();
5154 LastSeenGUID = GUID;
51595155 FS->setModulePath(ModuleIdMap[ModuleId]);
5160 TheIndex.addGlobalValueSummary(VI, std::move(FS));
5156 TheIndex.addGlobalValueSummary(GUID, std::move(FS));
51615157 break;
51625158 }
51635159 // FS_COMBINED_ALIAS: [valueid, modid, flags, valueid]
51735169 LastSeenSummary = AS.get();
51745170 AS->setModulePath(ModuleIdMap[ModuleId]);
51755171
5176 auto AliaseeGUID =
5177 getValueInfoFromValueId(AliaseeValueId).first.getGUID();
5172 auto AliaseeGUID = getGUIDFromValueId(AliaseeValueId).first;
51785173 auto AliaseeInModule =
51795174 TheIndex.findSummaryInModule(AliaseeGUID, AS->modulePath());
51805175 if (!AliaseeInModule)
51815176 return error("Alias expects aliasee summary to be parsed");
51825177 AS->setAliasee(AliaseeInModule);
51835178
5184 ValueInfo VI = getValueInfoFromValueId(ValueID).first;
5185 LastSeenGUID = VI.getGUID();
5186 TheIndex.addGlobalValueSummary(VI, std::move(AS));
5179 GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first;
5180 LastSeenGUID = GUID;
5181 TheIndex.addGlobalValueSummary(GUID, std::move(AS));
51875182 break;
51885183 }
51895184 // FS_COMBINED_GLOBALVAR_INIT_REFS: [valueid, modid, flags, n x valueid]
51975192 auto FS = llvm::make_unique(Flags, std::move(Refs));
51985193 LastSeenSummary = FS.get();
51995194 FS->setModulePath(ModuleIdMap[ModuleId]);
5200 ValueInfo VI = getValueInfoFromValueId(ValueID).first;
5201 LastSeenGUID = VI.getGUID();
5202 TheIndex.addGlobalValueSummary(VI, std::move(FS));
5195 GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first;
5196 LastSeenGUID = GUID;
5197 TheIndex.addGlobalValueSummary(GUID, std::move(FS));
52035198 break;
52045199 }
52055200 // FS_COMBINED_ORIGINAL_NAME: [original_name]
155155 return;
156156 for (const auto &GUIDSummaryLists : *Index)
157157 // Examine all summaries for this GUID.
158 for (auto &Summary : GUIDSummaryLists.second.SummaryList)
158 for (auto &Summary : GUIDSummaryLists.second)
159159 if (auto FS = dyn_cast(Summary.get()))
160160 // For each call in the function summary, see if the call
161161 // is to a GUID (which means it is for an indirect call,
162162 // otherwise we would have a Value for it). If so, synthesize
163163 // a value id.
164164 for (auto &CallEdge : FS->calls())
165 if (!CallEdge.first.getValue())
165 if (CallEdge.first.isGUID())
166166 assignValueId(CallEdge.first.getGUID());
167167 }
168168
303303 }
304304 // Helper to get the valueId for the type of value recorded in VI.
305305 unsigned getValueId(ValueInfo VI) {
306 if (!VI.getValue())
306 if (VI.isGUID())
307307 return getValueId(VI.getGUID());
308308 return VE.getValueID(VI.getValue());
309309 }
357357 Callback(Summary);
358358 } else {
359359 for (auto &Summaries : Index)
360 for (auto &Summary : Summaries.second.SummaryList)
360 for (auto &Summary : Summaries.second)
361361 Callback({Summaries.first, Summary.get()});
362362 }
363363 }
32693269 void ModuleBitcodeWriter::writeModuleLevelReferences(
32703270 const GlobalVariable &V, SmallVector &NameVals,
32713271 unsigned FSModRefsAbbrev) {
3272 auto VI = Index->getValueInfo(GlobalValue::getGUID(V.getName()));
3273 if (!VI || VI.getSummaryList().empty()) {
3272 auto Summaries =
3273 Index->findGlobalValueSummaryList(GlobalValue::getGUID(V.getName()));
3274 if (Summaries == Index->end()) {
32743275 // Only declarations should not have a summary (a declaration might however
32753276 // have a summary if the def was in module level asm).
32763277 assert(V.isDeclaration());
32773278 return;
32783279 }
3279 auto *Summary = VI.getSummaryList()[0].get();
3280 auto *Summary = Summaries->second.front().get();
32803281 NameVals.push_back(VE.getValueID(&V));
32813282 GlobalVarSummary *VS = cast(Summary);
32823283 NameVals.push_back(getEncodedGVSummaryFlags(VS->flags()));
33653366 if (!F.hasName())
33663367 report_fatal_error("Unexpected anonymous function when writing summary");
33673368
3368 ValueInfo VI = Index->getValueInfo(GlobalValue::getGUID(F.getName()));
3369 if (!VI || VI.getSummaryList().empty()) {
3369 auto Summaries =
3370 Index->findGlobalValueSummaryList(GlobalValue::getGUID(F.getName()));
3371 if (Summaries == Index->end()) {
33703372 // Only declarations should not have a summary (a declaration might
33713373 // however have a summary if the def was in module level asm).
33723374 assert(F.isDeclaration());
33733375 continue;
33743376 }
3375 auto *Summary = VI.getSummaryList()[0].get();
3377 auto *Summary = Summaries->second.front().get();
33763378 writePerModuleFunctionSummaryRecord(NameVals, Summary, VE.getValueID(&F),
33773379 FSCallsAbbrev, FSCallsProfileAbbrev, F);
33783380 }
2121 StringRef ModulePath, GVSummaryMapTy &GVSummaryMap) const {
2222 for (auto &GlobalList : *this) {
2323 auto GUID = GlobalList.first;
24 for (auto &GlobSummary : GlobalList.second.SummaryList) {
24 for (auto &GlobSummary : GlobalList.second) {
2525 auto *Summary = dyn_cast_or_null(GlobSummary.get());
2626 if (!Summary)
2727 // Ignore global variable, focus on functions
3939 StringMap &ModuleToDefinedGVSummaries) const {
4040 for (auto &GlobalList : *this) {
4141 auto GUID = GlobalList.first;
42 for (auto &Summary : GlobalList.second.SummaryList) {
42 for (auto &Summary : GlobalList.second) {
4343 ModuleToDefinedGVSummaries[Summary->modulePath()][GUID] = Summary.get();
4444 }
4545 }
4848 GlobalValueSummary *
4949 ModuleSummaryIndex::getGlobalValueSummary(uint64_t ValueGUID,
5050 bool PerModuleIndex) const {
51 auto VI = getValueInfo(ValueGUID);
52 assert(VI && "GlobalValue not found in index");
53 assert((!PerModuleIndex || VI.getSummaryList().size() == 1) &&
51 auto SummaryList = findGlobalValueSummaryList(ValueGUID);
52 assert(SummaryList != end() && "GlobalValue not found in index");
53 assert((!PerModuleIndex || SummaryList->second.size() == 1) &&
5454 "Expected a single entry per global value in per-module index");
55 auto &Summary = VI.getSummaryList()[0];
55 auto &Summary = SummaryList->second[0];
5656 return Summary.get();
5757 }
273273 // when needed.
274274 DenseSet GlobalInvolvedWithAlias;
275275 for (auto &I : Index)
276 for (auto &S : I.second.SummaryList)
276 for (auto &S : I.second)
277277 if (auto AS = dyn_cast(S.get()))
278278 GlobalInvolvedWithAlias.insert(&AS->getAliasee());
279279
280280 for (auto &I : Index)
281 thinLTOResolveWeakForLinkerGUID(I.second.SummaryList, I.first,
282 GlobalInvolvedWithAlias, isPrevailing,
283 recordNewLinkage);
281 thinLTOResolveWeakForLinkerGUID(I.second, I.first, GlobalInvolvedWithAlias,
282 isPrevailing, recordNewLinkage);
284283 }
285284
286285 static void thinLTOInternalizeAndPromoteGUID(
301300 ModuleSummaryIndex &Index,
302301 function_ref isExported) {
303302 for (auto &I : Index)
304 thinLTOInternalizeAndPromoteGUID(I.second.SummaryList, I.first, isExported);
303 thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported);
305304 }
306305
307306 // Requires a destructor for std::vector.
118118 };
119119
120120 for (auto &I : Index) {
121 if (HasMultipleCopies(I.second.SummaryList))
122 PrevailingCopy[I.first] =
123 getFirstDefinitionForLinker(I.second.SummaryList);
121 if (HasMultipleCopies(I.second))
122 PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second);
124123 }
125124 }
126125
116116 /// - [insert you fancy metric here]
117117 static const GlobalValueSummary *
118118 selectCallee(const ModuleSummaryIndex &Index,
119 ArrayRef> CalleeSummaryList,
119 const GlobalValueSummaryList &CalleeSummaryList,
120120 unsigned Threshold, StringRef CallerModulePath) {
121121 auto It = llvm::find_if(
122122 CalleeSummaryList,
167167 return cast(It->get());
168168 }
169169
170 /// Return the summary for the function \p GUID that fits the \p Threshold, or
171 /// null if there's no match.
172 static const GlobalValueSummary *selectCallee(GlobalValue::GUID GUID,
173 unsigned Threshold,
174 const ModuleSummaryIndex &Index,
175 StringRef CallerModulePath) {
176 auto CalleeSummaryList = Index.findGlobalValueSummaryList(GUID);
177 if (CalleeSummaryList == Index.end())
178 return nullptr; // This function does not have a summary
179 return selectCallee(Index, CalleeSummaryList->second, Threshold,
180 CallerModulePath);
181 }
182
170183 using EdgeInfo = std::tuple
171184 GlobalValue::GUID>;
172185
180193 FunctionImporter::ImportMapTy &ImportList,
181194 StringMap *ExportLists = nullptr) {
182195 for (auto &Edge : Summary.calls()) {
183 ValueInfo VI = Edge.first;
184 DEBUG(dbgs() << " edge -> " << VI.getGUID() << " Threshold:" << Threshold
185 << "\n");
186
187 if (VI.getSummaryList().empty()) {
196 auto GUID = Edge.first.getGUID();
197 DEBUG(dbgs() << " edge -> " << GUID << " Threshold:" << Threshold << "\n");
198
199 if (Index.findGlobalValueSummaryList(GUID) == Index.end()) {
188200 // For SamplePGO, the indirect call targets for local functions will
189201 // have its original name annotated in profile. We try to find the
190202 // corresponding PGOFuncName as the GUID.
191 auto GUID = Index.getGUIDFromOriginalID(VI.getGUID());
203 GUID = Index.getGUIDFromOriginalID(GUID);
192204 if (GUID == 0)
193205 continue;
194 VI = Index.getValueInfo(GUID);
195 if (!VI)
196 continue;
197 }
198
199 if (DefinedGVSummaries.count(VI.getGUID())) {
206 }
207
208 if (DefinedGVSummaries.count(GUID)) {
200209 DEBUG(dbgs() << "ignored! Target already in destination module.\n");
201210 continue;
202211 }
212221 const auto NewThreshold =
213222 Threshold * GetBonusMultiplier(Edge.second.Hotness);
214223
215 auto *CalleeSummary = selectCallee(Index, VI.getSummaryList(), NewThreshold,
216 Summary.modulePath());
224 auto *CalleeSummary =
225 selectCallee(GUID, NewThreshold, Index, Summary.modulePath());
217226 if (!CalleeSummary) {
218227 DEBUG(dbgs() << "ignored! No qualifying callee with summary found.\n");
219228 continue;
245254 const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
246255
247256 auto ExportModulePath = ResolvedCalleeSummary->modulePath();
248 auto &ProcessedThreshold = ImportList[ExportModulePath][VI.getGUID()];
257 auto &ProcessedThreshold = ImportList[ExportModulePath][GUID];
249258 /// Since the traversal of the call graph is DFS, we can revisit a function
250259 /// a second time with a higher threshold. In this case, it is added back to
251260 /// the worklist with the new threshold.
261270 // Make exports in the source module.
262271 if (ExportLists) {
263272 auto &ExportList = (*ExportLists)[ExportModulePath];
264 ExportList.insert(VI.getGUID());
273 ExportList.insert(GUID);
265274 if (!PreviouslyImported) {
266275 // This is the first time this function was exported from its source
267276 // module, so mark all functions and globals it references as exported
281290 }
282291
283292 // Insert the newly imported function to the worklist.
284 Worklist.emplace_back(ResolvedCalleeSummary, AdjThreshold, VI.getGUID());
293 Worklist.emplace_back(ResolvedCalleeSummary, AdjThreshold, GUID);
285294 }
286295 }
287296
421430 if (GUIDPreservedSymbols.empty())
422431 // Don't do anything when nothing is live, this is friendly with tests.
423432 return DenseSet();
424 DenseSet LiveSymbols;
425 SmallVector Worklist;
426 Worklist.reserve(GUIDPreservedSymbols.size() * 2);
427 for (auto GUID : GUIDPreservedSymbols) {
428 ValueInfo VI = Index.getValueInfo(GUID);
429 if (!VI)
430 continue;
431 DEBUG(dbgs() << "Live root: " << VI.getGUID() << "\n");
432 LiveSymbols.insert(VI);
433 Worklist.push_back(VI);
433 DenseSet LiveSymbols = GUIDPreservedSymbols;
434 SmallVector Worklist;
435 Worklist.reserve(LiveSymbols.size() * 2);
436 for (auto GUID : LiveSymbols) {
437 DEBUG(dbgs() << "Live root: " << GUID << "\n");
438 Worklist.push_back(GUID);
434439 }
435440 // Add values flagged in the index as live roots to the worklist.
436441 for (const auto &Entry : Index) {
437442 bool IsLiveRoot = llvm::any_of(
438 Entry.second.SummaryList,
443 Entry.second,
439444 [&](const std::unique_ptr &Summary) {
440445 return Summary->liveRoot();
441446 });
442447 if (!IsLiveRoot)
443448 continue;
444449 DEBUG(dbgs() << "Live root (summary): " << Entry.first << "\n");
445 Worklist.push_back(ValueInfo(&Entry));
450 Worklist.push_back(Entry.first);
446451 }
447452
448453 while (!Worklist.empty()) {
449 auto VI = Worklist.pop_back_val();
454 auto GUID = Worklist.pop_back_val();
455 auto It = Index.findGlobalValueSummaryList(GUID);
456 if (It == Index.end()) {
457 DEBUG(dbgs() << "Not in index: " << GUID << "\n");
458 continue;
459 }
450460
451461 // FIXME: we should only make the prevailing copy live here
452 for (auto &Summary : VI.getSummaryList()) {
462 for (auto &Summary : It->second) {
453463 for (auto Ref : Summary->refs()) {
454 if (LiveSymbols.insert(Ref).second) {
455 DEBUG(dbgs() << "Marking live (ref): " << Ref.getGUID() << "\n");
456 Worklist.push_back(Ref);
464 auto RefGUID = Ref.getGUID();
465 if (LiveSymbols.insert(RefGUID).second) {
466 DEBUG(dbgs() << "Marking live (ref): " << RefGUID << "\n");
467 Worklist.push_back(RefGUID);
457468 }
458469 }
459470 if (auto *FS = dyn_cast(Summary.get())) {
460471 for (auto Call : FS->calls()) {
461 if (LiveSymbols.insert(Call.first).second) {
462 DEBUG(dbgs() << "Marking live (call): " << Call.first.getGUID()
463 << "\n");
464 Worklist.push_back(Call.first);
472 auto CallGUID = Call.first.getGUID();
473 if (LiveSymbols.insert(CallGUID).second) {
474 DEBUG(dbgs() << "Marking live (call): " << CallGUID << "\n");
475 Worklist.push_back(CallGUID);
465476 }
466477 }
467478 }
468479 if (auto *AS = dyn_cast(Summary.get())) {
469480 auto AliaseeGUID = AS->getAliasee().getOriginalName();
470 ValueInfo AliaseeVI = Index.getValueInfo(AliaseeGUID);
471 if (AliaseeVI && LiveSymbols.insert(AliaseeVI).second) {
481 if (LiveSymbols.insert(AliaseeGUID).second) {
472482 DEBUG(dbgs() << "Marking live (alias): " << AliaseeGUID << "\n");
473 Worklist.push_back(AliaseeVI);
483 Worklist.push_back(AliaseeGUID);
474484 }
475485 }
476486 }
479489 DeadSymbols.reserve(
480490 std::min(Index.size(), Index.size() - LiveSymbols.size()));
481491 for (auto &Entry : Index) {
482 if (!LiveSymbols.count(ValueInfo(&Entry))) {
483 DEBUG(dbgs() << "Marking dead: " << Entry.first << "\n");
484 DeadSymbols.insert(Entry.first);
492 auto GUID = Entry.first;
493 if (!LiveSymbols.count(GUID)) {
494 DEBUG(dbgs() << "Marking dead: " << GUID << "\n");
495 DeadSymbols.insert(GUID);
485496 }
486497 }
487498 DEBUG(dbgs() << LiveSymbols.size() << " symbols Live, and "
813824 // is only enabled when testing importing via the 'opt' tool, which does
814825 // not do the ThinLink that would normally determine what values to promote.
815826 for (auto &I : *Index) {
816 for (auto &S : I.second.SummaryList) {
827 for (auto &S : I.second) {
817828 if (GlobalValue::isLocalLinkage(S->linkage()))
818829 S->setLinkage(GlobalValue::ExternalLinkage);
819830 }
14391439 }
14401440
14411441 for (auto &P : *ExportSummary) {
1442 for (auto &S : P.second.SummaryList) {
1442 for (auto &S : P.second) {
14431443 auto *FS = dyn_cast(S.get());
14441444 if (!FS)
14451445 continue;
13211321 }
13221322
13231323 for (auto &P : *ExportSummary) {
1324 for (auto &S : P.second.SummaryList) {
1324 for (auto &S : P.second) {
13251325 auto *FS = dyn_cast(S.get());
13261326 if (!FS)
13271327 continue;
299299 // does not do the ThinLink that would normally determine what values to
300300 // promote.
301301 for (auto &I : *Index) {
302 for (auto &S : I.second.SummaryList) {
302 for (auto &S : I.second) {
303303 if (GlobalValue::isLocalLinkage(S->linkage()))
304304 S->setLinkage(GlobalValue::ExternalLinkage);
305305 }
283283
284284 unsigned Calls = 0, Refs = 0, Functions = 0, Alias = 0, Globals = 0;
285285 for (auto &Summaries : *Index) {
286 for (auto &Summary : Summaries.second.SummaryList) {
286 for (auto &Summary : Summaries.second) {
287287 Refs += Summary->refs().size();
288288 if (auto *FuncSummary = dyn_cast(Summary.get())) {
289289 Functions++;