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"
22 #include <string>
23 #include <system_error>
24 
25 using namespace llvm;
26 using namespace sampleprof;
27 
28 namespace llvm {
29 namespace sampleprof {
31 } // namespace sampleprof
32 } // namespace llvm
33 
34 namespace {
35 
36 // FIXME: This class is only here to support the transition to llvm::Error. It
37 // will be removed once this transition is complete. Clients should prefer to
38 // deal with the Error value directly, rather than converting to error_code.
39 class SampleProfErrorCategoryType : public std::error_category {
40  const char *name() const noexcept override { return "llvm.sampleprof"; }
41 
42  std::string message(int IE) const override {
43  sampleprof_error E = static_cast<sampleprof_error>(IE);
44  switch (E) {
46  return "Success";
48  return "Invalid sample profile data (bad magic)";
50  return "Unsupported sample profile format version";
52  return "Too much profile data";
54  return "Truncated profile data";
56  return "Malformed sample profile data";
58  return "Unrecognized sample profile encoding format";
60  return "Profile encoding format unsupported for writing operations";
62  return "Truncated function name table";
64  return "Unimplemented feature";
66  return "Counter overflow";
68  return "Ostream does not support seek";
69  }
70  llvm_unreachable("A value of sampleprof_error has no message.");
71  }
72 };
73 
74 } // end anonymous namespace
75 
77 
79  return *ErrorCategory;
80 }
81 
83  OS << LineOffset;
84  if (Discriminator > 0)
85  OS << "." << Discriminator;
86 }
87 
89  const LineLocation &Loc) {
90  Loc.print(OS);
91  return OS;
92 }
93 
94 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
96 #endif
97 
98 /// Print the sample record to the stream \p OS indented by \p Indent.
99 void SampleRecord::print(raw_ostream &OS, unsigned Indent) const {
100  OS << NumSamples;
101  if (hasCalls()) {
102  OS << ", calls:";
103  for (const auto &I : getCallTargets())
104  OS << " " << I.first() << ":" << I.second;
105  }
106  OS << "\n";
107 }
108 
109 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
111 #endif
112 
114  const SampleRecord &Sample) {
115  Sample.print(OS, 0);
116  return OS;
117 }
118 
119 /// Print the samples collected for a function on stream \p OS.
120 void FunctionSamples::print(raw_ostream &OS, unsigned Indent) const {
121  OS << TotalSamples << ", " << TotalHeadSamples << ", " << BodySamples.size()
122  << " sampled lines\n";
123 
124  OS.indent(Indent);
125  if (!BodySamples.empty()) {
126  OS << "Samples collected in the function's body {\n";
127  SampleSorter<LineLocation, SampleRecord> SortedBodySamples(BodySamples);
128  for (const auto &SI : SortedBodySamples.get()) {
129  OS.indent(Indent + 2);
130  OS << SI->first << ": " << SI->second;
131  }
132  OS.indent(Indent);
133  OS << "}\n";
134  } else {
135  OS << "No samples collected in the function's body\n";
136  }
137 
138  OS.indent(Indent);
139  if (!CallsiteSamples.empty()) {
140  OS << "Samples collected in inlined callsites {\n";
142  CallsiteSamples);
143  for (const auto &CS : SortedCallsiteSamples.get()) {
144  for (const auto &FS : CS->second) {
145  OS.indent(Indent + 2);
146  OS << CS->first << ": inlined callee: " << FS.second.getName() << ": ";
147  FS.second.print(OS, Indent + 4);
148  }
149  }
150  OS << "}\n";
151  } else {
152  OS << "No inlined callsites in this function\n";
153  }
154 }
155 
157  const FunctionSamples &FS) {
158  FS.print(OS);
159  return OS;
160 }
161 
163  return (DIL->getLine() - DIL->getScope()->getSubprogram()->getLine()) &
164  0xffff;
165 }
166 
167 const FunctionSamples *
169  assert(DIL);
171 
172  const DILocation *PrevDIL = DIL;
173  for (DIL = DIL->getInlinedAt(); DIL; DIL = DIL->getInlinedAt()) {
174  S.push_back(std::make_pair(
176  PrevDIL->getScope()->getSubprogram()->getLinkageName()));
177  PrevDIL = DIL;
178  }
179  if (S.size() == 0)
180  return this;
181  const FunctionSamples *FS = this;
182  for (int i = S.size() - 1; i >= 0 && FS != nullptr; i--) {
183  FS = FS->findFunctionSamplesAt(S[i].first, S[i].second);
184  }
185  return FS;
186 }
187 
188 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
190 #endif
raw_ostream & operator<<(raw_ostream &OS, const LineLocation &Loc)
Definition: SampleProf.cpp:88
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:473
raw_ostream & indent(unsigned NumSpaces)
indent - Insert &#39;NumSpaces&#39; spaces.
unsigned second
static SampleProfileFormat Format
Definition: SampleProf.h:473
Representation of the samples collected for a function.
Definition: SampleProf.h:216
void print(raw_ostream &OS=dbgs(), unsigned Indent=0) const
Print the samples collected for a function on stream OS.
Definition: SampleProf.cpp:120
void print(raw_ostream &OS, unsigned Indent) const
Print the sample record to the stream OS indented by Indent.
Definition: SampleProf.cpp:99
Representation of a single sample record.
Definition: SampleProf.h:144
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
const SamplesWithLocList & get() const
Definition: SampleProf.h:547
Debug location.
Sort a LocationT->SampleT map by LocationT.
Definition: SampleProf.h:534
const FunctionSamples * findFunctionSamples(const DILocation *DIL) const
Get the FunctionSamples of the inline instance where DIL originates from.
Definition: SampleProf.cpp:168
sampleprof_error
Definition: SampleProf.h:40
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
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:294
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:162
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:78
void print(raw_ostream &OS) const
Definition: SampleProf.cpp:82
static ManagedStatic< SampleProfErrorCategoryType > ErrorCategory
Definition: SampleProf.cpp:76
unsigned getBaseDiscriminator() const
Returns the base discriminator stored in the discriminator.
Represents the relative location of an instruction.
Definition: SampleProf.h:117
#define I(x, y, z)
Definition: MD5.cpp:58
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
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
Definition: ManagedStatic.h:83