1 //=-- InstrProfReader.h - Instrumented profiling readers ----------*- C++ -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains support for reading profiling data for instrumentation
11 // based PGO and coverage.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_PROFILEDATA_INSTRPROF_READER_H_
16 #define LLVM_PROFILEDATA_INSTRPROF_READER_H_
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ProfileData/InstrProf.h"
20 #include "llvm/Support/LineIterator.h"
21 #include "llvm/Support/MemoryBuffer.h"
22 #include "llvm/Support/Endian.h"
28 class InstrProfReader;
30 /// Profiling information for a single function.
31 struct InstrProfRecord {
34 ArrayRef<uint64_t> Counts;
37 /// A file format agnostic iterator over profiling data.
38 class InstrProfIterator : public std::iterator<std::input_iterator_tag,
40 InstrProfReader *Reader;
41 InstrProfRecord Record;
45 InstrProfIterator() : Reader(nullptr) {}
46 InstrProfIterator(InstrProfReader *Reader) : Reader(Reader) { Increment(); }
48 InstrProfIterator &operator++() { Increment(); return *this; }
49 bool operator==(const InstrProfIterator &RHS) { return Reader == RHS.Reader; }
50 bool operator!=(const InstrProfIterator &RHS) { return Reader != RHS.Reader; }
51 InstrProfRecord &operator*() { return Record; }
52 InstrProfRecord *operator->() { return &Record; }
55 /// Base class and interface for reading profiling data of any known instrprof
56 /// format. Provides an iterator over InstrProfRecords.
57 class InstrProfReader {
60 InstrProfReader() : LastError(instrprof_error::success) {}
61 virtual ~InstrProfReader() {}
63 /// Read the header. Required before reading first record.
64 virtual error_code readHeader() = 0;
65 /// Read a single record.
66 virtual error_code readNextRecord(InstrProfRecord &Record) = 0;
67 /// Iterator over profile data.
68 InstrProfIterator begin() { return InstrProfIterator(this); }
69 InstrProfIterator end() { return InstrProfIterator(); }
72 /// Set the current error_code and return same.
73 error_code error(error_code EC) {
78 /// Clear the current error code and return a successful one.
79 error_code success() { return error(instrprof_error::success); }
82 /// Return true if the reader has finished reading the profile data.
83 bool isEOF() { return LastError == instrprof_error::eof; }
84 /// Return true if the reader encountered an error reading profiling data.
85 bool hasError() { return LastError && !isEOF(); }
86 /// Get the current error code.
87 error_code getError() { return LastError; }
89 /// Factory method to create an appropriately typed reader for the given
91 static error_code create(std::string Path,
92 std::unique_ptr<InstrProfReader> &Result);
95 /// Reader for the simple text based instrprof format.
97 /// This format is a simple text format that's suitable for test data. Records
98 /// are separated by one or more blank lines, and record fields are separated by
101 /// Each record consists of a function name, a function hash, a number of
102 /// counters, and then each counter value, in that order.
103 class TextInstrProfReader : public InstrProfReader {
105 /// The profile data file contents.
106 std::unique_ptr<MemoryBuffer> DataBuffer;
107 /// Iterator over the profile data.
109 /// The current set of counter values.
110 std::vector<uint64_t> Counts;
112 TextInstrProfReader(const TextInstrProfReader &) LLVM_DELETED_FUNCTION;
113 TextInstrProfReader &operator=(const TextInstrProfReader &)
114 LLVM_DELETED_FUNCTION;
116 TextInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer_)
117 : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, '#') {}
120 error_code readHeader() override { return success(); }
121 /// Read a single record.
122 error_code readNextRecord(InstrProfRecord &Record) override;
125 /// Reader for the raw instrprof binary format from runtime.
127 /// This format is a raw memory dump of the instrumentation-baed profiling data
128 /// from the runtime. It has no index.
129 class RawInstrProfReader : public InstrProfReader {
131 /// The profile data file contents.
132 std::unique_ptr<MemoryBuffer> DataBuffer;
133 /// The current set of counter values.
134 std::vector<uint64_t> Counts;
136 const uint32_t NameSize;
137 const uint32_t NumCounters;
138 const uint64_t FuncHash;
139 const uint64_t NamePtr;
140 const uint64_t CounterPtr;
143 const uint64_t Magic;
144 const uint64_t Version;
145 const uint64_t DataSize;
146 const uint64_t CountersSize;
147 const uint64_t NamesSize;
148 const uint64_t CountersDelta;
149 const uint64_t NamesDelta;
152 bool ShouldSwapBytes;
153 uint64_t CountersDelta;
155 const ProfileData *Data;
156 const ProfileData *DataEnd;
157 const uint64_t *CountersStart;
158 const char *NamesStart;
160 RawInstrProfReader(const TextInstrProfReader &) LLVM_DELETED_FUNCTION;
161 RawInstrProfReader &operator=(const TextInstrProfReader &)
162 LLVM_DELETED_FUNCTION;
164 RawInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer);
166 static bool hasFormat(const MemoryBuffer &DataBuffer);
167 error_code readHeader() override;
168 error_code readNextRecord(InstrProfRecord &Record) override;
171 error_code readHeader(const RawHeader &Header);
172 template <class IntT>
173 IntT swap(IntT Int) const {
174 return ShouldSwapBytes ? sys::SwapByteOrder(Int) : Int;
176 const uint64_t *getCounter(uint64_t CounterPtr) const {
177 ptrdiff_t Offset = (swap(CounterPtr) - CountersDelta) / sizeof(uint64_t);
178 return CountersStart + Offset;
180 const char *getName(uint64_t NamePtr) const {
181 ptrdiff_t Offset = (swap(NamePtr) - NamesDelta) / sizeof(char);
182 return NamesStart + Offset;
186 } // end namespace llvm
188 #endif // LLVM_PROFILEDATA_INSTRPROF_READER_H_