LLVM  3.7.0
InstrProfReader.h
Go to the documentation of this file.
1 //=-- InstrProfReader.h - Instrumented profiling readers ----------*- C++ -*-=//
2 //
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 //
10 // This file contains support for reading profiling data for instrumentation
11 // based PGO and coverage.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_PROFILEDATA_INSTRPROFREADER_H
16 #define LLVM_PROFILEDATA_INSTRPROFREADER_H
17 
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/Support/ErrorOr.h"
26 #include <iterator>
27 
28 namespace llvm {
29 
30 class InstrProfReader;
31 
32 /// A file format agnostic iterator over profiling data.
33 class InstrProfIterator : public std::iterator<std::input_iterator_tag,
34  InstrProfRecord> {
35  InstrProfReader *Reader;
37 
38  void Increment();
39 public:
40  InstrProfIterator() : Reader(nullptr) {}
41  InstrProfIterator(InstrProfReader *Reader) : Reader(Reader) { Increment(); }
42 
43  InstrProfIterator &operator++() { Increment(); return *this; }
44  bool operator==(const InstrProfIterator &RHS) { return Reader == RHS.Reader; }
45  bool operator!=(const InstrProfIterator &RHS) { return Reader != RHS.Reader; }
48 };
49 
50 /// Base class and interface for reading profiling data of any known instrprof
51 /// format. Provides an iterator over InstrProfRecords.
53  std::error_code LastError;
54 
55 public:
57  virtual ~InstrProfReader() {}
58 
59  /// Read the header. Required before reading first record.
60  virtual std::error_code readHeader() = 0;
61  /// Read a single record.
62  virtual std::error_code readNextRecord(InstrProfRecord &Record) = 0;
63  /// Iterator over profile data.
66 
67 protected:
68  /// Set the current std::error_code and return same.
69  std::error_code error(std::error_code EC) {
70  LastError = EC;
71  return EC;
72  }
73 
74  /// Clear the current error code and return a successful one.
75  std::error_code success() { return error(instrprof_error::success); }
76 
77 public:
78  /// Return true if the reader has finished reading the profile data.
79  bool isEOF() { return LastError == instrprof_error::eof; }
80  /// Return true if the reader encountered an error reading profiling data.
81  bool hasError() { return LastError && !isEOF(); }
82  /// Get the current error code.
83  std::error_code getError() { return LastError; }
84 
85  /// Factory method to create an appropriately typed reader for the given
86  /// instrprof file.
87  static ErrorOr<std::unique_ptr<InstrProfReader>> create(std::string Path);
88 
90  create(std::unique_ptr<MemoryBuffer> Buffer);
91 };
92 
93 /// Reader for the simple text based instrprof format.
94 ///
95 /// This format is a simple text format that's suitable for test data. Records
96 /// are separated by one or more blank lines, and record fields are separated by
97 /// new lines.
98 ///
99 /// Each record consists of a function name, a function hash, a number of
100 /// counters, and then each counter value, in that order.
102 private:
103  /// The profile data file contents.
104  std::unique_ptr<MemoryBuffer> DataBuffer;
105  /// Iterator over the profile data.
106  line_iterator Line;
107 
108  TextInstrProfReader(const TextInstrProfReader &) = delete;
109  TextInstrProfReader &operator=(const TextInstrProfReader &) = delete;
110 public:
111  TextInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer_)
112  : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#') {}
113 
114  /// Read the header.
115  std::error_code readHeader() override { return success(); }
116  /// Read a single record.
117  std::error_code readNextRecord(InstrProfRecord &Record) override;
118 };
119 
120 /// Reader for the raw instrprof binary format from runtime.
121 ///
122 /// This format is a raw memory dump of the instrumentation-baed profiling data
123 /// from the runtime. It has no index.
124 ///
125 /// Templated on the unsigned type whose size matches pointers on the platform
126 /// that wrote the profile.
127 template <class IntPtrT>
129 private:
130  /// The profile data file contents.
131  std::unique_ptr<MemoryBuffer> DataBuffer;
132  struct ProfileData {
133  const uint32_t NameSize;
134  const uint32_t NumCounters;
135  const uint64_t FuncHash;
136  const IntPtrT NamePtr;
137  const IntPtrT CounterPtr;
138  };
139  struct RawHeader {
140  const uint64_t Magic;
141  const uint64_t Version;
142  const uint64_t DataSize;
143  const uint64_t CountersSize;
144  const uint64_t NamesSize;
145  const uint64_t CountersDelta;
146  const uint64_t NamesDelta;
147  };
148 
149  bool ShouldSwapBytes;
150  uint64_t CountersDelta;
151  uint64_t NamesDelta;
152  const ProfileData *Data;
153  const ProfileData *DataEnd;
154  const uint64_t *CountersStart;
155  const char *NamesStart;
156  const char *ProfileEnd;
157 
158  RawInstrProfReader(const RawInstrProfReader &) = delete;
159  RawInstrProfReader &operator=(const RawInstrProfReader &) = delete;
160 public:
161  RawInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer)
162  : DataBuffer(std::move(DataBuffer)) { }
163 
164  static bool hasFormat(const MemoryBuffer &DataBuffer);
165  std::error_code readHeader() override;
166  std::error_code readNextRecord(InstrProfRecord &Record) override;
167 
168 private:
169  std::error_code readNextHeader(const char *CurrentPos);
170  std::error_code readHeader(const RawHeader &Header);
171  template <class IntT>
172  IntT swap(IntT Int) const {
173  return ShouldSwapBytes ? sys::getSwappedBytes(Int) : Int;
174  }
175  const uint64_t *getCounter(IntPtrT CounterPtr) const {
176  ptrdiff_t Offset = (swap(CounterPtr) - CountersDelta) / sizeof(uint64_t);
177  return CountersStart + Offset;
178  }
179  const char *getName(IntPtrT NamePtr) const {
180  ptrdiff_t Offset = (swap(NamePtr) - NamesDelta) / sizeof(char);
181  return NamesStart + Offset;
182  }
183 };
184 
187 
188 namespace IndexedInstrProf {
189 enum class HashT : uint32_t;
190 }
191 
192 /// Trait for lookups into the on-disk hash table for the binary instrprof
193 /// format.
195  std::vector<InstrProfRecord> DataBuffer;
197  unsigned FormatVersion;
198 
199 public:
201  : HashType(HashType), FormatVersion(FormatVersion) {}
202 
204 
207  typedef uint64_t hash_value_type;
208  typedef uint64_t offset_type;
209 
210  static bool EqualKey(StringRef A, StringRef B) { return A == B; }
211  static StringRef GetInternalKey(StringRef K) { return K; }
212 
213  hash_value_type ComputeHash(StringRef K);
214 
215  static std::pair<offset_type, offset_type>
216  ReadKeyDataLength(const unsigned char *&D) {
217  using namespace support;
218  offset_type KeyLen = endian::readNext<offset_type, little, unaligned>(D);
219  offset_type DataLen = endian::readNext<offset_type, little, unaligned>(D);
220  return std::make_pair(KeyLen, DataLen);
221  }
222 
223  StringRef ReadKey(const unsigned char *D, offset_type N) {
224  return StringRef((const char *)D, N);
225  }
226 
227  data_type ReadData(StringRef K, const unsigned char *D, offset_type N);
228 };
229 
230 typedef OnDiskIterableChainedHashTable<InstrProfLookupTrait>
232 
233 /// Reader for the indexed binary instrprof format.
235 private:
236  /// The profile data file contents.
237  std::unique_ptr<MemoryBuffer> DataBuffer;
238  /// The index into the profile data.
239  std::unique_ptr<InstrProfReaderIndex> Index;
240  /// Iterator over the profile data.
242  /// The file format version of the profile data.
243  uint64_t FormatVersion;
244  /// The maximal execution count among all functions.
245  uint64_t MaxFunctionCount;
246 
248  IndexedInstrProfReader &operator=(const IndexedInstrProfReader &) = delete;
249 public:
250  IndexedInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer)
251  : DataBuffer(std::move(DataBuffer)), Index(nullptr) {}
252 
253  /// Return true if the given buffer is in an indexed instrprof format.
254  static bool hasFormat(const MemoryBuffer &DataBuffer);
255 
256  /// Read the file header.
257  std::error_code readHeader() override;
258  /// Read a single record.
259  std::error_code readNextRecord(InstrProfRecord &Record) override;
260 
261  /// Fill Counts with the profile data for the given function name.
262  std::error_code getFunctionCounts(StringRef FuncName, uint64_t FuncHash,
263  std::vector<uint64_t> &Counts);
264  /// Return the maximum of all known function counts.
265  uint64_t getMaximumFunctionCount() { return MaxFunctionCount; }
266 
267  /// Factory method to create an indexed reader.
269  create(std::string Path);
270 
272  create(std::unique_ptr<MemoryBuffer> Buffer);
273 };
274 
275 } // end namespace llvm
276 
277 #endif
std::error_code readNextRecord(InstrProfRecord &Record) override
Read a single record.
Represents either an error or a value T.
Definition: ErrorOr.h:82
std::error_code readHeader() override
Read the header.
virtual std::error_code readHeader()=0
Read the header. Required before reading first record.
Defines facilities for reading and writing on-disk hash tables.
uint64_t getMaximumFunctionCount()
Return the maximum of all known function counts.
A forward iterator which reads text lines from a buffer.
Definition: LineIterator.h:32
std::error_code success()
Clear the current error code and return a successful one.
InstrProfIterator(InstrProfReader *Reader)
bool operator==(const InstrProfIterator &RHS)
std::error_code readNextRecord(InstrProfRecord &Record) override
Read a single record.
bool operator!=(const InstrProfIterator &RHS)
bool isEOF()
Return true if the reader has finished reading the profile data.
std::error_code error(std::error_code EC)
Set the current std::error_code and return same.
InstrProfLookupTrait::data_type data_type
RawInstrProfReader< uint32_t > RawInstrProfReader32
InstrProfLookupTrait::offset_type offset_type
Iterates over all the entries in the table, returning the data.
RawInstrProfReader(std::unique_ptr< MemoryBuffer > DataBuffer)
static cl::opt< std::string > FuncName("cppfname", cl::desc("Specify the name of the generated function"), cl::value_desc("function name"))
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: ArrayRef.h:31
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
Reader for the simple text based instrprof format.
static bool hasFormat(const MemoryBuffer &DataBuffer)
StringRef ReadKey(const unsigned char *D, offset_type N)
#define true
Definition: ConvertUTF.c:66
Base class and interface for reading profiling data of any known instrprof format.
InstrProfIterator end()
OnDiskIterableChainedHashTable< InstrProfLookupTrait > InstrProfReaderIndex
static const char *const Magic
Definition: Archive.cpp:26
InstrProfRecord * operator->()
Trait for lookups into the on-disk hash table for the binary instrprof format.
A file format agnostic iterator over profiling data.
Reader for the raw instrprof binary format from runtime.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:37
static ErrorOr< std::unique_ptr< InstrProfReader > > create(std::string Path)
Factory method to create an appropriately typed reader for the given instrprof file.
std::error_code readHeader() override
Read the header. Required before reading first record.
unsigned char getSwappedBytes(unsigned char C)
Definition: SwapByteOrder.h:70
RawInstrProfReader< uint64_t > RawInstrProfReader64
TextInstrProfReader(std::unique_ptr< MemoryBuffer > DataBuffer_)
virtual std::error_code readNextRecord(InstrProfRecord &Record)=0
Read a single record.
std::error_code getError()
Get the current error code.
Profiling information for a single function.
Definition: InstrProf.h:48
instrprof_error
Definition: InstrProf.h:27
ArrayRef< InstrProfRecord > data_type
#define N
static uint64_t ComputeHash(HashT Type, StringRef K)
InstrProfIterator begin()
Iterator over profile data.
Provides ErrorOr<T> smart pointer.
InstrProfIterator & operator++()
bool hasError()
Return true if the reader encountered an error reading profiling data.
static StringRef GetInternalKey(StringRef K)
InstrProfLookupTrait(IndexedInstrProf::HashT HashType, unsigned FormatVersion)
static bool EqualKey(StringRef A, StringRef B)
IndexedInstrProfReader(std::unique_ptr< MemoryBuffer > DataBuffer)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
Reader for the indexed binary instrprof format.
InstrProfRecord & operator*()