llvm.org GIT mirror llvm / 36fc3f6
IR: Eliminate non-determinism in the module summary analysis. Also make the summary ref and call graph vectors immutable. This means a smaller API surface and fewer places to audit for non-determinism. Differential Revision: https://reviews.llvm.org/D27875 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290200 91177308-0d34-0410-b5e6-96231b3b80d8 Peter Collingbourne 3 years ago
7 changed file(s) with 133 addition(s) and 173 deletion(s). Raw diff Collapse all Expand all
4141 typedef typename VectorType::reverse_iterator reverse_iterator;
4242 typedef typename VectorType::const_reverse_iterator const_reverse_iterator;
4343
44 ArrayRef getArrayRef() const { return Vector; }
44 /// Clear the MapVector and return the underlying vector.
45 VectorType takeVector() {
46 Map.clear();
47 return std::move(Vector);
48 }
4549
4650 size_type size() const { return Vector.size(); }
4751
6262
6363 ArrayRef getArrayRef() const { return vector_; }
6464
65 /// Clear the SetVector and return the underlying vector.
66 Vector takeVector() {
67 set_.clear();
68 return std::move(vector_);
69 }
70
6571 /// \brief Determine if the SetVector is empty or not.
6672 bool empty() const {
6773 return vector_.empty();
4040 }
4141 };
4242
43 /// Struct to hold value either by GUID or Value*, depending on whether this
44 /// is a combined or per-module index, respectively.
43 /// Struct to hold value either by GUID or GlobalValue*. Values in combined
44 /// indexes as well as indirect calls are GUIDs, all others are GlobalValues.
4545 struct ValueInfo {
4646 /// The value representation used in this instance.
4747 enum ValueInfoKind {
5252 /// Union of the two possible value types.
5353 union ValueUnion {
5454 GlobalValue::GUID Id;
55 const Value *V;
55 const GlobalValue *GV;
5656 ValueUnion(GlobalValue::GUID Id) : Id(Id) {}
57 ValueUnion(const Value *V) : V(V) {}
57 ValueUnion(const GlobalValue *GV) : GV(GV) {}
5858 };
5959
6060 /// The value being represented.
6363 ValueInfoKind Kind;
6464 /// Constructor for a GUID value
6565 ValueInfo(GlobalValue::GUID Id = 0) : TheValue(Id), Kind(VI_GUID) {}
66 /// Constructor for a Value* value
67 ValueInfo(const Value *V) : TheValue(V), Kind(VI_Value) {}
66 /// Constructor for a GlobalValue* value
67 ValueInfo(const GlobalValue *V) : TheValue(V), Kind(VI_Value) {}
6868 /// Accessor for GUID value
6969 GlobalValue::GUID getGUID() const {
7070 assert(Kind == VI_GUID && "Not a GUID type");
7171 return TheValue.Id;
7272 }
73 /// Accessor for Value* value
74 const Value *getValue() const {
73 /// Accessor for GlobalValue* value
74 const GlobalValue *getValue() const {
7575 assert(Kind == VI_Value && "Not a Value type");
76 return TheValue.V;
76 return TheValue.GV;
7777 }
7878 bool isGUID() const { return Kind == VI_GUID; }
79 };
80
81 template <> struct DenseMapInfo {
82 static inline ValueInfo getEmptyKey() { return ValueInfo((GlobalValue *)-1); }
83 static inline ValueInfo getTombstoneKey() {
84 return ValueInfo((GlobalValue *)-2);
85 }
86 static bool isEqual(ValueInfo L, ValueInfo R) {
87 if (L.isGUID() != R.isGUID())
88 return false;
89 return L.isGUID() ? (L.getGUID() == R.getGUID())
90 : (L.getValue() == R.getValue());
91 }
92 static unsigned getHashValue(ValueInfo I) {
93 return I.isGUID() ? I.getGUID() : (uintptr_t)I.getValue();
94 }
7995 };
8096
8197 /// \brief Function and variable summary information to aid decisions and
159175
160176 protected:
161177 /// GlobalValueSummary constructor.
162 GlobalValueSummary(SummaryKind K, GVFlags Flags) : Kind(K), Flags(Flags) {}
178 GlobalValueSummary(SummaryKind K, GVFlags Flags, std::vector Refs)
179 : Kind(K), Flags(Flags), RefEdgeList(std::move(Refs)) {}
163180
164181 public:
165182 virtual ~GlobalValueSummary() = default;
221238 Flags.HasInlineAsmMaybeReferencingInternal = true;
222239 }
223240
224 /// Record a reference from this global value to the global value identified
225 /// by \p RefGUID.
226 void addRefEdge(GlobalValue::GUID RefGUID) { RefEdgeList.push_back(RefGUID); }
227
228 /// Record a reference from this global value to the global value identified
229 /// by \p RefV.
230 void addRefEdge(const Value *RefV) { RefEdgeList.push_back(RefV); }
231
232 /// Record a reference from this global value to each global value identified
233 /// in \p RefEdges.
234 void addRefEdges(DenseSet &RefEdges) {
235 for (auto &RI : RefEdges)
236 addRefEdge(RI);
237 }
238
239241 /// Return the list of values referenced by this global value definition.
240 std::vector &refs() { return RefEdgeList; }
241 const std::vector &refs() const { return RefEdgeList; }
242 ArrayRef refs() const { return RefEdgeList; }
242243 };
243244
244245 /// \brief Alias summary information.
247248
248249 public:
249250 /// Summary constructors.
250 AliasSummary(GVFlags Flags) : GlobalValueSummary(AliasKind, Flags) {}
251 AliasSummary(GVFlags Flags, std::vector Refs)
252 : GlobalValueSummary(AliasKind, Flags, std::move(Refs)) {}
251253
252254 /// Check if this is an alias summary.
253255 static bool classof(const GlobalValueSummary *GVS) {
283285
284286 public:
285287 /// Summary constructors.
286 FunctionSummary(GVFlags Flags, unsigned NumInsts)
287 : GlobalValueSummary(FunctionKind, Flags), InstCount(NumInsts) {}
288 FunctionSummary(GVFlags Flags, unsigned NumInsts, std::vector Refs,
289 std::vector CGEdges)
290 : GlobalValueSummary(FunctionKind, Flags, std::move(Refs)),
291 InstCount(NumInsts), CallGraphEdgeList(std::move(CGEdges)) {}
288292
289293 /// Check if this is a function summary.
290294 static bool classof(const GlobalValueSummary *GVS) {
294298 /// Get the instruction count recorded for this function.
295299 unsigned instCount() const { return InstCount; }
296300
297 /// Record a call graph edge from this function to the function identified
298 /// by \p CalleeGUID, with \p CalleeInfo including the cumulative profile
299 /// count (across all calls from this function) or 0 if no PGO.
300 void addCallGraphEdge(GlobalValue::GUID CalleeGUID, CalleeInfo Info) {
301 CallGraphEdgeList.push_back(std::make_pair(CalleeGUID, Info));
302 }
303
304 /// Record a call graph edge from this function to each function GUID recorded
305 /// in \p CallGraphEdges.
306 void
307 addCallGraphEdges(DenseMap &CallGraphEdges) {
308 for (auto &EI : CallGraphEdges)
309 addCallGraphEdge(EI.first, EI.second);
310 }
311
312 /// Record a call graph edge from this function to the function identified
313 /// by \p CalleeV, with \p CalleeInfo including the cumulative profile
314 /// count (across all calls from this function) or 0 if no PGO.
315 void addCallGraphEdge(const Value *CalleeV, CalleeInfo Info) {
316 CallGraphEdgeList.push_back(std::make_pair(CalleeV, Info));
317 }
318
319 /// Record a call graph edge from this function to each function recorded
320 /// in \p CallGraphEdges.
321 void addCallGraphEdges(DenseMap &CallGraphEdges) {
322 for (auto &EI : CallGraphEdges)
323 addCallGraphEdge(EI.first, EI.second);
324 }
325
326301 /// Return the list of pairs.
327 std::vector &calls() { return CallGraphEdgeList; }
328 const std::vector &calls() const { return CallGraphEdgeList; }
302 ArrayRef calls() const { return CallGraphEdgeList; }
329303 };
330304
331305 /// \brief Global variable summary information to aid decisions and
338312
339313 public:
340314 /// Summary constructors.
341 GlobalVarSummary(GVFlags Flags) : GlobalValueSummary(GlobalVarKind, Flags) {}
315 GlobalVarSummary(GVFlags Flags, std::vector Refs)
316 : GlobalValueSummary(GlobalVarKind, Flags, std::move(Refs)) {}
342317
343318 /// Check if this is a global variable summary.
344319 static bool classof(const GlobalValueSummary *GVS) {
1212 //===----------------------------------------------------------------------===//
1313
1414 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
15 #include "llvm/ADT/MapVector.h"
16 #include "llvm/ADT/SetVector.h"
1517 #include "llvm/ADT/Triple.h"
1618 #include "llvm/Analysis/BlockFrequencyInfo.h"
1719 #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
3335 // Walk through the operands of a given User via worklist iteration and populate
3436 // the set of GlobalValue references encountered. Invoked either on an
3537 // Instruction or a GlobalVariable (which walks its initializer).
36 static void findRefEdges(const User *CurUser, DenseSet> &RefEdges,
38 static void findRefEdges(const User *CurUser, SetVector> &RefEdges,
3739 SmallPtrSet &Visited) {
3840 SmallVector Worklist;
3941 Worklist.push_back(CurUser);
5254 continue;
5355 if (isa(Operand))
5456 continue;
55 if (isa(Operand)) {
57 if (auto *GV = dyn_cast(Operand)) {
5658 // We have a reference to a global value. This should be added to
5759 // the reference set unless it is a callee. Callees are handled
5860 // specially by WriteFunction and are added to a separate list.
5961 if (!(CS && CS.isCallee(&OI)))
60 RefEdges.insert(Operand);
62 RefEdges.insert(GV);
6163 continue;
6264 }
6365 Worklist.push_back(Operand);
8789 unsigned NumInsts = 0;
8890 // Map from callee ValueId to profile count. Used to accumulate profile
8991 // counts for all static calls to a given callee.
90 DenseMap CallGraphEdges;
91 DenseMap IndirectCallEdges;
92 DenseSet RefEdges;
92 MapVector CallGraphEdges;
93 SetVector RefEdges;
9394 ICallPromotionAnalysis ICallAnalysis;
9495
9596 bool HasInlineAsmMaybeReferencingInternal = false;
129130 // We should have named any anonymous globals
130131 assert(CalledFunction->hasName());
131132 auto ScaledCount = BFI ? BFI->getBlockProfileCount(&BB) : None;
133 auto Hotness = ScaledCount ? getHotness(ScaledCount.getValue(), PSI)
134 : CalleeInfo::HotnessType::Unknown;
135
132136 // Use the original CalledValue, in case it was an alias. We want
133137 // to record the call edge to the alias in that case. Eventually
134138 // an alias summary will be created to associate the alias and
135139 // aliasee.
136 auto *CalleeId =
137 M.getValueSymbolTable().lookup(CalledValue->getName());
138
139 auto Hotness = ScaledCount ? getHotness(ScaledCount.getValue(), PSI)
140 : CalleeInfo::HotnessType::Unknown;
141 CallGraphEdges[CalleeId].updateHotness(Hotness);
140 CallGraphEdges[cast(CalledValue)].updateHotness(Hotness);
142141 } else {
143142 // Skip inline assembly calls.
144143 if (CI && CI->isInlineAsm())
153152 ICallAnalysis.getPromotionCandidatesForInstruction(
154153 &I, NumVals, TotalCount, NumCandidates);
155154 for (auto &Candidate : CandidateProfileData)
156 IndirectCallEdges[Candidate.Value].updateHotness(
155 CallGraphEdges[Candidate.Value].updateHotness(
157156 getHotness(Candidate.Count, PSI));
158157 }
159158 }
160159
161160 GlobalValueSummary::GVFlags Flags(F);
162 std::unique_ptr FuncSummary =
163 llvm::make_unique(Flags, NumInsts);
164 FuncSummary->addCallGraphEdges(CallGraphEdges);
165 FuncSummary->addCallGraphEdges(IndirectCallEdges);
166 FuncSummary->addRefEdges(RefEdges);
161 auto FuncSummary = llvm::make_unique(
162 Flags, NumInsts, RefEdges.takeVector(), CallGraphEdges.takeVector());
167163 if (HasInlineAsmMaybeReferencingInternal)
168164 FuncSummary->setHasInlineAsmMaybeReferencingInternal();
169165 Index.addGlobalValueSummary(F.getName(), std::move(FuncSummary));
171167
172168 static void computeVariableSummary(ModuleSummaryIndex &Index,
173169 const GlobalVariable &V) {
174 DenseSet> RefEdges;
170 SetVector> RefEdges;
175171 SmallPtrSet Visited;
176172 findRefEdges(&V, RefEdges, Visited);
177173 GlobalValueSummary::GVFlags Flags(V);
178 std::unique_ptr GVarSummary =
179 llvm::make_unique(Flags);
180 GVarSummary->addRefEdges(RefEdges);
174 auto GVarSummary =
175 llvm::make_unique(Flags, RefEdges.takeVector());
181176 Index.addGlobalValueSummary(V.getName(), std::move(GVarSummary));
182177 }
183178
184179 static void computeAliasSummary(ModuleSummaryIndex &Index,
185180 const GlobalAlias &A) {
186181 GlobalValueSummary::GVFlags Flags(A);
187 std::unique_ptr AS = llvm::make_unique(Flags);
182 auto AS = llvm::make_unique(Flags, ArrayRef{});
188183 auto *Aliasee = A.getBaseObject();
189184 auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee);
190185 assert(AliaseeSummary && "Alias expects aliasee summary to be parsed");
282277 // Create the appropriate summary type.
283278 if (isa(GV)) {
284279 std::unique_ptr Summary =
285 llvm::make_unique(GVFlags, 0);
280 llvm::make_unique(
281 GVFlags, 0, ArrayRef{},
282 ArrayRef{});
286283 Summary->setNoRename();
287284 Index.addGlobalValueSummary(Name, std::move(Summary));
288285 } else {
289286 std::unique_ptr Summary =
290 llvm::make_unique(GVFlags);
287 llvm::make_unique(GVFlags,
288 ArrayRef{});
291289 Summary->setNoRename();
292290 Index.addGlobalValueSummary(Name, std::move(Summary));
293291 }
667667 Error parseValueSymbolTable(
668668 uint64_t Offset,
669669 DenseMap &ValueIdToLinkageMap);
670 std::vector makeRefList(ArrayRef Record);
671 std::vector makeCallList(ArrayRef Record,
672 bool IsOldProfileFormat,
673 bool HasProfile);
670674 Error parseEntireSummary(StringRef ModulePath);
671675 Error parseModuleStringTable();
676
672677 std::pair
673
674678 getGUIDFromValueId(unsigned ValueId);
675 std::pair
676 readCallGraphEdge(const SmallVector &Record, unsigned int &I,
677 bool IsOldProfileFormat, bool HasProfile);
678679 };
679680
680681 } // end anonymous namespace
47914792 }
47924793 }
47934794
4795 std::vector
4796 ModuleSummaryIndexBitcodeReader::makeRefList(ArrayRef Record) {
4797 std::vector Ret;
4798 Ret.reserve(Record.size());
4799 for (uint64_t RefValueId : Record)
4800 Ret.push_back(getGUIDFromValueId(RefValueId).first);
4801 return Ret;
4802 }
4803
4804 std::vector ModuleSummaryIndexBitcodeReader::makeCallList(
4805 ArrayRef Record, bool IsOldProfileFormat, bool HasProfile) {
4806 std::vector Ret;
4807 Ret.reserve(Record.size());
4808 for (unsigned I = 0, E = Record.size(); I != E; ++I) {
4809 CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown;
4810 GlobalValue::GUID CalleeGUID = getGUIDFromValueId(Record[I]).first;
4811 if (IsOldProfileFormat) {
4812 I += 1; // Skip old callsitecount field
4813 if (HasProfile)
4814 I += 1; // Skip old profilecount field
4815 } else if (HasProfile)
4816 Hotness = static_cast(Record[++I]);
4817 Ret.push_back(FunctionSummary::EdgeTy{CalleeGUID, CalleeInfo{Hotness}});
4818 }
4819 return Ret;
4820 }
4821
47944822 // Eagerly parse the entire summary block. This populates the GlobalValueSummary
47954823 // objects in the index.
47964824 Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(
48674895 unsigned InstCount = Record[2];
48684896 unsigned NumRefs = Record[3];
48694897 auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
4870 std::unique_ptr FS =
4871 llvm::make_unique(Flags, InstCount);
48724898 // The module path string ref set in the summary must be owned by the
48734899 // index's module string table. Since we don't have a module path
48744900 // string table section in the per-module index, we create a single
48754901 // module path string table entry with an empty (0) ID to take
48764902 // ownership.
4877 FS->setModulePath(TheIndex.addModulePath(ModulePath, 0)->first());
48784903 static int RefListStartIndex = 4;
48794904 int CallGraphEdgeStartIndex = RefListStartIndex + NumRefs;
48804905 assert(Record.size() >= RefListStartIndex + NumRefs &&
48814906 "Record size inconsistent with number of references");
4882 for (unsigned I = 4, E = CallGraphEdgeStartIndex; I != E; ++I) {
4883 unsigned RefValueId = Record[I];
4884 GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId).first;
4885 FS->addRefEdge(RefGUID);
4886 }
4907 std::vector Refs = makeRefList(
4908 ArrayRef(Record).slice(RefListStartIndex, NumRefs));
48874909 bool HasProfile = (BitCode == bitc::FS_PERMODULE_PROFILE);
4888 for (unsigned I = CallGraphEdgeStartIndex, E = Record.size(); I != E;
4889 ++I) {
4890 CalleeInfo::HotnessType Hotness;
4891 GlobalValue::GUID CalleeGUID;
4892 std::tie(CalleeGUID, Hotness) =
4893 readCallGraphEdge(Record, I, IsOldProfileFormat, HasProfile);
4894 FS->addCallGraphEdge(CalleeGUID, CalleeInfo(Hotness));
4895 }
4910 std::vector Calls = makeCallList(
4911 ArrayRef(Record).slice(CallGraphEdgeStartIndex),
4912 IsOldProfileFormat, HasProfile);
4913 auto FS = llvm::make_unique(
4914 Flags, InstCount, std::move(Refs), std::move(Calls));
48964915 auto GUID = getGUIDFromValueId(ValueID);
4916 FS->setModulePath(TheIndex.addModulePath(ModulePath, 0)->first());
48974917 FS->setOriginalName(GUID.second);
48984918 TheIndex.addGlobalValueSummary(GUID.first, std::move(FS));
48994919 break;
49064926 uint64_t RawFlags = Record[1];
49074927 unsigned AliaseeID = Record[2];
49084928 auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
4909 std::unique_ptr AS = llvm::make_unique(Flags);
4929 auto AS =
4930 llvm::make_unique(Flags, std::vector{});
49104931 // The module path string ref set in the summary must be owned by the
49114932 // index's module string table. Since we don't have a module path
49124933 // string table section in the per-module index, we create a single
49304951 unsigned ValueID = Record[0];
49314952 uint64_t RawFlags = Record[1];
49324953 auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
4933 std::unique_ptr FS =
4934 llvm::make_unique(Flags);
4954 std::vector Refs =
4955 makeRefList(ArrayRef(Record).slice(2));
4956 auto FS = llvm::make_unique(Flags, std::move(Refs));
49354957 FS->setModulePath(TheIndex.addModulePath(ModulePath, 0)->first());
4936 for (unsigned I = 2, E = Record.size(); I != E; ++I) {
4937 unsigned RefValueId = Record[I];
4938 GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId).first;
4939 FS->addRefEdge(RefGUID);
4940 }
49414958 auto GUID = getGUIDFromValueId(ValueID);
49424959 FS->setOriginalName(GUID.second);
49434960 TheIndex.addGlobalValueSummary(GUID.first, std::move(FS));
49554972 unsigned InstCount = Record[3];
49564973 unsigned NumRefs = Record[4];
49574974 auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
4958 std::unique_ptr FS =
4959 llvm::make_unique(Flags, InstCount);
4960 LastSeenSummary = FS.get();
4961 FS->setModulePath(ModuleIdMap[ModuleId]);
49624975 static int RefListStartIndex = 5;
49634976 int CallGraphEdgeStartIndex = RefListStartIndex + NumRefs;
49644977 assert(Record.size() >= RefListStartIndex + NumRefs &&
49654978 "Record size inconsistent with number of references");
4966 for (unsigned I = RefListStartIndex, E = CallGraphEdgeStartIndex; I != E;
4967 ++I) {
4968 unsigned RefValueId = Record[I];
4969 GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId).first;
4970 FS->addRefEdge(RefGUID);
4971 }
4979 std::vector Refs = makeRefList(
4980 ArrayRef(Record).slice(RefListStartIndex, NumRefs));
49724981 bool HasProfile = (BitCode == bitc::FS_COMBINED_PROFILE);
4973 for (unsigned I = CallGraphEdgeStartIndex, E = Record.size(); I != E;
4974 ++I) {
4975 CalleeInfo::HotnessType Hotness;
4976 GlobalValue::GUID CalleeGUID;
4977 std::tie(CalleeGUID, Hotness) =
4978 readCallGraphEdge(Record, I, IsOldProfileFormat, HasProfile);
4979 FS->addCallGraphEdge(CalleeGUID, CalleeInfo(Hotness));
4980 }
4982 std::vector Edges = makeCallList(
4983 ArrayRef(Record).slice(CallGraphEdgeStartIndex),
4984 IsOldProfileFormat, HasProfile);
49814985 GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first;
4986 auto FS = llvm::make_unique(
4987 Flags, InstCount, std::move(Refs), std::move(Edges));
4988 LastSeenSummary = FS.get();
4989 FS->setModulePath(ModuleIdMap[ModuleId]);
49824990 TheIndex.addGlobalValueSummary(GUID, std::move(FS));
49834991 Combined = true;
49844992 break;
49925000 uint64_t RawFlags = Record[2];
49935001 unsigned AliaseeValueId = Record[3];
49945002 auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
4995 std::unique_ptr AS = llvm::make_unique(Flags);
5003 auto AS = llvm::make_unique(Flags, std::vector{});
49965004 LastSeenSummary = AS.get();
49975005 AS->setModulePath(ModuleIdMap[ModuleId]);
49985006
50145022 uint64_t ModuleId = Record[1];
50155023 uint64_t RawFlags = Record[2];
50165024 auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
5017 std::unique_ptr FS =
5018 llvm::make_unique(Flags);
5025 std::vector Refs =
5026 makeRefList(ArrayRef(Record).slice(3));
5027 auto FS = llvm::make_unique(Flags, std::move(Refs));
50195028 LastSeenSummary = FS.get();
50205029 FS->setModulePath(ModuleIdMap[ModuleId]);
5021 for (unsigned I = 3, E = Record.size(); I != E; ++I) {
5022 unsigned RefValueId = Record[I];
5023 GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId).first;
5024 FS->addRefEdge(RefGUID);
5025 }
50265030 GlobalValue::GUID GUID = getGUIDFromValueId(ValueID).first;
50275031 TheIndex.addGlobalValueSummary(GUID, std::move(FS));
50285032 Combined = true;
50405044 }
50415045 }
50425046 llvm_unreachable("Exit infinite loop");
5043 }
5044
5045 std::pair
5046 ModuleSummaryIndexBitcodeReader::readCallGraphEdge(
5047 const SmallVector &Record, unsigned int &I,
5048 const bool IsOldProfileFormat, const bool HasProfile) {
5049
5050 auto Hotness = CalleeInfo::HotnessType::Unknown;
5051 unsigned CalleeValueId = Record[I];
5052 GlobalValue::GUID CalleeGUID = getGUIDFromValueId(CalleeValueId).first;
5053 if (IsOldProfileFormat) {
5054 I += 1; // Skip old callsitecount field
5055 if (HasProfile)
5056 I += 1; // Skip old profilecount field
5057 } else if (HasProfile)
5058 Hotness = static_cast(Record[++I]);
5059 return {CalleeGUID, Hotness};
50605047 }
50615048
50625049 // Parse the module string table block into the Index.
32893289 NameVals.push_back(FS->instCount());
32903290 NameVals.push_back(FS->refs().size());
32913291
3292 unsigned SizeBeforeRefs = NameVals.size();
32933292 for (auto &RI : FS->refs())
32943293 NameVals.push_back(VE.getValueID(RI.getValue()));
3295 // Sort the refs for determinism output, the vector returned by FS->refs() has
3296 // been initialized from a DenseSet.
3297 std::sort(NameVals.begin() + SizeBeforeRefs, NameVals.end());
3298
3299 std::vector Calls = FS->calls();
3300 std::sort(Calls.begin(), Calls.end(),
3301 [this](const FunctionSummary::EdgeTy &L,
3302 const FunctionSummary::EdgeTy &R) {
3303 return getValueId(L.first) < getValueId(R.first);
3304 });
3294
33053295 bool HasProfileData = F.getEntryCount().hasValue();
3306 for (auto &ECI : Calls) {
3296 for (auto &ECI : FS->calls()) {
33073297 NameVals.push_back(getValueId(ECI.first));
33083298 if (HasProfileData)
33093299 NameVals.push_back(static_cast(ECI.second.Hotness));
99 ; CHECK-NEXT:
1010 ; See if the call to func is registered, using the expected callsite count
1111 ; and profile count, with value id matching the subsequent value symbol table.
12 ; CHECK-NEXT: HOT2:.*]] op7=3 op8=[[HOT3:.*]] op9=3 op10=[[COLD:.*]] op11=1 op12=[[NONE1:.*]] op13=2 op14=[[NONE2:.*]] op15=2 op16=[[NONE3:.*]] op17=2/>
12 ; CHECK-NEXT: COLD:.*]] op7=1 op8=[[HOT2:.*]] op9=3 op10=[[NONE1:.*]] op11=2 op12=[[HOT3:.*]] op13=3 op14=[[NONE2:.*]] op15=2 op16=[[NONE3:.*]] op17=2/>
1313 ; CHECK-NEXT:
1414 ; CHECK-LABEL:
1515 ; CHECK-NEXT: