1*9880d681SAndroid Build Coastguard Worker //=-- SampleProf.h - Sampling profiling format support --------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains common definitions used in the reading and writing of
11*9880d681SAndroid Build Coastguard Worker // sample profile data.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_PROFILEDATA_SAMPLEPROF_H_
16*9880d681SAndroid Build Coastguard Worker #define LLVM_PROFILEDATA_SAMPLEPROF_H_
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringMap.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorOr.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker #include <map>
25*9880d681SAndroid Build Coastguard Worker #include <system_error>
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker namespace llvm {
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker const std::error_category &sampleprof_category();
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker enum class sampleprof_error {
32*9880d681SAndroid Build Coastguard Worker success = 0,
33*9880d681SAndroid Build Coastguard Worker bad_magic,
34*9880d681SAndroid Build Coastguard Worker unsupported_version,
35*9880d681SAndroid Build Coastguard Worker too_large,
36*9880d681SAndroid Build Coastguard Worker truncated,
37*9880d681SAndroid Build Coastguard Worker malformed,
38*9880d681SAndroid Build Coastguard Worker unrecognized_format,
39*9880d681SAndroid Build Coastguard Worker unsupported_writing_format,
40*9880d681SAndroid Build Coastguard Worker truncated_name_table,
41*9880d681SAndroid Build Coastguard Worker not_implemented,
42*9880d681SAndroid Build Coastguard Worker counter_overflow
43*9880d681SAndroid Build Coastguard Worker };
44*9880d681SAndroid Build Coastguard Worker
make_error_code(sampleprof_error E)45*9880d681SAndroid Build Coastguard Worker inline std::error_code make_error_code(sampleprof_error E) {
46*9880d681SAndroid Build Coastguard Worker return std::error_code(static_cast<int>(E), sampleprof_category());
47*9880d681SAndroid Build Coastguard Worker }
48*9880d681SAndroid Build Coastguard Worker
MergeResult(sampleprof_error & Accumulator,sampleprof_error Result)49*9880d681SAndroid Build Coastguard Worker inline sampleprof_error MergeResult(sampleprof_error &Accumulator,
50*9880d681SAndroid Build Coastguard Worker sampleprof_error Result) {
51*9880d681SAndroid Build Coastguard Worker // Prefer first error encountered as later errors may be secondary effects of
52*9880d681SAndroid Build Coastguard Worker // the initial problem.
53*9880d681SAndroid Build Coastguard Worker if (Accumulator == sampleprof_error::success &&
54*9880d681SAndroid Build Coastguard Worker Result != sampleprof_error::success)
55*9880d681SAndroid Build Coastguard Worker Accumulator = Result;
56*9880d681SAndroid Build Coastguard Worker return Accumulator;
57*9880d681SAndroid Build Coastguard Worker }
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker namespace std {
62*9880d681SAndroid Build Coastguard Worker template <>
63*9880d681SAndroid Build Coastguard Worker struct is_error_code_enum<llvm::sampleprof_error> : std::true_type {};
64*9880d681SAndroid Build Coastguard Worker }
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker namespace llvm {
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker namespace sampleprof {
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker static inline uint64_t SPMagic() {
71*9880d681SAndroid Build Coastguard Worker return uint64_t('S') << (64 - 8) | uint64_t('P') << (64 - 16) |
72*9880d681SAndroid Build Coastguard Worker uint64_t('R') << (64 - 24) | uint64_t('O') << (64 - 32) |
73*9880d681SAndroid Build Coastguard Worker uint64_t('F') << (64 - 40) | uint64_t('4') << (64 - 48) |
74*9880d681SAndroid Build Coastguard Worker uint64_t('2') << (64 - 56) | uint64_t(0xff);
75*9880d681SAndroid Build Coastguard Worker }
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker static inline uint64_t SPVersion() { return 103; }
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker /// Represents the relative location of an instruction.
80*9880d681SAndroid Build Coastguard Worker ///
81*9880d681SAndroid Build Coastguard Worker /// Instruction locations are specified by the line offset from the
82*9880d681SAndroid Build Coastguard Worker /// beginning of the function (marked by the line where the function
83*9880d681SAndroid Build Coastguard Worker /// header is) and the discriminator value within that line.
84*9880d681SAndroid Build Coastguard Worker ///
85*9880d681SAndroid Build Coastguard Worker /// The discriminator value is useful to distinguish instructions
86*9880d681SAndroid Build Coastguard Worker /// that are on the same line but belong to different basic blocks
87*9880d681SAndroid Build Coastguard Worker /// (e.g., the two post-increment instructions in "if (p) x++; else y++;").
88*9880d681SAndroid Build Coastguard Worker struct LineLocation {
89*9880d681SAndroid Build Coastguard Worker LineLocation(uint32_t L, uint32_t D) : LineOffset(L), Discriminator(D) {}
90*9880d681SAndroid Build Coastguard Worker void print(raw_ostream &OS) const;
91*9880d681SAndroid Build Coastguard Worker void dump() const;
92*9880d681SAndroid Build Coastguard Worker bool operator<(const LineLocation &O) const {
93*9880d681SAndroid Build Coastguard Worker return LineOffset < O.LineOffset ||
94*9880d681SAndroid Build Coastguard Worker (LineOffset == O.LineOffset && Discriminator < O.Discriminator);
95*9880d681SAndroid Build Coastguard Worker }
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker uint32_t LineOffset;
98*9880d681SAndroid Build Coastguard Worker uint32_t Discriminator;
99*9880d681SAndroid Build Coastguard Worker };
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<<(raw_ostream &OS, const LineLocation &Loc);
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker /// Representation of a single sample record.
104*9880d681SAndroid Build Coastguard Worker ///
105*9880d681SAndroid Build Coastguard Worker /// A sample record is represented by a positive integer value, which
106*9880d681SAndroid Build Coastguard Worker /// indicates how frequently was the associated line location executed.
107*9880d681SAndroid Build Coastguard Worker ///
108*9880d681SAndroid Build Coastguard Worker /// Additionally, if the associated location contains a function call,
109*9880d681SAndroid Build Coastguard Worker /// the record will hold a list of all the possible called targets. For
110*9880d681SAndroid Build Coastguard Worker /// direct calls, this will be the exact function being invoked. For
111*9880d681SAndroid Build Coastguard Worker /// indirect calls (function pointers, virtual table dispatch), this
112*9880d681SAndroid Build Coastguard Worker /// will be a list of one or more functions.
113*9880d681SAndroid Build Coastguard Worker class SampleRecord {
114*9880d681SAndroid Build Coastguard Worker public:
115*9880d681SAndroid Build Coastguard Worker typedef StringMap<uint64_t> CallTargetMap;
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker SampleRecord() : NumSamples(0), CallTargets() {}
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker /// Increment the number of samples for this record by \p S.
120*9880d681SAndroid Build Coastguard Worker /// Optionally scale sample count \p S by \p Weight.
121*9880d681SAndroid Build Coastguard Worker ///
122*9880d681SAndroid Build Coastguard Worker /// Sample counts accumulate using saturating arithmetic, to avoid wrapping
123*9880d681SAndroid Build Coastguard Worker /// around unsigned integers.
124*9880d681SAndroid Build Coastguard Worker sampleprof_error addSamples(uint64_t S, uint64_t Weight = 1) {
125*9880d681SAndroid Build Coastguard Worker bool Overflowed;
126*9880d681SAndroid Build Coastguard Worker NumSamples = SaturatingMultiplyAdd(S, Weight, NumSamples, &Overflowed);
127*9880d681SAndroid Build Coastguard Worker return Overflowed ? sampleprof_error::counter_overflow
128*9880d681SAndroid Build Coastguard Worker : sampleprof_error::success;
129*9880d681SAndroid Build Coastguard Worker }
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker /// Add called function \p F with samples \p S.
132*9880d681SAndroid Build Coastguard Worker /// Optionally scale sample count \p S by \p Weight.
133*9880d681SAndroid Build Coastguard Worker ///
134*9880d681SAndroid Build Coastguard Worker /// Sample counts accumulate using saturating arithmetic, to avoid wrapping
135*9880d681SAndroid Build Coastguard Worker /// around unsigned integers.
136*9880d681SAndroid Build Coastguard Worker sampleprof_error addCalledTarget(StringRef F, uint64_t S,
137*9880d681SAndroid Build Coastguard Worker uint64_t Weight = 1) {
138*9880d681SAndroid Build Coastguard Worker uint64_t &TargetSamples = CallTargets[F];
139*9880d681SAndroid Build Coastguard Worker bool Overflowed;
140*9880d681SAndroid Build Coastguard Worker TargetSamples =
141*9880d681SAndroid Build Coastguard Worker SaturatingMultiplyAdd(S, Weight, TargetSamples, &Overflowed);
142*9880d681SAndroid Build Coastguard Worker return Overflowed ? sampleprof_error::counter_overflow
143*9880d681SAndroid Build Coastguard Worker : sampleprof_error::success;
144*9880d681SAndroid Build Coastguard Worker }
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker /// Return true if this sample record contains function calls.
147*9880d681SAndroid Build Coastguard Worker bool hasCalls() const { return CallTargets.size() > 0; }
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker uint64_t getSamples() const { return NumSamples; }
150*9880d681SAndroid Build Coastguard Worker const CallTargetMap &getCallTargets() const { return CallTargets; }
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Worker /// Merge the samples in \p Other into this record.
153*9880d681SAndroid Build Coastguard Worker /// Optionally scale sample counts by \p Weight.
154*9880d681SAndroid Build Coastguard Worker sampleprof_error merge(const SampleRecord &Other, uint64_t Weight = 1) {
155*9880d681SAndroid Build Coastguard Worker sampleprof_error Result = addSamples(Other.getSamples(), Weight);
156*9880d681SAndroid Build Coastguard Worker for (const auto &I : Other.getCallTargets()) {
157*9880d681SAndroid Build Coastguard Worker MergeResult(Result, addCalledTarget(I.first(), I.second, Weight));
158*9880d681SAndroid Build Coastguard Worker }
159*9880d681SAndroid Build Coastguard Worker return Result;
160*9880d681SAndroid Build Coastguard Worker }
161*9880d681SAndroid Build Coastguard Worker
162*9880d681SAndroid Build Coastguard Worker void print(raw_ostream &OS, unsigned Indent) const;
163*9880d681SAndroid Build Coastguard Worker void dump() const;
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker private:
166*9880d681SAndroid Build Coastguard Worker uint64_t NumSamples;
167*9880d681SAndroid Build Coastguard Worker CallTargetMap CallTargets;
168*9880d681SAndroid Build Coastguard Worker };
169*9880d681SAndroid Build Coastguard Worker
170*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<<(raw_ostream &OS, const SampleRecord &Sample);
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker typedef std::map<LineLocation, SampleRecord> BodySampleMap;
173*9880d681SAndroid Build Coastguard Worker class FunctionSamples;
174*9880d681SAndroid Build Coastguard Worker typedef std::map<LineLocation, FunctionSamples> CallsiteSampleMap;
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker /// Representation of the samples collected for a function.
177*9880d681SAndroid Build Coastguard Worker ///
178*9880d681SAndroid Build Coastguard Worker /// This data structure contains all the collected samples for the body
179*9880d681SAndroid Build Coastguard Worker /// of a function. Each sample corresponds to a LineLocation instance
180*9880d681SAndroid Build Coastguard Worker /// within the body of the function.
181*9880d681SAndroid Build Coastguard Worker class FunctionSamples {
182*9880d681SAndroid Build Coastguard Worker public:
183*9880d681SAndroid Build Coastguard Worker FunctionSamples() : Name(), TotalSamples(0), TotalHeadSamples(0) {}
184*9880d681SAndroid Build Coastguard Worker void print(raw_ostream &OS = dbgs(), unsigned Indent = 0) const;
185*9880d681SAndroid Build Coastguard Worker void dump() const;
186*9880d681SAndroid Build Coastguard Worker sampleprof_error addTotalSamples(uint64_t Num, uint64_t Weight = 1) {
187*9880d681SAndroid Build Coastguard Worker bool Overflowed;
188*9880d681SAndroid Build Coastguard Worker TotalSamples =
189*9880d681SAndroid Build Coastguard Worker SaturatingMultiplyAdd(Num, Weight, TotalSamples, &Overflowed);
190*9880d681SAndroid Build Coastguard Worker return Overflowed ? sampleprof_error::counter_overflow
191*9880d681SAndroid Build Coastguard Worker : sampleprof_error::success;
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight = 1) {
194*9880d681SAndroid Build Coastguard Worker bool Overflowed;
195*9880d681SAndroid Build Coastguard Worker TotalHeadSamples =
196*9880d681SAndroid Build Coastguard Worker SaturatingMultiplyAdd(Num, Weight, TotalHeadSamples, &Overflowed);
197*9880d681SAndroid Build Coastguard Worker return Overflowed ? sampleprof_error::counter_overflow
198*9880d681SAndroid Build Coastguard Worker : sampleprof_error::success;
199*9880d681SAndroid Build Coastguard Worker }
200*9880d681SAndroid Build Coastguard Worker sampleprof_error addBodySamples(uint32_t LineOffset, uint32_t Discriminator,
201*9880d681SAndroid Build Coastguard Worker uint64_t Num, uint64_t Weight = 1) {
202*9880d681SAndroid Build Coastguard Worker return BodySamples[LineLocation(LineOffset, Discriminator)].addSamples(
203*9880d681SAndroid Build Coastguard Worker Num, Weight);
204*9880d681SAndroid Build Coastguard Worker }
205*9880d681SAndroid Build Coastguard Worker sampleprof_error addCalledTargetSamples(uint32_t LineOffset,
206*9880d681SAndroid Build Coastguard Worker uint32_t Discriminator,
207*9880d681SAndroid Build Coastguard Worker const std::string &FName,
208*9880d681SAndroid Build Coastguard Worker uint64_t Num, uint64_t Weight = 1) {
209*9880d681SAndroid Build Coastguard Worker return BodySamples[LineLocation(LineOffset, Discriminator)].addCalledTarget(
210*9880d681SAndroid Build Coastguard Worker FName, Num, Weight);
211*9880d681SAndroid Build Coastguard Worker }
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard Worker /// Return the number of samples collected at the given location.
214*9880d681SAndroid Build Coastguard Worker /// Each location is specified by \p LineOffset and \p Discriminator.
215*9880d681SAndroid Build Coastguard Worker /// If the location is not found in profile, return error.
216*9880d681SAndroid Build Coastguard Worker ErrorOr<uint64_t> findSamplesAt(uint32_t LineOffset,
217*9880d681SAndroid Build Coastguard Worker uint32_t Discriminator) const {
218*9880d681SAndroid Build Coastguard Worker const auto &ret = BodySamples.find(LineLocation(LineOffset, Discriminator));
219*9880d681SAndroid Build Coastguard Worker if (ret == BodySamples.end())
220*9880d681SAndroid Build Coastguard Worker return std::error_code();
221*9880d681SAndroid Build Coastguard Worker else
222*9880d681SAndroid Build Coastguard Worker return ret->second.getSamples();
223*9880d681SAndroid Build Coastguard Worker }
224*9880d681SAndroid Build Coastguard Worker
225*9880d681SAndroid Build Coastguard Worker /// Return the function samples at the given callsite location.
226*9880d681SAndroid Build Coastguard Worker FunctionSamples &functionSamplesAt(const LineLocation &Loc) {
227*9880d681SAndroid Build Coastguard Worker return CallsiteSamples[Loc];
228*9880d681SAndroid Build Coastguard Worker }
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Worker /// Return a pointer to function samples at the given callsite location.
231*9880d681SAndroid Build Coastguard Worker const FunctionSamples *findFunctionSamplesAt(const LineLocation &Loc) const {
232*9880d681SAndroid Build Coastguard Worker auto iter = CallsiteSamples.find(Loc);
233*9880d681SAndroid Build Coastguard Worker if (iter == CallsiteSamples.end()) {
234*9880d681SAndroid Build Coastguard Worker return nullptr;
235*9880d681SAndroid Build Coastguard Worker } else {
236*9880d681SAndroid Build Coastguard Worker return &iter->second;
237*9880d681SAndroid Build Coastguard Worker }
238*9880d681SAndroid Build Coastguard Worker }
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker bool empty() const { return TotalSamples == 0; }
241*9880d681SAndroid Build Coastguard Worker
242*9880d681SAndroid Build Coastguard Worker /// Return the total number of samples collected inside the function.
243*9880d681SAndroid Build Coastguard Worker uint64_t getTotalSamples() const { return TotalSamples; }
244*9880d681SAndroid Build Coastguard Worker
245*9880d681SAndroid Build Coastguard Worker /// Return the total number of samples collected at the head of the
246*9880d681SAndroid Build Coastguard Worker /// function.
247*9880d681SAndroid Build Coastguard Worker uint64_t getHeadSamples() const { return TotalHeadSamples; }
248*9880d681SAndroid Build Coastguard Worker
249*9880d681SAndroid Build Coastguard Worker /// Return all the samples collected in the body of the function.
250*9880d681SAndroid Build Coastguard Worker const BodySampleMap &getBodySamples() const { return BodySamples; }
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker /// Return all the callsite samples collected in the body of the function.
253*9880d681SAndroid Build Coastguard Worker const CallsiteSampleMap &getCallsiteSamples() const {
254*9880d681SAndroid Build Coastguard Worker return CallsiteSamples;
255*9880d681SAndroid Build Coastguard Worker }
256*9880d681SAndroid Build Coastguard Worker
257*9880d681SAndroid Build Coastguard Worker /// Merge the samples in \p Other into this one.
258*9880d681SAndroid Build Coastguard Worker /// Optionally scale samples by \p Weight.
259*9880d681SAndroid Build Coastguard Worker sampleprof_error merge(const FunctionSamples &Other, uint64_t Weight = 1) {
260*9880d681SAndroid Build Coastguard Worker sampleprof_error Result = sampleprof_error::success;
261*9880d681SAndroid Build Coastguard Worker Name = Other.getName();
262*9880d681SAndroid Build Coastguard Worker MergeResult(Result, addTotalSamples(Other.getTotalSamples(), Weight));
263*9880d681SAndroid Build Coastguard Worker MergeResult(Result, addHeadSamples(Other.getHeadSamples(), Weight));
264*9880d681SAndroid Build Coastguard Worker for (const auto &I : Other.getBodySamples()) {
265*9880d681SAndroid Build Coastguard Worker const LineLocation &Loc = I.first;
266*9880d681SAndroid Build Coastguard Worker const SampleRecord &Rec = I.second;
267*9880d681SAndroid Build Coastguard Worker MergeResult(Result, BodySamples[Loc].merge(Rec, Weight));
268*9880d681SAndroid Build Coastguard Worker }
269*9880d681SAndroid Build Coastguard Worker for (const auto &I : Other.getCallsiteSamples()) {
270*9880d681SAndroid Build Coastguard Worker const LineLocation &Loc = I.first;
271*9880d681SAndroid Build Coastguard Worker const FunctionSamples &Rec = I.second;
272*9880d681SAndroid Build Coastguard Worker MergeResult(Result, functionSamplesAt(Loc).merge(Rec, Weight));
273*9880d681SAndroid Build Coastguard Worker }
274*9880d681SAndroid Build Coastguard Worker return Result;
275*9880d681SAndroid Build Coastguard Worker }
276*9880d681SAndroid Build Coastguard Worker
277*9880d681SAndroid Build Coastguard Worker /// Set the name of the function.
278*9880d681SAndroid Build Coastguard Worker void setName(StringRef FunctionName) { Name = FunctionName; }
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker /// Return the function name.
281*9880d681SAndroid Build Coastguard Worker const StringRef &getName() const { return Name; }
282*9880d681SAndroid Build Coastguard Worker
283*9880d681SAndroid Build Coastguard Worker private:
284*9880d681SAndroid Build Coastguard Worker /// Mangled name of the function.
285*9880d681SAndroid Build Coastguard Worker StringRef Name;
286*9880d681SAndroid Build Coastguard Worker
287*9880d681SAndroid Build Coastguard Worker /// Total number of samples collected inside this function.
288*9880d681SAndroid Build Coastguard Worker ///
289*9880d681SAndroid Build Coastguard Worker /// Samples are cumulative, they include all the samples collected
290*9880d681SAndroid Build Coastguard Worker /// inside this function and all its inlined callees.
291*9880d681SAndroid Build Coastguard Worker uint64_t TotalSamples;
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker /// Total number of samples collected at the head of the function.
294*9880d681SAndroid Build Coastguard Worker /// This is an approximation of the number of calls made to this function
295*9880d681SAndroid Build Coastguard Worker /// at runtime.
296*9880d681SAndroid Build Coastguard Worker uint64_t TotalHeadSamples;
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker /// Map instruction locations to collected samples.
299*9880d681SAndroid Build Coastguard Worker ///
300*9880d681SAndroid Build Coastguard Worker /// Each entry in this map contains the number of samples
301*9880d681SAndroid Build Coastguard Worker /// collected at the corresponding line offset. All line locations
302*9880d681SAndroid Build Coastguard Worker /// are an offset from the start of the function.
303*9880d681SAndroid Build Coastguard Worker BodySampleMap BodySamples;
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Worker /// Map call sites to collected samples for the called function.
306*9880d681SAndroid Build Coastguard Worker ///
307*9880d681SAndroid Build Coastguard Worker /// Each entry in this map corresponds to all the samples
308*9880d681SAndroid Build Coastguard Worker /// collected for the inlined function call at the given
309*9880d681SAndroid Build Coastguard Worker /// location. For example, given:
310*9880d681SAndroid Build Coastguard Worker ///
311*9880d681SAndroid Build Coastguard Worker /// void foo() {
312*9880d681SAndroid Build Coastguard Worker /// 1 bar();
313*9880d681SAndroid Build Coastguard Worker /// ...
314*9880d681SAndroid Build Coastguard Worker /// 8 baz();
315*9880d681SAndroid Build Coastguard Worker /// }
316*9880d681SAndroid Build Coastguard Worker ///
317*9880d681SAndroid Build Coastguard Worker /// If the bar() and baz() calls were inlined inside foo(), this
318*9880d681SAndroid Build Coastguard Worker /// map will contain two entries. One for all the samples collected
319*9880d681SAndroid Build Coastguard Worker /// in the call to bar() at line offset 1, the other for all the samples
320*9880d681SAndroid Build Coastguard Worker /// collected in the call to baz() at line offset 8.
321*9880d681SAndroid Build Coastguard Worker CallsiteSampleMap CallsiteSamples;
322*9880d681SAndroid Build Coastguard Worker };
323*9880d681SAndroid Build Coastguard Worker
324*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<<(raw_ostream &OS, const FunctionSamples &FS);
325*9880d681SAndroid Build Coastguard Worker
326*9880d681SAndroid Build Coastguard Worker /// Sort a LocationT->SampleT map by LocationT.
327*9880d681SAndroid Build Coastguard Worker ///
328*9880d681SAndroid Build Coastguard Worker /// It produces a sorted list of <LocationT, SampleT> records by ascending
329*9880d681SAndroid Build Coastguard Worker /// order of LocationT.
330*9880d681SAndroid Build Coastguard Worker template <class LocationT, class SampleT> class SampleSorter {
331*9880d681SAndroid Build Coastguard Worker public:
332*9880d681SAndroid Build Coastguard Worker typedef std::pair<const LocationT, SampleT> SamplesWithLoc;
333*9880d681SAndroid Build Coastguard Worker typedef SmallVector<const SamplesWithLoc *, 20> SamplesWithLocList;
334*9880d681SAndroid Build Coastguard Worker
335*9880d681SAndroid Build Coastguard Worker SampleSorter(const std::map<LocationT, SampleT> &Samples) {
336*9880d681SAndroid Build Coastguard Worker for (const auto &I : Samples)
337*9880d681SAndroid Build Coastguard Worker V.push_back(&I);
338*9880d681SAndroid Build Coastguard Worker std::stable_sort(V.begin(), V.end(),
339*9880d681SAndroid Build Coastguard Worker [](const SamplesWithLoc *A, const SamplesWithLoc *B) {
340*9880d681SAndroid Build Coastguard Worker return A->first < B->first;
341*9880d681SAndroid Build Coastguard Worker });
342*9880d681SAndroid Build Coastguard Worker }
343*9880d681SAndroid Build Coastguard Worker const SamplesWithLocList &get() const { return V; }
344*9880d681SAndroid Build Coastguard Worker
345*9880d681SAndroid Build Coastguard Worker private:
346*9880d681SAndroid Build Coastguard Worker SamplesWithLocList V;
347*9880d681SAndroid Build Coastguard Worker };
348*9880d681SAndroid Build Coastguard Worker
349*9880d681SAndroid Build Coastguard Worker } // end namespace sampleprof
350*9880d681SAndroid Build Coastguard Worker
351*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
352*9880d681SAndroid Build Coastguard Worker
353*9880d681SAndroid Build Coastguard Worker #endif // LLVM_PROFILEDATA_SAMPLEPROF_H_
354