blob: 51bcd1845c7d222ee86c6dc9e2bc985565613eae [file] [log] [blame]
Easwaran Ramane5a17e32016-05-19 21:07:12 +00001//=-- Profilesummary.cpp - Profile summary support --------------------------=//
Easwaran Ramand68aae22016-02-04 23:34:31 +00002//
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//
Easwaran Ramane5a17e32016-05-19 21:07:12 +000010// This file contains support for converting profile summary data from/to
11// metadata.
Easwaran Ramand68aae22016-02-04 23:34:31 +000012//
13//===----------------------------------------------------------------------===//
14
Easwaran Ramane5a17e32016-05-19 21:07:12 +000015#include "llvm/IR/ProfileSummary.h"
Dehao Chenf84b6302016-02-23 03:39:24 +000016#include "llvm/IR/Attributes.h"
Easwaran Raman7c4f25d2016-03-01 18:30:58 +000017#include "llvm/IR/Constants.h"
Dehao Chenf84b6302016-02-23 03:39:24 +000018#include "llvm/IR/Function.h"
Easwaran Raman7c4f25d2016-03-01 18:30:58 +000019#include "llvm/IR/Metadata.h"
20#include "llvm/IR/Type.h"
Easwaran Raman7c4f25d2016-03-01 18:30:58 +000021#include "llvm/Support/Casting.h"
Easwaran Ramand68aae22016-02-04 23:34:31 +000022
23using namespace llvm;
24
Easwaran Raman8832e5e2016-03-01 18:59:11 +000025const char *ProfileSummary::KindStr[2] = {"InstrProf", "SampleProfile"};
Easwaran Raman40ee23d2016-02-19 03:15:33 +000026
Easwaran Raman7c4f25d2016-03-01 18:30:58 +000027// Return an MDTuple with two elements. The first element is a string Key and
28// the second is a uint64_t Value.
29static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
30 uint64_t Val) {
31 Type *Int64Ty = Type::getInt64Ty(Context);
32 Metadata *Ops[2] = {MDString::get(Context, Key),
33 ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Val))};
34 return MDTuple::get(Context, Ops);
35}
36
37// Return an MDTuple with two elements. The first element is a string Key and
38// the second is a string Value.
39static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
40 const char *Val) {
41 Metadata *Ops[2] = {MDString::get(Context, Key), MDString::get(Context, Val)};
42 return MDTuple::get(Context, Ops);
43}
44
45// This returns an MDTuple representing the detiled summary. The tuple has two
46// elements: a string "DetailedSummary" and an MDTuple representing the value
47// of the detailed summary. Each element of this tuple is again an MDTuple whose
48// elements are the (Cutoff, MinCount, NumCounts) triplet of the
49// DetailedSummaryEntry.
50Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) {
51 std::vector<Metadata *> Entries;
52 Type *Int32Ty = Type::getInt32Ty(Context);
53 Type *Int64Ty = Type::getInt64Ty(Context);
54 for (auto &Entry : DetailedSummary) {
55 Metadata *EntryMD[3] = {
56 ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.Cutoff)),
57 ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Entry.MinCount)),
58 ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.NumCounts))};
59 Entries.push_back(MDTuple::get(Context, EntryMD));
60 }
61 Metadata *Ops[2] = {MDString::get(Context, "DetailedSummary"),
62 MDTuple::get(Context, Entries)};
63 return MDTuple::get(Context, Ops);
64}
65
66// This returns an MDTuple representing this ProfileSummary object. The first
67// entry of this tuple is another MDTuple of two elements: a string
68// "ProfileFormat" and a string representing the format ("InstrProf" or
69// "SampleProfile"). The rest of the elements of the outer MDTuple are specific
70// to the kind of profile summary as returned by getFormatSpecificMD.
71Metadata *ProfileSummary::getMD(LLVMContext &Context) {
72 std::vector<Metadata *> Components;
73 Components.push_back(getKeyValMD(Context, "ProfileFormat", getKindStr()));
74 std::vector<Metadata *> Res = getFormatSpecificMD(Context);
75 Components.insert(Components.end(), Res.begin(), Res.end());
76 return MDTuple::get(Context, Components);
77}
78
79// Returns a vector of MDTuples specific to InstrProfSummary. The first six
80// elements of this vector are (Key, Val) pairs of the six scalar fields of
81// InstrProfSummary (TotalCount, MaxBlockCount, MaxInternalBlockCount,
82// MaxFunctionCount, NumBlocks, NumFunctions). The last element of this vector
83// is an MDTuple returned by getDetailedSummaryMD.
84std::vector<Metadata *>
85InstrProfSummary::getFormatSpecificMD(LLVMContext &Context) {
86 std::vector<Metadata *> Components;
87
88 Components.push_back(getKeyValMD(Context, "TotalCount", getTotalCount()));
89 Components.push_back(
90 getKeyValMD(Context, "MaxBlockCount", getMaxBlockCount()));
91 Components.push_back(getKeyValMD(Context, "MaxInternalBlockCount",
92 getMaxInternalBlockCount()));
93 Components.push_back(
94 getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()));
95 Components.push_back(getKeyValMD(Context, "NumBlocks", getNumBlocks()));
96 Components.push_back(getKeyValMD(Context, "NumFunctions", getNumFunctions()));
97
98 Components.push_back(getDetailedSummaryMD(Context));
99 return Components;
100}
101
102std::vector<Metadata *>
103SampleProfileSummary::getFormatSpecificMD(LLVMContext &Context) {
104 std::vector<Metadata *> Components;
105
106 Components.push_back(getKeyValMD(Context, "TotalSamples", getTotalSamples()));
107 Components.push_back(
108 getKeyValMD(Context, "MaxSamplesPerLine", getMaxSamplesPerLine()));
109 Components.push_back(
Easwaran Raman6f4903d2016-03-28 23:14:29 +0000110 getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()));
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000111 Components.push_back(
112 getKeyValMD(Context, "NumLinesWithSamples", getNumLinesWithSamples()));
113 Components.push_back(getKeyValMD(Context, "NumFunctions", NumFunctions));
114
115 Components.push_back(getDetailedSummaryMD(Context));
116 return Components;
117}
118
119// Parse an MDTuple representing (Key, Val) pair.
120static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) {
121 if (!MD)
122 return false;
123 if (MD->getNumOperands() != 2)
124 return false;
125 MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
126 ConstantAsMetadata *ValMD = dyn_cast<ConstantAsMetadata>(MD->getOperand(1));
127 if (!KeyMD || !ValMD)
128 return false;
129 if (!KeyMD->getString().equals(Key))
130 return false;
131 Val = cast<ConstantInt>(ValMD->getValue())->getZExtValue();
132 return true;
133}
134
135// Check if an MDTuple represents a (Key, Val) pair.
136static bool isKeyValuePair(MDTuple *MD, const char *Key, const char *Val) {
137 if (!MD || MD->getNumOperands() != 2)
138 return false;
139 MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
140 MDString *ValMD = dyn_cast<MDString>(MD->getOperand(1));
141 if (!KeyMD || !ValMD)
142 return false;
143 if (!KeyMD->getString().equals(Key) || !ValMD->getString().equals(Val))
144 return false;
145 return true;
146}
147
148// Parse an MDTuple representing detailed summary.
149static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary) {
150 if (!MD || MD->getNumOperands() != 2)
151 return false;
152 MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
153 if (!KeyMD || !KeyMD->getString().equals("DetailedSummary"))
154 return false;
155 MDTuple *EntriesMD = dyn_cast<MDTuple>(MD->getOperand(1));
156 if (!EntriesMD)
157 return false;
158 for (auto &&MDOp : EntriesMD->operands()) {
159 MDTuple *EntryMD = dyn_cast<MDTuple>(MDOp);
160 if (!EntryMD || EntryMD->getNumOperands() != 3)
161 return false;
162 ConstantAsMetadata *Op0 =
163 dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(0));
164 ConstantAsMetadata *Op1 =
165 dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(1));
166 ConstantAsMetadata *Op2 =
167 dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(2));
168
169 if (!Op0 || !Op1 || !Op2)
170 return false;
171 Summary.emplace_back(cast<ConstantInt>(Op0->getValue())->getZExtValue(),
172 cast<ConstantInt>(Op1->getValue())->getZExtValue(),
173 cast<ConstantInt>(Op2->getValue())->getZExtValue());
174 }
175 return true;
176}
177
178// Parse an MDTuple representing an InstrProfSummary object.
179static ProfileSummary *getInstrProfSummaryFromMD(MDTuple *Tuple) {
180 uint64_t NumBlocks, TotalCount, NumFunctions, MaxFunctionCount, MaxBlockCount,
181 MaxInternalBlockCount;
182 SummaryEntryVector Summary;
183
184 if (Tuple->getNumOperands() != 8)
185 return nullptr;
186
187 // Skip operand 0 which has been already parsed in the caller
188 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalCount",
189 TotalCount))
190 return nullptr;
191 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxBlockCount",
192 MaxBlockCount))
193 return nullptr;
194 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxInternalBlockCount",
195 MaxInternalBlockCount))
196 return nullptr;
197 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "MaxFunctionCount",
198 MaxFunctionCount))
199 return nullptr;
200 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumBlocks", NumBlocks))
201 return nullptr;
202 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(6)), "NumFunctions",
203 NumFunctions))
204 return nullptr;
205 if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(7)), Summary))
206 return nullptr;
207 return new InstrProfSummary(TotalCount, MaxBlockCount, MaxInternalBlockCount,
208 MaxFunctionCount, NumBlocks, NumFunctions,
209 Summary);
210}
211
212// Parse an MDTuple representing a SampleProfileSummary object.
213static ProfileSummary *getSampleProfileSummaryFromMD(MDTuple *Tuple) {
Easwaran Raman6f4903d2016-03-28 23:14:29 +0000214 uint64_t TotalSamples, MaxSamplesPerLine, MaxFunctionCount,
215 NumLinesWithSamples, NumFunctions;
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000216 SummaryEntryVector Summary;
217
218 if (Tuple->getNumOperands() != 7)
219 return nullptr;
220
221 // Skip operand 0 which has been already parsed in the caller
222 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalSamples",
223 TotalSamples))
224 return nullptr;
225 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxSamplesPerLine",
226 MaxSamplesPerLine))
227 return nullptr;
Easwaran Raman6f4903d2016-03-28 23:14:29 +0000228 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxFunctionCount",
229 MaxFunctionCount))
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000230 return nullptr;
231 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "NumLinesWithSamples",
232 NumLinesWithSamples))
233 return nullptr;
234 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumFunctions",
235 NumFunctions))
236 return nullptr;
237 if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(6)), Summary))
238 return nullptr;
239 return new SampleProfileSummary(TotalSamples, MaxSamplesPerLine,
Easwaran Raman6f4903d2016-03-28 23:14:29 +0000240 MaxFunctionCount, NumLinesWithSamples,
Easwaran Raman7c4f25d2016-03-01 18:30:58 +0000241 NumFunctions, Summary);
242}
243
244ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) {
245 if (!isa<MDTuple>(MD))
246 return nullptr;
247 MDTuple *Tuple = cast<MDTuple>(MD);
248 auto &FormatMD = Tuple->getOperand(0);
249 if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
250 "SampleProfile"))
251 return getSampleProfileSummaryFromMD(Tuple);
252 else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
253 "InstrProf"))
254 return getInstrProfSummaryFromMD(Tuple);
255 else
256 return nullptr;
257}