blob: 33c1479e19c8ab59c2d34f2b0cf4faca80ca95d7 [file] [log] [blame]
Easwaran Ramand68aae22016-02-04 23:34:31 +00001//=-- Profilesummary.cpp - Profile summary computation ----------------------=//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains support for computing profile summary data.
11//
12//===----------------------------------------------------------------------===//
13
Dehao Chenf84b6302016-02-23 03:39:24 +000014#include "llvm/IR/Attributes.h"
Easwaran Raman7c4f25d2016-03-01 18:30:58 +000015#include "llvm/IR/Constants.h"
Dehao Chenf84b6302016-02-23 03:39:24 +000016#include "llvm/IR/Function.h"
Easwaran Raman7c4f25d2016-03-01 18:30:58 +000017#include "llvm/IR/Metadata.h"
18#include "llvm/IR/Type.h"
Easwaran Ramand68aae22016-02-04 23:34:31 +000019#include "llvm/ProfileData/InstrProf.h"
Easwaran Raman40ee23d2016-02-19 03:15:33 +000020#include "llvm/ProfileData/ProfileCommon.h"
21#include "llvm/ProfileData/SampleProf.h"
Easwaran Raman7c4f25d2016-03-01 18:30:58 +000022#include "llvm/Support/Casting.h"
Easwaran Ramand68aae22016-02-04 23:34:31 +000023
24using namespace llvm;
25
Easwaran Raman40ee23d2016-02-19 03:15:33 +000026// A set of cutoff values. Each value, when divided by ProfileSummary::Scale
27// (which is 1000000) is a desired percentile of total counts.
28const std::vector<uint32_t> ProfileSummary::DefaultCutoffs(
29 {10000, /* 1% */
30 100000, /* 10% */
31 200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000, 800000,
32 900000, 950000, 990000, 999000, 999900, 999990, 999999});
Easwaran Raman8832e5e2016-03-01 18:59:11 +000033const char *ProfileSummary::KindStr[2] = {"InstrProf", "SampleProfile"};
Easwaran Raman40ee23d2016-02-19 03:15:33 +000034
Easwaran Raman43095702016-02-17 18:18:47 +000035void InstrProfSummary::addRecord(const InstrProfRecord &R) {
36 addEntryCount(R.Counts[0]);
37 for (size_t I = 1, E = R.Counts.size(); I < E; ++I)
38 addInternalCount(R.Counts[I]);
Easwaran Ramand68aae22016-02-04 23:34:31 +000039}
40
Easwaran Raman40ee23d2016-02-19 03:15:33 +000041// To compute the detailed summary, we consider each line containing samples as
42// equivalent to a block with a count in the instrumented profile.
43void SampleProfileSummary::addRecord(const sampleprof::FunctionSamples &FS) {
44 NumFunctions++;
Easwaran Raman8f6b9ef2016-03-28 18:58:05 +000045 if (FS.getHeadSamples() > MaxFunctionCount)
46 MaxFunctionCount = FS.getHeadSamples();
Easwaran Raman40ee23d2016-02-19 03:15:33 +000047 for (const auto &I : FS.getBodySamples())
48 addCount(I.second.getSamples());
49}
50
Easwaran Ramand68aae22016-02-04 23:34:31 +000051// The argument to this method is a vector of cutoff percentages and the return
Easwaran Raman43095702016-02-17 18:18:47 +000052// value is a vector of (Cutoff, MinCount, NumCounts) triplets.
Easwaran Ramand68aae22016-02-04 23:34:31 +000053void ProfileSummary::computeDetailedSummary() {
54 if (DetailedSummaryCutoffs.empty())
55 return;
56 auto Iter = CountFrequencies.begin();
57 auto End = CountFrequencies.end();
58 std::sort(DetailedSummaryCutoffs.begin(), DetailedSummaryCutoffs.end());
59
Easwaran Raman43095702016-02-17 18:18:47 +000060 uint32_t CountsSeen = 0;
Easwaran Ramand68aae22016-02-04 23:34:31 +000061 uint64_t CurrSum = 0, Count = 0;
62
63 for (uint32_t Cutoff : DetailedSummaryCutoffs) {
64 assert(Cutoff <= 999999);
65 APInt Temp(128, TotalCount);
66 APInt N(128, Cutoff);
67 APInt D(128, ProfileSummary::Scale);
68 Temp *= N;
69 Temp = Temp.sdiv(D);
70 uint64_t DesiredCount = Temp.getZExtValue();
71 assert(DesiredCount <= TotalCount);
72 while (CurrSum < DesiredCount && Iter != End) {
73 Count = Iter->first;
74 uint32_t Freq = Iter->second;
75 CurrSum += (Count * Freq);
Easwaran Raman43095702016-02-17 18:18:47 +000076 CountsSeen += Freq;
Easwaran Ramand68aae22016-02-04 23:34:31 +000077 Iter++;
78 }
79 assert(CurrSum >= DesiredCount);
Easwaran Raman43095702016-02-17 18:18:47 +000080 ProfileSummaryEntry PSE = {Cutoff, Count, CountsSeen};
Easwaran Ramand68aae22016-02-04 23:34:31 +000081 DetailedSummary.push_back(PSE);
82 }
83}
84
Dehao Chenf84b6302016-02-23 03:39:24 +000085// Returns true if the function is a hot function.
86bool ProfileSummary::isFunctionHot(const Function *F) {
87 // FIXME: update when summary data is stored in module's metadata.
88 return false;
89}
90
91// Returns true if the function is a cold function.
92bool ProfileSummary::isFunctionUnlikely(const Function *F) {
93 if (F->hasFnAttribute(Attribute::Cold)) {
94 return true;
95 }
96 if (!F->getEntryCount()) {
97 return false;
98 }
99 // FIXME: update when summary data is stored in module's metadata.
100 return (*F->getEntryCount()) == 0;
101}
102
Easwaran Raman43095702016-02-17 18:18:47 +0000103InstrProfSummary::InstrProfSummary(const IndexedInstrProf::Summary &S)
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000104 : ProfileSummary(PSK_Instr),
105 MaxInternalBlockCount(
Easwaran Raman8f6b9ef2016-03-28 18:58:05 +0000106 S.get(IndexedInstrProf::Summary::MaxInternalBlockCount)) {
Easwaran Raman43095702016-02-17 18:18:47 +0000107
108 TotalCount = S.get(IndexedInstrProf::Summary::TotalBlockCount);
109 MaxCount = S.get(IndexedInstrProf::Summary::MaxBlockCount);
Easwaran Raman8f6b9ef2016-03-28 18:58:05 +0000110 MaxFunctionCount = S.get(IndexedInstrProf::Summary::MaxFunctionCount);
Easwaran Raman43095702016-02-17 18:18:47 +0000111 NumCounts = S.get(IndexedInstrProf::Summary::TotalNumBlocks);
Easwaran Raman8f6b9ef2016-03-28 18:58:05 +0000112 NumFunctions = S.get(IndexedInstrProf::Summary::TotalNumFunctions);
Easwaran Raman43095702016-02-17 18:18:47 +0000113
Easwaran Ramand68aae22016-02-04 23:34:31 +0000114 for (unsigned I = 0; I < S.NumCutoffEntries; I++) {
115 const IndexedInstrProf::Summary::Entry &Ent = S.getEntry(I);
116 DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
117 Ent.NumBlocks);
118 }
119}
Easwaran Raman8f6b9ef2016-03-28 18:58:05 +0000120
Easwaran Raman43095702016-02-17 18:18:47 +0000121void InstrProfSummary::addEntryCount(uint64_t Count) {
122 addCount(Count);
123 NumFunctions++;
124 if (Count > MaxFunctionCount)
125 MaxFunctionCount = Count;
126}
127
128void InstrProfSummary::addInternalCount(uint64_t Count) {
129 addCount(Count);
130 if (Count > MaxInternalBlockCount)
131 MaxInternalBlockCount = Count;
132}
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000133
134// Return an MDTuple with two elements. The first element is a string Key and
135// the second is a uint64_t Value.
136static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
137 uint64_t Val) {
138 Type *Int64Ty = Type::getInt64Ty(Context);
139 Metadata *Ops[2] = {MDString::get(Context, Key),
140 ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Val))};
141 return MDTuple::get(Context, Ops);
142}
143
144// Return an MDTuple with two elements. The first element is a string Key and
145// the second is a string Value.
146static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
147 const char *Val) {
148 Metadata *Ops[2] = {MDString::get(Context, Key), MDString::get(Context, Val)};
149 return MDTuple::get(Context, Ops);
150}
151
152// This returns an MDTuple representing the detiled summary. The tuple has two
153// elements: a string "DetailedSummary" and an MDTuple representing the value
154// of the detailed summary. Each element of this tuple is again an MDTuple whose
155// elements are the (Cutoff, MinCount, NumCounts) triplet of the
156// DetailedSummaryEntry.
157Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) {
158 std::vector<Metadata *> Entries;
159 Type *Int32Ty = Type::getInt32Ty(Context);
160 Type *Int64Ty = Type::getInt64Ty(Context);
161 for (auto &Entry : DetailedSummary) {
162 Metadata *EntryMD[3] = {
163 ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.Cutoff)),
164 ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Entry.MinCount)),
165 ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.NumCounts))};
166 Entries.push_back(MDTuple::get(Context, EntryMD));
167 }
168 Metadata *Ops[2] = {MDString::get(Context, "DetailedSummary"),
169 MDTuple::get(Context, Entries)};
170 return MDTuple::get(Context, Ops);
171}
172
173// This returns an MDTuple representing this ProfileSummary object. The first
174// entry of this tuple is another MDTuple of two elements: a string
175// "ProfileFormat" and a string representing the format ("InstrProf" or
176// "SampleProfile"). The rest of the elements of the outer MDTuple are specific
177// to the kind of profile summary as returned by getFormatSpecificMD.
178Metadata *ProfileSummary::getMD(LLVMContext &Context) {
179 std::vector<Metadata *> Components;
180 Components.push_back(getKeyValMD(Context, "ProfileFormat", getKindStr()));
181 std::vector<Metadata *> Res = getFormatSpecificMD(Context);
182 Components.insert(Components.end(), Res.begin(), Res.end());
183 return MDTuple::get(Context, Components);
184}
185
186// Returns a vector of MDTuples specific to InstrProfSummary. The first six
187// elements of this vector are (Key, Val) pairs of the six scalar fields of
188// InstrProfSummary (TotalCount, MaxBlockCount, MaxInternalBlockCount,
189// MaxFunctionCount, NumBlocks, NumFunctions). The last element of this vector
190// is an MDTuple returned by getDetailedSummaryMD.
191std::vector<Metadata *>
192InstrProfSummary::getFormatSpecificMD(LLVMContext &Context) {
193 std::vector<Metadata *> Components;
194
195 Components.push_back(getKeyValMD(Context, "TotalCount", getTotalCount()));
196 Components.push_back(
197 getKeyValMD(Context, "MaxBlockCount", getMaxBlockCount()));
198 Components.push_back(getKeyValMD(Context, "MaxInternalBlockCount",
199 getMaxInternalBlockCount()));
200 Components.push_back(
201 getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()));
202 Components.push_back(getKeyValMD(Context, "NumBlocks", getNumBlocks()));
203 Components.push_back(getKeyValMD(Context, "NumFunctions", getNumFunctions()));
204
205 Components.push_back(getDetailedSummaryMD(Context));
206 return Components;
207}
208
209std::vector<Metadata *>
210SampleProfileSummary::getFormatSpecificMD(LLVMContext &Context) {
211 std::vector<Metadata *> Components;
212
213 Components.push_back(getKeyValMD(Context, "TotalSamples", getTotalSamples()));
214 Components.push_back(
215 getKeyValMD(Context, "MaxSamplesPerLine", getMaxSamplesPerLine()));
216 Components.push_back(
Easwaran Raman6f4903d2016-03-28 23:14:29 +0000217 getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()));
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000218 Components.push_back(
219 getKeyValMD(Context, "NumLinesWithSamples", getNumLinesWithSamples()));
220 Components.push_back(getKeyValMD(Context, "NumFunctions", NumFunctions));
221
222 Components.push_back(getDetailedSummaryMD(Context));
223 return Components;
224}
225
226// Parse an MDTuple representing (Key, Val) pair.
227static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) {
228 if (!MD)
229 return false;
230 if (MD->getNumOperands() != 2)
231 return false;
232 MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
233 ConstantAsMetadata *ValMD = dyn_cast<ConstantAsMetadata>(MD->getOperand(1));
234 if (!KeyMD || !ValMD)
235 return false;
236 if (!KeyMD->getString().equals(Key))
237 return false;
238 Val = cast<ConstantInt>(ValMD->getValue())->getZExtValue();
239 return true;
240}
241
242// Check if an MDTuple represents a (Key, Val) pair.
243static bool isKeyValuePair(MDTuple *MD, const char *Key, const char *Val) {
244 if (!MD || MD->getNumOperands() != 2)
245 return false;
246 MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
247 MDString *ValMD = dyn_cast<MDString>(MD->getOperand(1));
248 if (!KeyMD || !ValMD)
249 return false;
250 if (!KeyMD->getString().equals(Key) || !ValMD->getString().equals(Val))
251 return false;
252 return true;
253}
254
255// Parse an MDTuple representing detailed summary.
256static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary) {
257 if (!MD || MD->getNumOperands() != 2)
258 return false;
259 MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
260 if (!KeyMD || !KeyMD->getString().equals("DetailedSummary"))
261 return false;
262 MDTuple *EntriesMD = dyn_cast<MDTuple>(MD->getOperand(1));
263 if (!EntriesMD)
264 return false;
265 for (auto &&MDOp : EntriesMD->operands()) {
266 MDTuple *EntryMD = dyn_cast<MDTuple>(MDOp);
267 if (!EntryMD || EntryMD->getNumOperands() != 3)
268 return false;
269 ConstantAsMetadata *Op0 =
270 dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(0));
271 ConstantAsMetadata *Op1 =
272 dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(1));
273 ConstantAsMetadata *Op2 =
274 dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(2));
275
276 if (!Op0 || !Op1 || !Op2)
277 return false;
278 Summary.emplace_back(cast<ConstantInt>(Op0->getValue())->getZExtValue(),
279 cast<ConstantInt>(Op1->getValue())->getZExtValue(),
280 cast<ConstantInt>(Op2->getValue())->getZExtValue());
281 }
282 return true;
283}
284
285// Parse an MDTuple representing an InstrProfSummary object.
286static ProfileSummary *getInstrProfSummaryFromMD(MDTuple *Tuple) {
287 uint64_t NumBlocks, TotalCount, NumFunctions, MaxFunctionCount, MaxBlockCount,
288 MaxInternalBlockCount;
289 SummaryEntryVector Summary;
290
291 if (Tuple->getNumOperands() != 8)
292 return nullptr;
293
294 // Skip operand 0 which has been already parsed in the caller
295 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalCount",
296 TotalCount))
297 return nullptr;
298 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxBlockCount",
299 MaxBlockCount))
300 return nullptr;
301 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxInternalBlockCount",
302 MaxInternalBlockCount))
303 return nullptr;
304 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "MaxFunctionCount",
305 MaxFunctionCount))
306 return nullptr;
307 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumBlocks", NumBlocks))
308 return nullptr;
309 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(6)), "NumFunctions",
310 NumFunctions))
311 return nullptr;
312 if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(7)), Summary))
313 return nullptr;
314 return new InstrProfSummary(TotalCount, MaxBlockCount, MaxInternalBlockCount,
315 MaxFunctionCount, NumBlocks, NumFunctions,
316 Summary);
317}
318
319// Parse an MDTuple representing a SampleProfileSummary object.
320static ProfileSummary *getSampleProfileSummaryFromMD(MDTuple *Tuple) {
Easwaran Raman6f4903d2016-03-28 23:14:29 +0000321 uint64_t TotalSamples, MaxSamplesPerLine, MaxFunctionCount,
322 NumLinesWithSamples, NumFunctions;
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000323 SummaryEntryVector Summary;
324
325 if (Tuple->getNumOperands() != 7)
326 return nullptr;
327
328 // Skip operand 0 which has been already parsed in the caller
329 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalSamples",
330 TotalSamples))
331 return nullptr;
332 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxSamplesPerLine",
333 MaxSamplesPerLine))
334 return nullptr;
Easwaran Raman6f4903d2016-03-28 23:14:29 +0000335 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxFunctionCount",
336 MaxFunctionCount))
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000337 return nullptr;
338 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "NumLinesWithSamples",
339 NumLinesWithSamples))
340 return nullptr;
341 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumFunctions",
342 NumFunctions))
343 return nullptr;
344 if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(6)), Summary))
345 return nullptr;
346 return new SampleProfileSummary(TotalSamples, MaxSamplesPerLine,
Easwaran Raman6f4903d2016-03-28 23:14:29 +0000347 MaxFunctionCount, NumLinesWithSamples,
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000348 NumFunctions, Summary);
349}
350
351ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) {
352 if (!isa<MDTuple>(MD))
353 return nullptr;
354 MDTuple *Tuple = cast<MDTuple>(MD);
355 auto &FormatMD = Tuple->getOperand(0);
356 if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
357 "SampleProfile"))
358 return getSampleProfileSummaryFromMD(Tuple);
359 else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
360 "InstrProf"))
361 return getInstrProfSummaryFromMD(Tuple);
362 else
363 return nullptr;
364}