LLVM  10.0.0svn
SampleProf.cpp
Go to the documentation of this file.
1 //=-- SampleProf.cpp - Sample profiling format support --------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains common definitions used in the reading and writing of
10 // sample profile data.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/Config/llvm-config.h"
17 #include "llvm/Support/Compiler.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/Error.h"
21 #include "llvm/Support/LEB128.h"
24 #include <string>
25 #include <system_error>
26 
27 using namespace llvm;
28 using namespace sampleprof;
29 
30 namespace llvm {
31 namespace sampleprof {
33 } // namespace sampleprof
34 } // namespace llvm
35 
36 namespace {
37 
38 // FIXME: This class is only here to support the transition to llvm::Error. It
39 // will be removed once this transition is complete. Clients should prefer to
40 // deal with the Error value directly, rather than converting to error_code.
41 class SampleProfErrorCategoryType : public std::error_category {
42  const char *name() const noexcept override { return "llvm.sampleprof"; }
43 
44  std::string message(int IE) const override {
45  sampleprof_error E = static_cast<sampleprof_error>(IE);
46  switch (E) {
48  return "Success";
50  return "Invalid sample profile data (bad magic)";
52  return "Unsupported sample profile format version";
54  return "Too much profile data";
56  return "Truncated profile data";
58  return "Malformed sample profile data";
60  return "Unrecognized sample profile encoding format";
62  return "Profile encoding format unsupported for writing operations";
64  return "Truncated function name table";
66  return "Unimplemented feature";
68  return "Counter overflow";
70  return "Ostream does not support seek";
72  return "Compress failure";
74  return "Uncompress failure";
76  return "Zlib is unavailable";
77  }
78  llvm_unreachable("A value of sampleprof_error has no message.");
79  }
80 };
81 
82 } // end anonymous namespace
83 
85 
87  return *ErrorCategory;
88 }
89 
91  OS << LineOffset;
92  if (Discriminator > 0)
93  OS << "." << Discriminator;
94 }
95 
97  const LineLocation &Loc) {
98  Loc.print(OS);
99  return OS;
100 }
101 
102 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
104 #endif
105 
106 /// Print the sample record to the stream \p OS indented by \p Indent.
107 void SampleRecord::print(raw_ostream &OS, unsigned Indent) const {
108  OS << NumSamples;
109  if (hasCalls()) {
110  OS << ", calls:";
111  for (const auto &I : getSortedCallTargets())
112  OS << " " << I.first << ":" << I.second;
113  }
114  OS << "\n";
115 }
116 
117 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
119 #endif
120 
122  const SampleRecord &Sample) {
123  Sample.print(OS, 0);
124  return OS;
125 }
126 
127 /// Print the samples collected for a function on stream \p OS.
128 void FunctionSamples::print(raw_ostream &OS, unsigned Indent) const {
129  OS << TotalSamples << ", " << TotalHeadSamples << ", " << BodySamples.size()
130  << " sampled lines\n";
131 
132  OS.indent(Indent);
133  if (!BodySamples.empty()) {
134  OS << "Samples collected in the function's body {\n";
135  SampleSorter<LineLocation, SampleRecord> SortedBodySamples(BodySamples);
136  for (const auto &SI : SortedBodySamples.get()) {
137  OS.indent(Indent + 2);
138  OS << SI->first << ": " << SI->second;
139  }
140  OS.indent(Indent);
141  OS << "}\n";
142  } else {
143  OS << "No samples collected in the function's body\n";
144  }
145 
146  OS.indent(Indent);
147  if (!CallsiteSamples.empty()) {
148  OS << "Samples collected in inlined callsites {\n";
150  CallsiteSamples);
151  for (const auto &CS : SortedCallsiteSamples.get()) {
152  for (const auto &FS : CS->second) {
153  OS.indent(Indent + 2);
154  OS << CS->first << ": inlined callee: " << FS.second.getName() << ": ";
155  FS.second.print(OS, Indent + 4);
156  }
157  }
158  OS.indent(Indent);
159  OS << "}\n";
160  } else {
161  OS << "No inlined callsites in this function\n";
162  }
163 }
164 
166  const FunctionSamples &FS) {
167  FS.print(OS);
168  return OS;
169 }
170 
172  return (DIL->getLine() - DIL->getScope()->getSubprogram()->getLine()) &
173  0xffff;
174 }
175 
176 const FunctionSamples *
178  assert(DIL);
180 
181  const DILocation *PrevDIL = DIL;
182  for (DIL = DIL->getInlinedAt(); DIL; DIL = DIL->getInlinedAt()) {
183  S.push_back(std::make_pair(
185  PrevDIL->getScope()->getSubprogram()->getLinkageName()));
186  PrevDIL = DIL;
187  }
188  if (S.size() == 0)
189  return this;
190  const FunctionSamples *FS = this;
191  for (int i = S.size() - 1; i >= 0 && FS != nullptr; i--) {
192  FS = FS->findFunctionSamplesAt(S[i].first, S[i].second);
193  }
194  return FS;
195 }
196 
197 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
199 #endif
200 
201 std::error_code ProfileSymbolList::read(const uint8_t *Data,
202  uint64_t ListSize) {
203  const char *ListStart = reinterpret_cast<const char *>(Data);
204  uint64_t Size = 0;
205  while (Size < ListSize) {
206  StringRef Str(ListStart + Size);
207  add(Str);
208  Size += Str.size() + 1;
209  }
210  if (Size != ListSize)
213 }
214 
215 std::error_code ProfileSymbolList::write(raw_ostream &OS) {
216  // Sort the symbols before output. If doing compression.
217  // It will make the compression much more effective.
218  std::vector<StringRef> SortedList;
219  SortedList.insert(SortedList.begin(), Syms.begin(), Syms.end());
220  llvm::sort(SortedList);
221 
222  std::string OutputString;
223  for (auto &Sym : SortedList) {
224  OutputString.append(Sym.str());
225  OutputString.append(1, '\0');
226  }
227 
228  OS << OutputString;
230 }
231 
233  OS << "======== Dump profile symbol list ========\n";
234  std::vector<StringRef> SortedList;
235  SortedList.insert(SortedList.begin(), Syms.begin(), Syms.end());
236  llvm::sort(SortedList);
237 
238  for (auto &Sym : SortedList)
239  OS << Sym << "\n";
240 }
raw_ostream & operator<<(raw_ostream &OS, const LineLocation &Loc)
Definition: SampleProf.cpp:96
This class represents lattice values for constants.
Definition: AllocatorList.h:23
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Definition: Compiler.h:484
raw_ostream & indent(unsigned NumSpaces)
indent - Insert &#39;NumSpaces&#39; spaces.
unsigned second
static SampleProfileFormat Format
Definition: SampleProf.h:557
Representation of the samples collected for a function.
Definition: SampleProf.h:300
void print(raw_ostream &OS=dbgs(), unsigned Indent=0) const
Print the samples collected for a function on stream OS.
Definition: SampleProf.cpp:128
void print(raw_ostream &OS, unsigned Indent) const
Print the sample record to the stream OS indented by Indent.
Definition: SampleProf.cpp:107
Representation of a single sample record.
Definition: SampleProf.h:206
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:144
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
const SamplesWithLocList & get() const
Definition: SampleProf.h:631
Debug location.
Sort a LocationT->SampleT map by LocationT.
Definition: SampleProf.h:618
void dump(raw_ostream &OS=dbgs()) const
Definition: SampleProf.cpp:232
const FunctionSamples * findFunctionSamples(const DILocation *DIL) const
Get the FunctionSamples of the inline instance where DIL originates from.
Definition: SampleProf.cpp:177
sampleprof_error
Definition: SampleProf.h:43
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static ManagedStatic< _object_error_category > error_category
Definition: Error.cpp:74
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
size_t size() const
Definition: SmallVector.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned first
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1095
const FunctionSamples * findFunctionSamplesAt(const LineLocation &Loc, StringRef CalleeName) const
Returns a pointer to FunctionSamples at the given callsite location Loc with callee CalleeName...
Definition: SampleProf.h:378
static uint64_t add(uint64_t LeftOp, uint64_t RightOp)
Definition: FileCheck.cpp:215
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
static unsigned getOffset(const DILocation *DIL)
Returns the line offset to the start line of the subprogram.
Definition: SampleProf.cpp:171
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
const std::error_category & sampleprof_category()
Definition: SampleProf.cpp:86
void print(raw_ostream &OS) const
Definition: SampleProf.cpp:90
static ManagedStatic< SampleProfErrorCategoryType > ErrorCategory
Definition: SampleProf.cpp:84
unsigned getBaseDiscriminator() const
Returns the base discriminator stored in the discriminator.
Represents the relative location of an instruction.
Definition: SampleProf.h:179
#define I(x, y, z)
Definition: MD5.cpp:58
std::error_code write(raw_ostream &OS)
Definition: SampleProf.cpp:215
uint32_t Size
Definition: Profile.cpp:46
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
aarch64 promote const
static const char * name
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
Definition: ManagedStatic.h:83
std::error_code read(const uint8_t *Data, uint64_t ListSize)
Definition: SampleProf.cpp:201