blob: 82546eb47d448f3b7f0b0ed68d78be3a16504d47 [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++;
45 if (FS.getHeadSamples() > MaxHeadSamples)
46 MaxHeadSamples = FS.getHeadSamples();
47 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(
106 S.get(IndexedInstrProf::Summary::MaxInternalBlockCount)),
Easwaran Ramand68aae22016-02-04 23:34:31 +0000107 MaxFunctionCount(S.get(IndexedInstrProf::Summary::MaxFunctionCount)),
Easwaran Ramand68aae22016-02-04 23:34:31 +0000108 NumFunctions(S.get(IndexedInstrProf::Summary::TotalNumFunctions)) {
Easwaran Raman43095702016-02-17 18:18:47 +0000109
110 TotalCount = S.get(IndexedInstrProf::Summary::TotalBlockCount);
111 MaxCount = S.get(IndexedInstrProf::Summary::MaxBlockCount);
112 NumCounts = S.get(IndexedInstrProf::Summary::TotalNumBlocks);
113
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 Raman43095702016-02-17 18:18:47 +0000120void InstrProfSummary::addEntryCount(uint64_t Count) {
121 addCount(Count);
122 NumFunctions++;
123 if (Count > MaxFunctionCount)
124 MaxFunctionCount = Count;
125}
126
127void InstrProfSummary::addInternalCount(uint64_t Count) {
128 addCount(Count);
129 if (Count > MaxInternalBlockCount)
130 MaxInternalBlockCount = Count;
131}
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000132
133// Return an MDTuple with two elements. The first element is a string Key and
134// the second is a uint64_t Value.
135static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
136 uint64_t Val) {
137 Type *Int64Ty = Type::getInt64Ty(Context);
138 Metadata *Ops[2] = {MDString::get(Context, Key),
139 ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Val))};
140 return MDTuple::get(Context, Ops);
141}
142
143// Return an MDTuple with two elements. The first element is a string Key and
144// the second is a string Value.
145static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
146 const char *Val) {
147 Metadata *Ops[2] = {MDString::get(Context, Key), MDString::get(Context, Val)};
148 return MDTuple::get(Context, Ops);
149}
150
151// This returns an MDTuple representing the detiled summary. The tuple has two
152// elements: a string "DetailedSummary" and an MDTuple representing the value
153// of the detailed summary. Each element of this tuple is again an MDTuple whose
154// elements are the (Cutoff, MinCount, NumCounts) triplet of the
155// DetailedSummaryEntry.
156Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) {
157 std::vector<Metadata *> Entries;
158 Type *Int32Ty = Type::getInt32Ty(Context);
159 Type *Int64Ty = Type::getInt64Ty(Context);
160 for (auto &Entry : DetailedSummary) {
161 Metadata *EntryMD[3] = {
162 ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.Cutoff)),
163 ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Entry.MinCount)),
164 ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.NumCounts))};
165 Entries.push_back(MDTuple::get(Context, EntryMD));
166 }
167 Metadata *Ops[2] = {MDString::get(Context, "DetailedSummary"),
168 MDTuple::get(Context, Entries)};
169 return MDTuple::get(Context, Ops);
170}
171
172// This returns an MDTuple representing this ProfileSummary object. The first
173// entry of this tuple is another MDTuple of two elements: a string
174// "ProfileFormat" and a string representing the format ("InstrProf" or
175// "SampleProfile"). The rest of the elements of the outer MDTuple are specific
176// to the kind of profile summary as returned by getFormatSpecificMD.
177Metadata *ProfileSummary::getMD(LLVMContext &Context) {
178 std::vector<Metadata *> Components;
179 Components.push_back(getKeyValMD(Context, "ProfileFormat", getKindStr()));
180 std::vector<Metadata *> Res = getFormatSpecificMD(Context);
181 Components.insert(Components.end(), Res.begin(), Res.end());
182 return MDTuple::get(Context, Components);
183}
184
185// Returns a vector of MDTuples specific to InstrProfSummary. The first six
186// elements of this vector are (Key, Val) pairs of the six scalar fields of
187// InstrProfSummary (TotalCount, MaxBlockCount, MaxInternalBlockCount,
188// MaxFunctionCount, NumBlocks, NumFunctions). The last element of this vector
189// is an MDTuple returned by getDetailedSummaryMD.
190std::vector<Metadata *>
191InstrProfSummary::getFormatSpecificMD(LLVMContext &Context) {
192 std::vector<Metadata *> Components;
193
194 Components.push_back(getKeyValMD(Context, "TotalCount", getTotalCount()));
195 Components.push_back(
196 getKeyValMD(Context, "MaxBlockCount", getMaxBlockCount()));
197 Components.push_back(getKeyValMD(Context, "MaxInternalBlockCount",
198 getMaxInternalBlockCount()));
199 Components.push_back(
200 getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()));
201 Components.push_back(getKeyValMD(Context, "NumBlocks", getNumBlocks()));
202 Components.push_back(getKeyValMD(Context, "NumFunctions", getNumFunctions()));
203
204 Components.push_back(getDetailedSummaryMD(Context));
205 return Components;
206}
207
208std::vector<Metadata *>
209SampleProfileSummary::getFormatSpecificMD(LLVMContext &Context) {
210 std::vector<Metadata *> Components;
211
212 Components.push_back(getKeyValMD(Context, "TotalSamples", getTotalSamples()));
213 Components.push_back(
214 getKeyValMD(Context, "MaxSamplesPerLine", getMaxSamplesPerLine()));
215 Components.push_back(
216 getKeyValMD(Context, "MaxHeadSamples", getMaxHeadSamples()));
217 Components.push_back(
218 getKeyValMD(Context, "NumLinesWithSamples", getNumLinesWithSamples()));
219 Components.push_back(getKeyValMD(Context, "NumFunctions", NumFunctions));
220
221 Components.push_back(getDetailedSummaryMD(Context));
222 return Components;
223}
224
225// Parse an MDTuple representing (Key, Val) pair.
226static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) {
227 if (!MD)
228 return false;
229 if (MD->getNumOperands() != 2)
230 return false;
231 MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
232 ConstantAsMetadata *ValMD = dyn_cast<ConstantAsMetadata>(MD->getOperand(1));
233 if (!KeyMD || !ValMD)
234 return false;
235 if (!KeyMD->getString().equals(Key))
236 return false;
237 Val = cast<ConstantInt>(ValMD->getValue())->getZExtValue();
238 return true;
239}
240
241// Check if an MDTuple represents a (Key, Val) pair.
242static bool isKeyValuePair(MDTuple *MD, const char *Key, const char *Val) {
243 if (!MD || MD->getNumOperands() != 2)
244 return false;
245 MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
246 MDString *ValMD = dyn_cast<MDString>(MD->getOperand(1));
247 if (!KeyMD || !ValMD)
248 return false;
249 if (!KeyMD->getString().equals(Key) || !ValMD->getString().equals(Val))
250 return false;
251 return true;
252}
253
254// Parse an MDTuple representing detailed summary.
255static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary) {
256 if (!MD || MD->getNumOperands() != 2)
257 return false;
258 MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
259 if (!KeyMD || !KeyMD->getString().equals("DetailedSummary"))
260 return false;
261 MDTuple *EntriesMD = dyn_cast<MDTuple>(MD->getOperand(1));
262 if (!EntriesMD)
263 return false;
264 for (auto &&MDOp : EntriesMD->operands()) {
265 MDTuple *EntryMD = dyn_cast<MDTuple>(MDOp);
266 if (!EntryMD || EntryMD->getNumOperands() != 3)
267 return false;
268 ConstantAsMetadata *Op0 =
269 dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(0));
270 ConstantAsMetadata *Op1 =
271 dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(1));
272 ConstantAsMetadata *Op2 =
273 dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(2));
274
275 if (!Op0 || !Op1 || !Op2)
276 return false;
277 Summary.emplace_back(cast<ConstantInt>(Op0->getValue())->getZExtValue(),
278 cast<ConstantInt>(Op1->getValue())->getZExtValue(),
279 cast<ConstantInt>(Op2->getValue())->getZExtValue());
280 }
281 return true;
282}
283
284// Parse an MDTuple representing an InstrProfSummary object.
285static ProfileSummary *getInstrProfSummaryFromMD(MDTuple *Tuple) {
286 uint64_t NumBlocks, TotalCount, NumFunctions, MaxFunctionCount, MaxBlockCount,
287 MaxInternalBlockCount;
288 SummaryEntryVector Summary;
289
290 if (Tuple->getNumOperands() != 8)
291 return nullptr;
292
293 // Skip operand 0 which has been already parsed in the caller
294 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalCount",
295 TotalCount))
296 return nullptr;
297 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxBlockCount",
298 MaxBlockCount))
299 return nullptr;
300 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxInternalBlockCount",
301 MaxInternalBlockCount))
302 return nullptr;
303 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "MaxFunctionCount",
304 MaxFunctionCount))
305 return nullptr;
306 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumBlocks", NumBlocks))
307 return nullptr;
308 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(6)), "NumFunctions",
309 NumFunctions))
310 return nullptr;
311 if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(7)), Summary))
312 return nullptr;
313 return new InstrProfSummary(TotalCount, MaxBlockCount, MaxInternalBlockCount,
314 MaxFunctionCount, NumBlocks, NumFunctions,
315 Summary);
316}
317
318// Parse an MDTuple representing a SampleProfileSummary object.
319static ProfileSummary *getSampleProfileSummaryFromMD(MDTuple *Tuple) {
320 uint64_t TotalSamples, MaxSamplesPerLine, MaxHeadSamples, NumLinesWithSamples,
321 NumFunctions;
322 SummaryEntryVector Summary;
323
324 if (Tuple->getNumOperands() != 7)
325 return nullptr;
326
327 // Skip operand 0 which has been already parsed in the caller
328 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalSamples",
329 TotalSamples))
330 return nullptr;
331 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxSamplesPerLine",
332 MaxSamplesPerLine))
333 return nullptr;
334 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxHeadSamples",
335 MaxHeadSamples))
336 return nullptr;
337 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "NumLinesWithSamples",
338 NumLinesWithSamples))
339 return nullptr;
340 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumFunctions",
341 NumFunctions))
342 return nullptr;
343 if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(6)), Summary))
344 return nullptr;
345 return new SampleProfileSummary(TotalSamples, MaxSamplesPerLine,
346 MaxHeadSamples, NumLinesWithSamples,
347 NumFunctions, Summary);
348}
349
350ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) {
351 if (!isa<MDTuple>(MD))
352 return nullptr;
353 MDTuple *Tuple = cast<MDTuple>(MD);
354 auto &FormatMD = Tuple->getOperand(0);
355 if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
356 "SampleProfile"))
357 return getSampleProfileSummaryFromMD(Tuple);
358 else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
359 "InstrProf"))
360 return getInstrProfSummaryFromMD(Tuple);
361 else
362 return nullptr;
363}