xref: /aosp_15_r20/external/llvm/include/llvm/ProfileData/SampleProf.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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