llvm.org GIT mirror llvm / 17e7f11
Move ProfileSummary to IR. This splits ProfileSummary into two classes: a ProfileSummary class that has methods to convert from/to metadata and a ProfileSummaryBuilder class that computes the profiles summary which is in ProfileData. Differential Revision: http://reviews.llvm.org/D20314 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270136 91177308-0d34-0410-b5e6-96231b3b80d8 Easwaran Raman 4 years ago
12 changed file(s) with 570 addition(s) and 507 deletion(s). Raw diff Collapse all Expand all
0 //===-- ProfileSummary.h - Profile summary data structure. ------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the profile summary data structure.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_SUPPORT_PROFILE_SUMMARY_H
14 #define LLVM_SUPPORT_PROFILE_SUMMARY_H
15
16 #include
17 #include
18
19 #include "llvm/Support/Casting.h"
20
21 namespace llvm {
22
23 class LLVMContext;
24 class Metadata;
25 class MDTuple;
26 class MDNode;
27
28 // The profile summary is one or more (Cutoff, MinCount, NumCounts) triplets.
29 // The semantics of counts depend on the type of profile. For instrumentation
30 // profile, counts are block counts and for sample profile, counts are
31 // per-line samples. Given a target counts percentile, we compute the minimum
32 // number of counts needed to reach this target and the minimum among these
33 // counts.
34 struct ProfileSummaryEntry {
35 uint32_t Cutoff; ///< The required percentile of counts.
36 uint64_t MinCount; ///< The minimum count for this percentile.
37 uint64_t NumCounts; ///< Number of counts >= the minimum count.
38 ProfileSummaryEntry(uint32_t TheCutoff, uint64_t TheMinCount,
39 uint64_t TheNumCounts)
40 : Cutoff(TheCutoff), MinCount(TheMinCount), NumCounts(TheNumCounts) {}
41 };
42
43 typedef std::vector SummaryEntryVector;
44
45 class ProfileSummary {
46 public:
47 enum Kind { PSK_Instr, PSK_Sample };
48
49 private:
50 const Kind PSK;
51 static const char *KindStr[2];
52
53 protected:
54 SummaryEntryVector DetailedSummary;
55 uint64_t TotalCount, MaxCount, MaxFunctionCount;
56 uint32_t NumCounts, NumFunctions;
57 ProfileSummary(Kind K, SummaryEntryVector DetailedSummary,
58 uint64_t TotalCount, uint64_t MaxCount,
59 uint64_t MaxFunctionCount, uint32_t NumCounts,
60 uint32_t NumFunctions)
61 : PSK(K), DetailedSummary(DetailedSummary), TotalCount(TotalCount),
62 MaxCount(MaxCount), MaxFunctionCount(MaxFunctionCount),
63 NumCounts(NumCounts), NumFunctions(NumFunctions) {}
64 ~ProfileSummary() = default;
65 /// \brief Return metadata specific to the profile format.
66 /// Derived classes implement this method to return a vector of Metadata.
67 virtual std::vector getFormatSpecificMD(LLVMContext &Context) = 0;
68 /// \brief Return detailed summary as metadata.
69 Metadata *getDetailedSummaryMD(LLVMContext &Context);
70
71 public:
72 static const int Scale = 1000000;
73 Kind getKind() const { return PSK; }
74 const char *getKindStr() const { return KindStr[PSK]; }
75 /// \brief Return summary information as metadata.
76 Metadata *getMD(LLVMContext &Context);
77 /// \brief Construct profile summary from metdata.
78 static ProfileSummary *getFromMD(Metadata *MD);
79 SummaryEntryVector &getDetailedSummary() { return DetailedSummary; }
80 uint32_t getNumFunctions() { return NumFunctions; }
81 uint64_t getMaxFunctionCount() { return MaxFunctionCount; }
82 };
83
84 class InstrProfSummary final : public ProfileSummary {
85 uint64_t MaxInternalBlockCount;
86
87 protected:
88 std::vector getFormatSpecificMD(LLVMContext &Context) override;
89
90 public:
91 InstrProfSummary(uint64_t TotalCount, uint64_t MaxBlockCount,
92 uint64_t MaxInternalBlockCount, uint64_t MaxFunctionCount,
93 uint32_t NumBlocks, uint32_t NumFunctions,
94 SummaryEntryVector Summary)
95 : ProfileSummary(PSK_Instr, Summary, TotalCount, MaxBlockCount,
96 MaxFunctionCount, NumBlocks, NumFunctions),
97 MaxInternalBlockCount(MaxInternalBlockCount) {}
98 static bool classof(const ProfileSummary *PS) {
99 return PS->getKind() == PSK_Instr;
100 }
101 uint32_t getNumBlocks() { return NumCounts; }
102 uint64_t getTotalCount() { return TotalCount; }
103 uint64_t getMaxBlockCount() { return MaxCount; }
104 uint64_t getMaxInternalBlockCount() { return MaxInternalBlockCount; }
105 };
106
107 class SampleProfileSummary final : public ProfileSummary {
108 protected:
109 std::vector getFormatSpecificMD(LLVMContext &Context) override;
110
111 public:
112 uint32_t getNumLinesWithSamples() { return NumCounts; }
113 uint64_t getTotalSamples() { return TotalCount; }
114 uint64_t getMaxSamplesPerLine() { return MaxCount; }
115 SampleProfileSummary(uint64_t TotalSamples, uint64_t MaxSamplesPerLine,
116 uint64_t MaxFunctionCount, int32_t NumLinesWithSamples,
117 uint32_t NumFunctions,
118 SummaryEntryVector DetailedSummary)
119 : ProfileSummary(PSK_Sample, DetailedSummary, TotalSamples,
120 MaxSamplesPerLine, MaxFunctionCount, NumLinesWithSamples,
121 NumFunctions) {}
122 static bool classof(const ProfileSummary *PS) {
123 return PS->getKind() == PSK_Sample;
124 }
125 };
126
127 } // end namespace llvm
128 #endif
1919 #include
2020 #include
2121
22 #include "llvm/Support/Casting.h"
22 #include "llvm/IR/ProfileSummary.h"
2323 #include "llvm/Support/Error.h"
2424
2525 namespace llvm {
3939 inline const char *getHotSectionPrefix() { return ".hot"; }
4040 inline const char *getUnlikelySectionPrefix() { return ".unlikely"; }
4141
42 // The profile summary is one or more (Cutoff, MinCount, NumCounts) triplets.
43 // The semantics of counts depend on the type of profile. For instrumentation
44 // profile, counts are block counts and for sample profile, counts are
45 // per-line samples. Given a target counts percentile, we compute the minimum
46 // number of counts needed to reach this target and the minimum among these
47 // counts.
48 struct ProfileSummaryEntry {
49 uint32_t Cutoff; ///< The required percentile of counts.
50 uint64_t MinCount; ///< The minimum count for this percentile.
51 uint64_t NumCounts; ///< Number of counts >= the minimum count.
52 ProfileSummaryEntry(uint32_t TheCutoff, uint64_t TheMinCount,
53 uint64_t TheNumCounts)
54 : Cutoff(TheCutoff), MinCount(TheMinCount), NumCounts(TheNumCounts) {}
55 };
56
57 typedef std::vector SummaryEntryVector;
58
59 class ProfileSummary {
60 public:
61 enum Kind { PSK_Instr, PSK_Sample };
42 class ProfileSummaryBuilder {
6243
6344 private:
64 const Kind PSK;
65 static const char *KindStr[2];
6645 // We keep track of the number of times a count (block count or samples)
6746 // appears in the profile. The map is kept sorted in the descending order of
6847 // counts.
6948 std::map> CountFrequencies;
49 std::vector DetailedSummaryCutoffs;
50
7051 protected:
7152 SummaryEntryVector DetailedSummary;
72 std::vector DetailedSummaryCutoffs;
53 ProfileSummaryBuilder(std::vector Cutoffs)
54 : DetailedSummaryCutoffs(Cutoffs), TotalCount(0), MaxCount(0),
55 MaxFunctionCount(0), NumCounts(0), NumFunctions(0) {}
56 inline void addCount(uint64_t Count);
57 ~ProfileSummaryBuilder() = default;
58 void computeDetailedSummary();
7359 uint64_t TotalCount, MaxCount, MaxFunctionCount;
7460 uint32_t NumCounts, NumFunctions;
75 ProfileSummary(Kind K, std::vector Cutoffs)
76 : PSK(K), DetailedSummaryCutoffs(Cutoffs), TotalCount(0), MaxCount(0),
77 MaxFunctionCount(0), NumCounts(0), NumFunctions(0) {}
78 ProfileSummary(Kind K)
79 : PSK(K), TotalCount(0), MaxCount(0), MaxFunctionCount(0), NumCounts(0),
80 NumFunctions(0) {}
81 ProfileSummary(Kind K, SummaryEntryVector DetailedSummary,
82 uint64_t TotalCount, uint64_t MaxCount,
83 uint64_t MaxFunctionCount, uint32_t NumCounts,
84 uint32_t NumFunctions)
85 : PSK(K), DetailedSummary(DetailedSummary), TotalCount(TotalCount),
86 MaxCount(MaxCount), MaxFunctionCount(MaxFunctionCount),
87 NumCounts(NumCounts), NumFunctions(NumFunctions) {}
88 ~ProfileSummary() = default;
89 inline void addCount(uint64_t Count);
90 /// \brief Return metadata specific to the profile format.
91 /// Derived classes implement this method to return a vector of Metadata.
92 virtual std::vector getFormatSpecificMD(LLVMContext &Context) = 0;
93 /// \brief Return detailed summary as metadata.
94 Metadata *getDetailedSummaryMD(LLVMContext &Context);
9561
9662 public:
97 static const int Scale = 1000000;
98 Kind getKind() const { return PSK; }
99 const char *getKindStr() const { return KindStr[PSK]; }
100 // \brief Returns true if F is a hot function.
101 static bool isFunctionHot(const Function *F);
102 // \brief Returns true if F is unlikley executed.
103 static bool isFunctionUnlikely(const Function *F);
104 inline SummaryEntryVector &getDetailedSummary();
105 void computeDetailedSummary();
10663 /// \brief A vector of useful cutoff values for detailed summary.
10764 static const std::vector DefaultCutoffs;
108 /// \brief Return summary information as metadata.
109 Metadata *getMD(LLVMContext &Context);
110 /// \brief Construct profile summary from metdata.
111 static ProfileSummary *getFromMD(Metadata *MD);
112 uint32_t getNumFunctions() { return NumFunctions; }
113 uint64_t getMaxFunctionCount() { return MaxFunctionCount; }
11465 };
11566
116 class InstrProfSummary final : public ProfileSummary {
67 class InstrProfSummaryBuilder final : public ProfileSummaryBuilder {
11768 uint64_t MaxInternalBlockCount;
11869 inline void addEntryCount(uint64_t Count);
11970 inline void addInternalCount(uint64_t Count);
12071
121 protected:
122 std::vector getFormatSpecificMD(LLVMContext &Context) override;
72 public:
73 InstrProfSummaryBuilder(std::vector Cutoffs)
74 : ProfileSummaryBuilder(Cutoffs), MaxInternalBlockCount(0) {}
75 void addRecord(const InstrProfRecord &);
76 InstrProfSummary *getSummary();
77 };
78
79 class SampleProfileSummaryBuilder final : public ProfileSummaryBuilder {
12380
12481 public:
125 InstrProfSummary(std::vector Cutoffs)
126 : ProfileSummary(PSK_Instr, Cutoffs), MaxInternalBlockCount(0) {}
127 InstrProfSummary(const IndexedInstrProf::Summary &S);
128 InstrProfSummary(uint64_t TotalCount, uint64_t MaxBlockCount,
129 uint64_t MaxInternalBlockCount, uint64_t MaxFunctionCount,
130 uint32_t NumBlocks, uint32_t NumFunctions,
131 SummaryEntryVector Summary)
132 : ProfileSummary(PSK_Instr, Summary, TotalCount, MaxBlockCount,
133 MaxFunctionCount, NumBlocks, NumFunctions),
134 MaxInternalBlockCount(MaxInternalBlockCount) {}
135 static bool classof(const ProfileSummary *PS) {
136 return PS->getKind() == PSK_Instr;
137 }
138 void addRecord(const InstrProfRecord &);
139 uint32_t getNumBlocks() { return NumCounts; }
140 uint64_t getTotalCount() { return TotalCount; }
141 uint64_t getMaxBlockCount() { return MaxCount; }
142 uint64_t getMaxInternalBlockCount() { return MaxInternalBlockCount; }
143 };
144
145 class SampleProfileSummary final : public ProfileSummary {
146 protected:
147 std::vector getFormatSpecificMD(LLVMContext &Context) override;
148
149 public:
150 uint32_t getNumLinesWithSamples() { return NumCounts; }
151 uint64_t getTotalSamples() { return TotalCount; }
152 uint64_t getMaxSamplesPerLine() { return MaxCount; }
15382 void addRecord(const sampleprof::FunctionSamples &FS);
154 SampleProfileSummary(std::vector Cutoffs)
155 : ProfileSummary(PSK_Sample, Cutoffs) {}
156 SampleProfileSummary(uint64_t TotalSamples, uint64_t MaxSamplesPerLine,
157 uint64_t MaxFunctionCount, int32_t NumLinesWithSamples,
158 uint32_t NumFunctions,
159 SummaryEntryVector DetailedSummary)
160 : ProfileSummary(PSK_Sample, DetailedSummary, TotalSamples,
161 MaxSamplesPerLine, MaxFunctionCount, NumLinesWithSamples,
162 NumFunctions) {}
163 static bool classof(const ProfileSummary *PS) {
164 return PS->getKind() == PSK_Sample;
165 }
83 SampleProfileSummaryBuilder(std::vector Cutoffs)
84 : ProfileSummaryBuilder(Cutoffs) {}
85 SampleProfileSummary *getSummary();
16686 };
16787
16888 // This is called when a count is seen in the profile.
169 void ProfileSummary::addCount(uint64_t Count) {
89 void ProfileSummaryBuilder::addCount(uint64_t Count) {
17090 TotalCount += Count;
17191 if (Count > MaxCount)
17292 MaxCount = Count;
17494 CountFrequencies[Count]++;
17595 }
17696
177 SummaryEntryVector &ProfileSummary::getDetailedSummary() {
178 if (!DetailedSummaryCutoffs.empty() && DetailedSummary.empty())
179 computeDetailedSummary();
180 return DetailedSummary;
181 }
18297
18398 } // end namespace llvm
18499 #endif
4242 Pass.cpp
4343 PassManager.cpp
4444 PassRegistry.cpp
45 ProfileSummary.cpp
4546 Statepoint.cpp
4647 Type.cpp
4748 TypeFinder.cpp
0 //=-- Profilesummary.cpp - Profile summary support --------------------------=//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains support for converting profile summary data from/to
10 // metadata.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/IR/ProfileSummary.h"
15 #include "llvm/IR/Attributes.h"
16 #include "llvm/IR/Constants.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/IR/Metadata.h"
19 #include "llvm/IR/Type.h"
20 #include "llvm/Support/Casting.h"
21
22 using namespace llvm;
23
24 const char *ProfileSummary::KindStr[2] = {"InstrProf", "SampleProfile"};
25
26 // Return an MDTuple with two elements. The first element is a string Key and
27 // the second is a uint64_t Value.
28 static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
29 uint64_t Val) {
30 Type *Int64Ty = Type::getInt64Ty(Context);
31 Metadata *Ops[2] = {MDString::get(Context, Key),
32 ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Val))};
33 return MDTuple::get(Context, Ops);
34 }
35
36 // Return an MDTuple with two elements. The first element is a string Key and
37 // the second is a string Value.
38 static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
39 const char *Val) {
40 Metadata *Ops[2] = {MDString::get(Context, Key), MDString::get(Context, Val)};
41 return MDTuple::get(Context, Ops);
42 }
43
44 // This returns an MDTuple representing the detiled summary. The tuple has two
45 // elements: a string "DetailedSummary" and an MDTuple representing the value
46 // of the detailed summary. Each element of this tuple is again an MDTuple whose
47 // elements are the (Cutoff, MinCount, NumCounts) triplet of the
48 // DetailedSummaryEntry.
49 Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) {
50 std::vector Entries;
51 Type *Int32Ty = Type::getInt32Ty(Context);
52 Type *Int64Ty = Type::getInt64Ty(Context);
53 for (auto &Entry : DetailedSummary) {
54 Metadata *EntryMD[3] = {
55 ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.Cutoff)),
56 ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Entry.MinCount)),
57 ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.NumCounts))};
58 Entries.push_back(MDTuple::get(Context, EntryMD));
59 }
60 Metadata *Ops[2] = {MDString::get(Context, "DetailedSummary"),
61 MDTuple::get(Context, Entries)};
62 return MDTuple::get(Context, Ops);
63 }
64
65 // This returns an MDTuple representing this ProfileSummary object. The first
66 // entry of this tuple is another MDTuple of two elements: a string
67 // "ProfileFormat" and a string representing the format ("InstrProf" or
68 // "SampleProfile"). The rest of the elements of the outer MDTuple are specific
69 // to the kind of profile summary as returned by getFormatSpecificMD.
70 Metadata *ProfileSummary::getMD(LLVMContext &Context) {
71 std::vector Components;
72 Components.push_back(getKeyValMD(Context, "ProfileFormat", getKindStr()));
73 std::vector Res = getFormatSpecificMD(Context);
74 Components.insert(Components.end(), Res.begin(), Res.end());
75 return MDTuple::get(Context, Components);
76 }
77
78 // Returns a vector of MDTuples specific to InstrProfSummary. The first six
79 // elements of this vector are (Key, Val) pairs of the six scalar fields of
80 // InstrProfSummary (TotalCount, MaxBlockCount, MaxInternalBlockCount,
81 // MaxFunctionCount, NumBlocks, NumFunctions). The last element of this vector
82 // is an MDTuple returned by getDetailedSummaryMD.
83 std::vector
84 InstrProfSummary::getFormatSpecificMD(LLVMContext &Context) {
85 std::vector Components;
86
87 Components.push_back(getKeyValMD(Context, "TotalCount", getTotalCount()));
88 Components.push_back(
89 getKeyValMD(Context, "MaxBlockCount", getMaxBlockCount()));
90 Components.push_back(getKeyValMD(Context, "MaxInternalBlockCount",
91 getMaxInternalBlockCount()));
92 Components.push_back(
93 getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()));
94 Components.push_back(getKeyValMD(Context, "NumBlocks", getNumBlocks()));
95 Components.push_back(getKeyValMD(Context, "NumFunctions", getNumFunctions()));
96
97 Components.push_back(getDetailedSummaryMD(Context));
98 return Components;
99 }
100
101 std::vector
102 SampleProfileSummary::getFormatSpecificMD(LLVMContext &Context) {
103 std::vector Components;
104
105 Components.push_back(getKeyValMD(Context, "TotalSamples", getTotalSamples()));
106 Components.push_back(
107 getKeyValMD(Context, "MaxSamplesPerLine", getMaxSamplesPerLine()));
108 Components.push_back(
109 getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()));
110 Components.push_back(
111 getKeyValMD(Context, "NumLinesWithSamples", getNumLinesWithSamples()));
112 Components.push_back(getKeyValMD(Context, "NumFunctions", NumFunctions));
113
114 Components.push_back(getDetailedSummaryMD(Context));
115 return Components;
116 }
117
118 // Parse an MDTuple representing (Key, Val) pair.
119 static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) {
120 if (!MD)
121 return false;
122 if (MD->getNumOperands() != 2)
123 return false;
124 MDString *KeyMD = dyn_cast(MD->getOperand(0));
125 ConstantAsMetadata *ValMD = dyn_cast(MD->getOperand(1));
126 if (!KeyMD || !ValMD)
127 return false;
128 if (!KeyMD->getString().equals(Key))
129 return false;
130 Val = cast(ValMD->getValue())->getZExtValue();
131 return true;
132 }
133
134 // Check if an MDTuple represents a (Key, Val) pair.
135 static bool isKeyValuePair(MDTuple *MD, const char *Key, const char *Val) {
136 if (!MD || MD->getNumOperands() != 2)
137 return false;
138 MDString *KeyMD = dyn_cast(MD->getOperand(0));
139 MDString *ValMD = dyn_cast(MD->getOperand(1));
140 if (!KeyMD || !ValMD)
141 return false;
142 if (!KeyMD->getString().equals(Key) || !ValMD->getString().equals(Val))
143 return false;
144 return true;
145 }
146
147 // Parse an MDTuple representing detailed summary.
148 static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary) {
149 if (!MD || MD->getNumOperands() != 2)
150 return false;
151 MDString *KeyMD = dyn_cast(MD->getOperand(0));
152 if (!KeyMD || !KeyMD->getString().equals("DetailedSummary"))
153 return false;
154 MDTuple *EntriesMD = dyn_cast(MD->getOperand(1));
155 if (!EntriesMD)
156 return false;
157 for (auto &&MDOp : EntriesMD->operands()) {
158 MDTuple *EntryMD = dyn_cast(MDOp);
159 if (!EntryMD || EntryMD->getNumOperands() != 3)
160 return false;
161 ConstantAsMetadata *Op0 =
162 dyn_cast(EntryMD->getOperand(0));
163 ConstantAsMetadata *Op1 =
164 dyn_cast(EntryMD->getOperand(1));
165 ConstantAsMetadata *Op2 =
166 dyn_cast(EntryMD->getOperand(2));
167
168 if (!Op0 || !Op1 || !Op2)
169 return false;
170 Summary.emplace_back(cast(Op0->getValue())->getZExtValue(),
171 cast(Op1->getValue())->getZExtValue(),
172 cast(Op2->getValue())->getZExtValue());
173 }
174 return true;
175 }
176
177 // Parse an MDTuple representing an InstrProfSummary object.
178 static ProfileSummary *getInstrProfSummaryFromMD(MDTuple *Tuple) {
179 uint64_t NumBlocks, TotalCount, NumFunctions, MaxFunctionCount, MaxBlockCount,
180 MaxInternalBlockCount;
181 SummaryEntryVector Summary;
182
183 if (Tuple->getNumOperands() != 8)
184 return nullptr;
185
186 // Skip operand 0 which has been already parsed in the caller
187 if (!getVal(dyn_cast(Tuple->getOperand(1)), "TotalCount",
188 TotalCount))
189 return nullptr;
190 if (!getVal(dyn_cast(Tuple->getOperand(2)), "MaxBlockCount",
191 MaxBlockCount))
192 return nullptr;
193 if (!getVal(dyn_cast(Tuple->getOperand(3)), "MaxInternalBlockCount",
194 MaxInternalBlockCount))
195 return nullptr;
196 if (!getVal(dyn_cast(Tuple->getOperand(4)), "MaxFunctionCount",
197 MaxFunctionCount))
198 return nullptr;
199 if (!getVal(dyn_cast(Tuple->getOperand(5)), "NumBlocks", NumBlocks))
200 return nullptr;
201 if (!getVal(dyn_cast(Tuple->getOperand(6)), "NumFunctions",
202 NumFunctions))
203 return nullptr;
204 if (!getSummaryFromMD(dyn_cast(Tuple->getOperand(7)), Summary))
205 return nullptr;
206 return new InstrProfSummary(TotalCount, MaxBlockCount, MaxInternalBlockCount,
207 MaxFunctionCount, NumBlocks, NumFunctions,
208 Summary);
209 }
210
211 // Parse an MDTuple representing a SampleProfileSummary object.
212 static ProfileSummary *getSampleProfileSummaryFromMD(MDTuple *Tuple) {
213 uint64_t TotalSamples, MaxSamplesPerLine, MaxFunctionCount,
214 NumLinesWithSamples, NumFunctions;
215 SummaryEntryVector Summary;
216
217 if (Tuple->getNumOperands() != 7)
218 return nullptr;
219
220 // Skip operand 0 which has been already parsed in the caller
221 if (!getVal(dyn_cast(Tuple->getOperand(1)), "TotalSamples",
222 TotalSamples))
223 return nullptr;
224 if (!getVal(dyn_cast(Tuple->getOperand(2)), "MaxSamplesPerLine",
225 MaxSamplesPerLine))
226 return nullptr;
227 if (!getVal(dyn_cast(Tuple->getOperand(3)), "MaxFunctionCount",
228 MaxFunctionCount))
229 return nullptr;
230 if (!getVal(dyn_cast(Tuple->getOperand(4)), "NumLinesWithSamples",
231 NumLinesWithSamples))
232 return nullptr;
233 if (!getVal(dyn_cast(Tuple->getOperand(5)), "NumFunctions",
234 NumFunctions))
235 return nullptr;
236 if (!getSummaryFromMD(dyn_cast(Tuple->getOperand(6)), Summary))
237 return nullptr;
238 return new SampleProfileSummary(TotalSamples, MaxSamplesPerLine,
239 MaxFunctionCount, NumLinesWithSamples,
240 NumFunctions, Summary);
241 }
242
243 ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) {
244 if (!isa(MD))
245 return nullptr;
246 MDTuple *Tuple = cast(MD);
247 auto &FormatMD = Tuple->getOperand(0);
248 if (isKeyValuePair(dyn_cast_or_null(FormatMD), "ProfileFormat",
249 "SampleProfile"))
250 return getSampleProfileSummaryFromMD(Tuple);
251 else if (isKeyValuePair(dyn_cast_or_null(FormatMD), "ProfileFormat",
252 "InstrProf"))
253 return getInstrProfSummaryFromMD(Tuple);
254 else
255 return nullptr;
256 }
11 InstrProf.cpp
22 InstrProfReader.cpp
33 InstrProfWriter.cpp
4 ProfileSummary.cpp
4 ProfileSummaryBuilder.cpp
55 SampleProf.cpp
66 SampleProfReader.cpp
77 SampleProfWriter.cpp
575575 const unsigned char *
576576 IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
577577 const unsigned char *Cur) {
578 using namespace IndexedInstrProf;
578579 using namespace support;
579580 if (Version >= IndexedInstrProf::Version4) {
580581 const IndexedInstrProf::Summary *SummaryInLE =
593594 for (unsigned I = 0; I < SummarySize / sizeof(uint64_t); I++)
594595 Dst[I] = endian::byte_swap(Src[I]);
595596
597 llvm::SummaryEntryVector DetailedSummary;
598 for (unsigned I = 0; I < SummaryData->NumCutoffEntries; I++) {
599 const IndexedInstrProf::Summary::Entry &Ent = SummaryData->getEntry(I);
600 DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
601 Ent.NumBlocks);
602 }
596603 // initialize InstrProfSummary using the SummaryData from disk.
597 this->Summary = llvm::make_unique(*(SummaryData.get()));
604 this->Summary = llvm::make_unique(
605 SummaryData->get(Summary::TotalBlockCount),
606 SummaryData->get(Summary::MaxBlockCount),
607 SummaryData->get(Summary::MaxInternalBlockCount),
608 SummaryData->get(Summary::MaxFunctionCount),
609 SummaryData->get(Summary::TotalNumBlocks),
610 SummaryData->get(Summary::TotalNumFunctions), DetailedSummary);
598611 return Cur + SummarySize;
599612 } else {
600613 // For older version of profile data, we need to compute on the fly:
601614 using namespace IndexedInstrProf;
602 this->Summary =
603 llvm::make_unique(ProfileSummary::DefaultCutoffs);
604 this->Summary->computeDetailedSummary();
615 InstrProfSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
616 // FIXME: This only computes an empty summary. Need to call addRecord for
617 // all InstrProfRecords to get the correct summary.
618 this->Summary.reset(Builder.getSummary());
605619 return Cur;
606620 }
607621 }
8383 typedef uint64_t offset_type;
8484
8585 support::endianness ValueProfDataEndianness;
86 InstrProfSummary *TheProfileSummary;
86 InstrProfSummaryBuilder *SummaryBuilder;
8787
8888 InstrProfRecordWriterTrait() : ValueProfDataEndianness(support::little) {}
8989 static hash_value_type ComputeHash(key_type_ref K) {
122122 endian::Writer LE(Out);
123123 for (const auto &ProfileData : *V) {
124124 const InstrProfRecord &ProfRecord = ProfileData.second;
125 TheProfileSummary->addRecord(ProfRecord);
125 SummaryBuilder->addRecord(ProfRecord);
126126
127127 LE.write(ProfileData.first); // Function hash
128128 LE.write(ProfRecord.Counts.size());
214214 OnDiskChainedHashTableGenerator Generator;
215215
216216 using namespace IndexedInstrProf;
217 InstrProfSummary PS(ProfileSummary::DefaultCutoffs);
218 InfoObj->TheProfileSummary = &PS;
217 InstrProfSummaryBuilder ISB(ProfileSummaryBuilder::DefaultCutoffs);
218 InfoObj->SummaryBuilder = &ISB;
219219
220220 // Populate the hash table generator.
221221 for (const auto &I : FunctionData)
244244 OS.write(0);
245245
246246 // Reserve space to write profile summary data.
247 uint32_t NumEntries = ProfileSummary::DefaultCutoffs.size();
247 uint32_t NumEntries = ProfileSummaryBuilder::DefaultCutoffs.size();
248248 uint32_t SummarySize = Summary::getSize(Summary::NumKinds, NumEntries);
249249 // Remember the summary offset.
250250 uint64_t SummaryOffset = OS.tell();
259259 IndexedInstrProf::allocSummary(SummarySize);
260260 // Compute the Summary and copy the data to the data
261261 // structure to be serialized out (to disk or buffer).
262 setSummary(TheSummary.get(), PS);
263 InfoObj->TheProfileSummary = 0;
262 InstrProfSummary *IPS = ISB.getSummary();
263 setSummary(TheSummary.get(), *IPS);
264 InfoObj->SummaryBuilder = 0;
264265
265266 // Now do the final patch:
266267 PatchItem PatchItems[] = {
+0
-368
lib/ProfileData/ProfileSummary.cpp less more
None //=-- Profilesummary.cpp - Profile summary computation ----------------------=//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains support for computing profile summary data.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/IR/Attributes.h"
14 #include "llvm/IR/Constants.h"
15 #include "llvm/IR/Function.h"
16 #include "llvm/IR/Metadata.h"
17 #include "llvm/IR/Type.h"
18 #include "llvm/ProfileData/InstrProf.h"
19 #include "llvm/ProfileData/ProfileCommon.h"
20 #include "llvm/ProfileData/SampleProf.h"
21 #include "llvm/Support/Casting.h"
22
23 using namespace llvm;
24
25 // A set of cutoff values. Each value, when divided by ProfileSummary::Scale
26 // (which is 1000000) is a desired percentile of total counts.
27 const std::vector ProfileSummary::DefaultCutoffs(
28 {10000, /* 1% */
29 100000, /* 10% */
30 200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000, 800000,
31 900000, 950000, 990000, 999000, 999900, 999990, 999999});
32 const char *ProfileSummary::KindStr[2] = {"InstrProf", "SampleProfile"};
33
34 void InstrProfSummary::addRecord(const InstrProfRecord &R) {
35 // The first counter is not necessarily an entry count for IR
36 // instrumentation profiles.
37 // Eventually MaxFunctionCount will become obsolete and this can be
38 // removed.
39 addEntryCount(R.Counts[0]);
40 for (size_t I = 1, E = R.Counts.size(); I < E; ++I)
41 addInternalCount(R.Counts[I]);
42 }
43
44 // To compute the detailed summary, we consider each line containing samples as
45 // equivalent to a block with a count in the instrumented profile.
46 void SampleProfileSummary::addRecord(const sampleprof::FunctionSamples &FS) {
47 NumFunctions++;
48 if (FS.getHeadSamples() > MaxFunctionCount)
49 MaxFunctionCount = FS.getHeadSamples();
50 for (const auto &I : FS.getBodySamples())
51 addCount(I.second.getSamples());
52 }
53
54 // The argument to this method is a vector of cutoff percentages and the return
55 // value is a vector of (Cutoff, MinCount, NumCounts) triplets.
56 void ProfileSummary::computeDetailedSummary() {
57 if (DetailedSummaryCutoffs.empty())
58 return;
59 auto Iter = CountFrequencies.begin();
60 auto End = CountFrequencies.end();
61 std::sort(DetailedSummaryCutoffs.begin(), DetailedSummaryCutoffs.end());
62
63 uint32_t CountsSeen = 0;
64 uint64_t CurrSum = 0, Count = 0;
65
66 for (uint32_t Cutoff : DetailedSummaryCutoffs) {
67 assert(Cutoff <= 999999);
68 APInt Temp(128, TotalCount);
69 APInt N(128, Cutoff);
70 APInt D(128, ProfileSummary::Scale);
71 Temp *= N;
72 Temp = Temp.sdiv(D);
73 uint64_t DesiredCount = Temp.getZExtValue();
74 assert(DesiredCount <= TotalCount);
75 while (CurrSum < DesiredCount && Iter != End) {
76 Count = Iter->first;
77 uint32_t Freq = Iter->second;
78 CurrSum += (Count * Freq);
79 CountsSeen += Freq;
80 Iter++;
81 }
82 assert(CurrSum >= DesiredCount);
83 ProfileSummaryEntry PSE = {Cutoff, Count, CountsSeen};
84 DetailedSummary.push_back(PSE);
85 }
86 }
87
88 // Returns true if the function is a hot function.
89 bool ProfileSummary::isFunctionHot(const Function *F) {
90 // FIXME: update when summary data is stored in module's metadata.
91 return false;
92 }
93
94 // Returns true if the function is a cold function.
95 bool ProfileSummary::isFunctionUnlikely(const Function *F) {
96 if (F->hasFnAttribute(Attribute::Cold)) {
97 return true;
98 }
99 if (!F->getEntryCount()) {
100 return false;
101 }
102 // FIXME: update when summary data is stored in module's metadata.
103 return (*F->getEntryCount()) == 0;
104 }
105
106 InstrProfSummary::InstrProfSummary(const IndexedInstrProf::Summary &S)
107 : ProfileSummary(PSK_Instr),
108 MaxInternalBlockCount(
109 S.get(IndexedInstrProf::Summary::MaxInternalBlockCount)) {
110
111 TotalCount = S.get(IndexedInstrProf::Summary::TotalBlockCount);
112 MaxCount = S.get(IndexedInstrProf::Summary::MaxBlockCount);
113 MaxFunctionCount = S.get(IndexedInstrProf::Summary::MaxFunctionCount);
114 NumCounts = S.get(IndexedInstrProf::Summary::TotalNumBlocks);
115 NumFunctions = S.get(IndexedInstrProf::Summary::TotalNumFunctions);
116
117 for (unsigned I = 0; I < S.NumCutoffEntries; I++) {
118 const IndexedInstrProf::Summary::Entry &Ent = S.getEntry(I);
119 DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
120 Ent.NumBlocks);
121 }
122 }
123
124 void InstrProfSummary::addEntryCount(uint64_t Count) {
125 addCount(Count);
126 NumFunctions++;
127 if (Count > MaxFunctionCount)
128 MaxFunctionCount = Count;
129 }
130
131 void InstrProfSummary::addInternalCount(uint64_t Count) {
132 addCount(Count);
133 if (Count > MaxInternalBlockCount)
134 MaxInternalBlockCount = Count;
135 }
136
137 // Return an MDTuple with two elements. The first element is a string Key and
138 // the second is a uint64_t Value.
139 static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
140 uint64_t Val) {
141 Type *Int64Ty = Type::getInt64Ty(Context);
142 Metadata *Ops[2] = {MDString::get(Context, Key),
143 ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Val))};
144 return MDTuple::get(Context, Ops);
145 }
146
147 // Return an MDTuple with two elements. The first element is a string Key and
148 // the second is a string Value.
149 static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
150 const char *Val) {
151 Metadata *Ops[2] = {MDString::get(Context, Key), MDString::get(Context, Val)};
152 return MDTuple::get(Context, Ops);
153 }
154
155 // This returns an MDTuple representing the detiled summary. The tuple has two
156 // elements: a string "DetailedSummary" and an MDTuple representing the value
157 // of the detailed summary. Each element of this tuple is again an MDTuple whose
158 // elements are the (Cutoff, MinCount, NumCounts) triplet of the
159 // DetailedSummaryEntry.
160 Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) {
161 std::vector Entries;
162 Type *Int32Ty = Type::getInt32Ty(Context);
163 Type *Int64Ty = Type::getInt64Ty(Context);
164 for (auto &Entry : DetailedSummary) {
165 Metadata *EntryMD[3] = {
166 ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.Cutoff)),
167 ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Entry.MinCount)),
168 ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.NumCounts))};
169 Entries.push_back(MDTuple::get(Context, EntryMD));
170 }
171 Metadata *Ops[2] = {MDString::get(Context, "DetailedSummary"),
172 MDTuple::get(Context, Entries)};
173 return MDTuple::get(Context, Ops);
174 }
175
176 // This returns an MDTuple representing this ProfileSummary object. The first
177 // entry of this tuple is another MDTuple of two elements: a string
178 // "ProfileFormat" and a string representing the format ("InstrProf" or
179 // "SampleProfile"). The rest of the elements of the outer MDTuple are specific
180 // to the kind of profile summary as returned by getFormatSpecificMD.
181 Metadata *ProfileSummary::getMD(LLVMContext &Context) {
182 std::vector Components;
183 Components.push_back(getKeyValMD(Context, "ProfileFormat", getKindStr()));
184 std::vector Res = getFormatSpecificMD(Context);
185 Components.insert(Components.end(), Res.begin(), Res.end());
186 return MDTuple::get(Context, Components);
187 }
188
189 // Returns a vector of MDTuples specific to InstrProfSummary. The first six
190 // elements of this vector are (Key, Val) pairs of the six scalar fields of
191 // InstrProfSummary (TotalCount, MaxBlockCount, MaxInternalBlockCount,
192 // MaxFunctionCount, NumBlocks, NumFunctions). The last element of this vector
193 // is an MDTuple returned by getDetailedSummaryMD.
194 std::vector
195 InstrProfSummary::getFormatSpecificMD(LLVMContext &Context) {
196 std::vector Components;
197
198 Components.push_back(getKeyValMD(Context, "TotalCount", getTotalCount()));
199 Components.push_back(
200 getKeyValMD(Context, "MaxBlockCount", getMaxBlockCount()));
201 Components.push_back(getKeyValMD(Context, "MaxInternalBlockCount",
202 getMaxInternalBlockCount()));
203 Components.push_back(
204 getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()));
205 Components.push_back(getKeyValMD(Context, "NumBlocks", getNumBlocks()));
206 Components.push_back(getKeyValMD(Context, "NumFunctions", getNumFunctions()));
207
208 Components.push_back(getDetailedSummaryMD(Context));
209 return Components;
210 }
211
212 std::vector
213 SampleProfileSummary::getFormatSpecificMD(LLVMContext &Context) {
214 std::vector Components;
215
216 Components.push_back(getKeyValMD(Context, "TotalSamples", getTotalSamples()));
217 Components.push_back(
218 getKeyValMD(Context, "MaxSamplesPerLine", getMaxSamplesPerLine()));
219 Components.push_back(
220 getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()));
221 Components.push_back(
222 getKeyValMD(Context, "NumLinesWithSamples", getNumLinesWithSamples()));
223 Components.push_back(getKeyValMD(Context, "NumFunctions", NumFunctions));
224
225 Components.push_back(getDetailedSummaryMD(Context));
226 return Components;
227 }
228
229 // Parse an MDTuple representing (Key, Val) pair.
230 static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) {
231 if (!MD)
232 return false;
233 if (MD->getNumOperands() != 2)
234 return false;
235 MDString *KeyMD = dyn_cast(MD->getOperand(0));
236 ConstantAsMetadata *ValMD = dyn_cast(MD->getOperand(1));
237 if (!KeyMD || !ValMD)
238 return false;
239 if (!KeyMD->getString().equals(Key))
240 return false;
241 Val = cast(ValMD->getValue())->getZExtValue();
242 return true;
243 }
244
245 // Check if an MDTuple represents a (Key, Val) pair.
246 static bool isKeyValuePair(MDTuple *MD, const char *Key, const char *Val) {
247 if (!MD || MD->getNumOperands() != 2)
248 return false;
249 MDString *KeyMD = dyn_cast(MD->getOperand(0));
250 MDString *ValMD = dyn_cast(MD->getOperand(1));
251 if (!KeyMD || !ValMD)
252 return false;
253 if (!KeyMD->getString().equals(Key) || !ValMD->getString().equals(Val))
254 return false;
255 return true;
256 }
257
258 // Parse an MDTuple representing detailed summary.
259 static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary) {
260 if (!MD || MD->getNumOperands() != 2)
261 return false;
262 MDString *KeyMD = dyn_cast(MD->getOperand(0));
263 if (!KeyMD || !KeyMD->getString().equals("DetailedSummary"))
264 return false;
265 MDTuple *EntriesMD = dyn_cast(MD->getOperand(1));
266 if (!EntriesMD)
267 return false;
268 for (auto &&MDOp : EntriesMD->operands()) {
269 MDTuple *EntryMD = dyn_cast(MDOp);
270 if (!EntryMD || EntryMD->getNumOperands() != 3)
271 return false;
272 ConstantAsMetadata *Op0 =
273 dyn_cast(EntryMD->getOperand(0));
274 ConstantAsMetadata *Op1 =
275 dyn_cast(EntryMD->getOperand(1));
276 ConstantAsMetadata *Op2 =
277 dyn_cast(EntryMD->getOperand(2));
278
279 if (!Op0 || !Op1 || !Op2)
280 return false;
281 Summary.emplace_back(cast(Op0->getValue())->getZExtValue(),
282 cast(Op1->getValue())->getZExtValue(),
283 cast(Op2->getValue())->getZExtValue());
284 }
285 return true;
286 }
287
288 // Parse an MDTuple representing an InstrProfSummary object.
289 static ProfileSummary *getInstrProfSummaryFromMD(MDTuple *Tuple) {
290 uint64_t NumBlocks, TotalCount, NumFunctions, MaxFunctionCount, MaxBlockCount,
291 MaxInternalBlockCount;
292 SummaryEntryVector Summary;
293
294 if (Tuple->getNumOperands() != 8)
295 return nullptr;
296
297 // Skip operand 0 which has been already parsed in the caller
298 if (!getVal(dyn_cast(Tuple->getOperand(1)), "TotalCount",
299 TotalCount))
300 return nullptr;
301 if (!getVal(dyn_cast(Tuple->getOperand(2)), "MaxBlockCount",
302 MaxBlockCount))
303 return nullptr;
304 if (!getVal(dyn_cast(Tuple->getOperand(3)), "MaxInternalBlockCount",
305 MaxInternalBlockCount))
306 return nullptr;
307 if (!getVal(dyn_cast(Tuple->getOperand(4)), "MaxFunctionCount",
308 MaxFunctionCount))
309 return nullptr;
310 if (!getVal(dyn_cast(Tuple->getOperand(5)), "NumBlocks", NumBlocks))
311 return nullptr;
312 if (!getVal(dyn_cast(Tuple->getOperand(6)), "NumFunctions",
313 NumFunctions))
314 return nullptr;
315 if (!getSummaryFromMD(dyn_cast(Tuple->getOperand(7)), Summary))
316 return nullptr;
317 return new InstrProfSummary(TotalCount, MaxBlockCount, MaxInternalBlockCount,
318 MaxFunctionCount, NumBlocks, NumFunctions,
319 Summary);
320 }
321
322 // Parse an MDTuple representing a SampleProfileSummary object.
323 static ProfileSummary *getSampleProfileSummaryFromMD(MDTuple *Tuple) {
324 uint64_t TotalSamples, MaxSamplesPerLine, MaxFunctionCount,
325 NumLinesWithSamples, NumFunctions;
326 SummaryEntryVector Summary;
327
328 if (Tuple->getNumOperands() != 7)
329 return nullptr;
330
331 // Skip operand 0 which has been already parsed in the caller
332 if (!getVal(dyn_cast(Tuple->getOperand(1)), "TotalSamples",
333 TotalSamples))
334 return nullptr;
335 if (!getVal(dyn_cast(Tuple->getOperand(2)), "MaxSamplesPerLine",
336 MaxSamplesPerLine))
337 return nullptr;
338 if (!getVal(dyn_cast(Tuple->getOperand(3)), "MaxFunctionCount",
339 MaxFunctionCount))
340 return nullptr;
341 if (!getVal(dyn_cast(Tuple->getOperand(4)), "NumLinesWithSamples",
342 NumLinesWithSamples))
343 return nullptr;
344 if (!getVal(dyn_cast(Tuple->getOperand(5)), "NumFunctions",
345 NumFunctions))
346 return nullptr;
347 if (!getSummaryFromMD(dyn_cast(Tuple->getOperand(6)), Summary))
348 return nullptr;
349 return new SampleProfileSummary(TotalSamples, MaxSamplesPerLine,
350 MaxFunctionCount, NumLinesWithSamples,
351 NumFunctions, Summary);
352 }
353
354 ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) {
355 if (!isa(MD))
356 return nullptr;
357 MDTuple *Tuple = cast(MD);
358 auto &FormatMD = Tuple->getOperand(0);
359 if (isKeyValuePair(dyn_cast_or_null(FormatMD), "ProfileFormat",
360 "SampleProfile"))
361 return getSampleProfileSummaryFromMD(Tuple);
362 else if (isKeyValuePair(dyn_cast_or_null(FormatMD), "ProfileFormat",
363 "InstrProf"))
364 return getInstrProfSummaryFromMD(Tuple);
365 else
366 return nullptr;
367 }
0 //=-- ProfilesummaryBuilder.cpp - Profile summary computation ---------------=//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains support for computing profile summary data.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/IR/Attributes.h"
14 #include "llvm/IR/Constants.h"
15 #include "llvm/IR/Function.h"
16 #include "llvm/IR/Metadata.h"
17 #include "llvm/IR/Type.h"
18 #include "llvm/ProfileData/InstrProf.h"
19 #include "llvm/ProfileData/ProfileCommon.h"
20 #include "llvm/ProfileData/SampleProf.h"
21 #include "llvm/Support/Casting.h"
22
23 using namespace llvm;
24
25 // A set of cutoff values. Each value, when divided by ProfileSummary::Scale
26 // (which is 1000000) is a desired percentile of total counts.
27 const std::vector ProfileSummaryBuilder::DefaultCutoffs(
28 {10000, /* 1% */
29 100000, /* 10% */
30 200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000, 800000,
31 900000, 950000, 990000, 999000, 999900, 999990, 999999});
32
33 void InstrProfSummaryBuilder::addRecord(const InstrProfRecord &R) {
34 // The first counter is not necessarily an entry count for IR
35 // instrumentation profiles.
36 // Eventually MaxFunctionCount will become obsolete and this can be
37 // removed.
38 addEntryCount(R.Counts[0]);
39 for (size_t I = 1, E = R.Counts.size(); I < E; ++I)
40 addInternalCount(R.Counts[I]);
41 }
42
43 // To compute the detailed summary, we consider each line containing samples as
44 // equivalent to a block with a count in the instrumented profile.
45 void SampleProfileSummaryBuilder::addRecord(
46 const sampleprof::FunctionSamples &FS) {
47 NumFunctions++;
48 if (FS.getHeadSamples() > MaxFunctionCount)
49 MaxFunctionCount = FS.getHeadSamples();
50 for (const auto &I : FS.getBodySamples())
51 addCount(I.second.getSamples());
52 }
53
54 // The argument to this method is a vector of cutoff percentages and the return
55 // value is a vector of (Cutoff, MinCount, NumCounts) triplets.
56 void ProfileSummaryBuilder::computeDetailedSummary() {
57 if (DetailedSummaryCutoffs.empty())
58 return;
59 auto Iter = CountFrequencies.begin();
60 auto End = CountFrequencies.end();
61 std::sort(DetailedSummaryCutoffs.begin(), DetailedSummaryCutoffs.end());
62
63 uint32_t CountsSeen = 0;
64 uint64_t CurrSum = 0, Count = 0;
65
66 for (uint32_t Cutoff : DetailedSummaryCutoffs) {
67 assert(Cutoff <= 999999);
68 APInt Temp(128, TotalCount);
69 APInt N(128, Cutoff);
70 APInt D(128, ProfileSummary::Scale);
71 Temp *= N;
72 Temp = Temp.sdiv(D);
73 uint64_t DesiredCount = Temp.getZExtValue();
74 assert(DesiredCount <= TotalCount);
75 while (CurrSum < DesiredCount && Iter != End) {
76 Count = Iter->first;
77 uint32_t Freq = Iter->second;
78 CurrSum += (Count * Freq);
79 CountsSeen += Freq;
80 Iter++;
81 }
82 assert(CurrSum >= DesiredCount);
83 ProfileSummaryEntry PSE = {Cutoff, Count, CountsSeen};
84 DetailedSummary.push_back(PSE);
85 }
86 }
87
88 SampleProfileSummary *SampleProfileSummaryBuilder::getSummary() {
89 computeDetailedSummary();
90 return new SampleProfileSummary(TotalCount, MaxCount, MaxFunctionCount,
91 NumCounts, NumFunctions, DetailedSummary);
92 }
93
94 InstrProfSummary *InstrProfSummaryBuilder::getSummary() {
95 computeDetailedSummary();
96 return new InstrProfSummary(TotalCount, MaxCount, MaxInternalBlockCount,
97 MaxFunctionCount, NumCounts, NumFunctions,
98 DetailedSummary);
99 }
100
101 void InstrProfSummaryBuilder::addEntryCount(uint64_t Count) {
102 addCount(Count);
103 NumFunctions++;
104 if (Count > MaxFunctionCount)
105 MaxFunctionCount = Count;
106 }
107
108 void InstrProfSummaryBuilder::addInternalCount(uint64_t Count) {
109 addCount(Count);
110 if (Count > MaxInternalBlockCount)
111 MaxInternalBlockCount = Count;
112 }
792792 // For text and GCC file formats, we compute the summary after reading the
793793 // profile. Binary format has the profile summary in its header.
794794 void SampleProfileReader::computeSummary() {
795 Summary.reset(new SampleProfileSummary(ProfileSummary::DefaultCutoffs));
795 SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
796796 for (const auto &I : Profiles) {
797797 const FunctionSamples &Profile = I.second;
798 Summary->addRecord(Profile);
799 }
800 Summary->computeDetailedSummary();
801 }
798 Builder.addRecord(Profile);
799 }
800 Summary.reset(Builder.getSummary());
801 }
254254
255255 void SampleProfileWriter::computeSummary(
256256 const StringMap &ProfileMap) {
257 Summary.reset(new SampleProfileSummary(ProfileSummary::DefaultCutoffs));
257 SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
258258 for (const auto &I : ProfileMap) {
259259 const FunctionSamples &Profile = I.second;
260 Summary->addRecord(Profile);
261 }
262 Summary->computeDetailedSummary();
263 }
260 Builder.addRecord(Profile);
261 }
262 Summary.reset(Builder.getSummary());
263 }
280280 if (ShowDetailedSummary && DetailedSummaryCutoffs.empty()) {
281281 Cutoffs = {800000, 900000, 950000, 990000, 999000, 999900, 999990};
282282 }
283 InstrProfSummary PS(Cutoffs);
283 InstrProfSummaryBuilder Builder(Cutoffs);
284284 if (Error E = ReaderOrErr.takeError())
285285 exitWithError(std::move(E), Filename);
286286
301301 }
302302
303303 assert(Func.Counts.size() > 0 && "function missing entry counter");
304 PS.addRecord(Func);
304 Builder.addRecord(Func);
305305
306306 if (Show) {
307307
352352
353353 if (ShowCounts && TextFormat)
354354 return 0;
355
355 std::unique_ptr PS(Builder.getSummary());
356356 if (ShowAllFunctions || !ShowFunction.empty())
357357 OS << "Functions shown: " << ShownFunctions << "\n";
358 OS << "Total functions: " << PS.getNumFunctions() << "\n";
359 OS << "Maximum function count: " << PS.getMaxFunctionCount() << "\n";
360 OS << "Maximum internal block count: " << PS.getMaxInternalBlockCount() << "\n";
358 OS << "Total functions: " << PS->getNumFunctions() << "\n";
359 OS << "Maximum function count: " << PS->getMaxFunctionCount() << "\n";
360 OS << "Maximum internal block count: " << PS->getMaxInternalBlockCount()
361 << "\n";
361362
362363 if (ShowDetailedSummary) {
363364 OS << "Detailed summary:\n";
364 OS << "Total number of blocks: " << PS.getNumBlocks() << "\n";
365 OS << "Total count: " << PS.getTotalCount() << "\n";
366 for (auto Entry : PS.getDetailedSummary()) {
365 OS << "Total number of blocks: " << PS->getNumBlocks() << "\n";
366 OS << "Total count: " << PS->getTotalCount() << "\n";
367 for (auto Entry : PS->getDetailedSummary()) {
367368 OS << Entry.NumCounts << " blocks with count >= " << Entry.MinCount
368369 << " account for "
369370 << format("%0.6g", (float)Entry.Cutoff / ProfileSummary::Scale * 100)