26 if (std::error_code EC = BufferOrErr.
getError())
28 return std::move(BufferOrErr.
get());
39 if (std::error_code EC = BufferOrError.getError())
47 if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max())
50 std::unique_ptr<InstrProfReader> Result;
65 return std::move(Result);
72 if (std::error_code EC = BufferOrError.getError())
81 if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max())
87 auto Result = llvm::make_unique<IndexedInstrProfReader>(std::move(Buffer));
93 return std::move(Result);
96 void InstrProfIterator::Increment() {
110 Record.
Name = *Line++;
115 if ((Line++)->getAsInteger(0, Record.
Hash))
119 uint64_t NumCounters;
122 if ((Line++)->getAsInteger(10, NumCounters))
124 if (NumCounters == 0)
129 Record.
Counts.reserve(NumCounters);
130 for (uint64_t
I = 0;
I < NumCounters; ++
I) {
134 if ((Line++)->getAsInteger(10, Count))
136 Record.
Counts.push_back(Count);
142 template <
class IntPtrT>
148 uint64_t(255) << 56 |
149 uint64_t(
'l') << 48 |
150 uint64_t(
'p') << 40 |
151 uint64_t(
'r') << 32 |
152 uint64_t(
'o') << 24 |
153 uint64_t(
'f') << 16 |
161 uint64_t(255) << 56 |
162 uint64_t(
'l') << 48 |
163 uint64_t(
'p') << 40 |
164 uint64_t(
'r') << 32 |
165 uint64_t(
'o') << 24 |
166 uint64_t(
'f') << 16 |
171 template <
class IntPtrT>
177 return getRawMagic<IntPtrT>() == Magic ||
181 template <
class IntPtrT>
183 if (!hasFormat(*DataBuffer))
185 if (DataBuffer->getBufferSize() <
sizeof(RawHeader))
188 reinterpret_cast<const RawHeader *
>(DataBuffer->getBufferStart());
189 ShouldSwapBytes = Header->Magic != getRawMagic<IntPtrT>();
190 return readHeader(*Header);
193 template <
class IntPtrT>
196 const char *End = DataBuffer->getBufferEnd();
198 while (CurrentPos != End && *CurrentPos == 0)
201 if (CurrentPos == End)
205 if (CurrentPos +
sizeof(RawHeader) > End)
208 if (reinterpret_cast<size_t>(CurrentPos) % alignOf<uint64_t>())
211 uint64_t
Magic = *
reinterpret_cast<const uint64_t *
>(CurrentPos);
212 if (Magic !=
swap(getRawMagic<IntPtrT>()))
216 auto *Header =
reinterpret_cast<const RawHeader *
>(CurrentPos);
217 return readHeader(*Header);
224 template <
class IntPtrT>
230 CountersDelta =
swap(Header.CountersDelta);
231 NamesDelta =
swap(Header.NamesDelta);
232 auto DataSize =
swap(Header.DataSize);
233 auto CountersSize =
swap(Header.CountersSize);
234 auto NamesSize =
swap(Header.NamesSize);
236 ptrdiff_t DataOffset =
sizeof(RawHeader);
237 ptrdiff_t CountersOffset = DataOffset +
sizeof(ProfileData) * DataSize;
238 ptrdiff_t NamesOffset = CountersOffset +
sizeof(uint64_t) * CountersSize;
239 size_t ProfileSize = NamesOffset +
sizeof(char) * NamesSize;
241 auto *Start =
reinterpret_cast<const char *
>(&Header);
242 if (Start + ProfileSize > DataBuffer->getBufferEnd())
245 Data =
reinterpret_cast<const ProfileData *
>(Start + DataOffset);
246 DataEnd =
Data + DataSize;
247 CountersStart =
reinterpret_cast<const uint64_t *
>(Start + CountersOffset);
248 NamesStart = Start + NamesOffset;
249 ProfileEnd = Start + ProfileSize;
254 template <
class IntPtrT>
258 if (std::error_code EC = readNextHeader(ProfileEnd))
263 uint32_t NumCounters =
swap(
Data->NumCounters);
264 if (NumCounters == 0)
269 auto *NamesStartAsCounter =
reinterpret_cast<const uint64_t *
>(NamesStart);
270 if (RawName.
data() < NamesStart ||
271 RawName.
data() + RawName.
size() > DataBuffer->getBufferEnd() ||
272 RawCounts.data() < CountersStart ||
273 RawCounts.data() + RawCounts.size() > NamesStartAsCounter)
278 Record.
Name = RawName;
279 if (ShouldSwapBytes) {
281 Record.
Counts.reserve(RawCounts.size());
282 for (uint64_t Count : RawCounts)
285 Record.
Counts = RawCounts;
309 if (N %
sizeof(uint64_t))
314 uint64_t NumEntries = N /
sizeof(uint64_t);
315 std::vector<uint64_t> CounterBuffer;
316 for (uint64_t
I = 0;
I < NumEntries;
I += NumCounts) {
317 using namespace support;
319 uint64_t
Hash = endian::readNext<uint64_t, little, unaligned>(D);
321 if (++
I >= NumEntries)
326 NumCounts = (1 == FormatVersion)
328 : endian::readNext<uint64_t, little, unaligned>(D);
329 if (1 != FormatVersion)
333 if (
I + NumCounts > NumEntries)
336 CounterBuffer.clear();
337 for (
unsigned J = 0; J < NumCounts; ++J)
338 CounterBuffer.push_back(endian::readNext<uint64_t, little, unaligned>(D));
348 using namespace support;
350 endian::read<uint64_t, little, aligned>(DataBuffer.
getBufferStart());
355 const unsigned char *Start =
356 (
const unsigned char *)DataBuffer->getBufferStart();
357 const unsigned char *Cur = Start;
358 if ((
const unsigned char *)DataBuffer->getBufferEnd() - Cur < 24)
361 using namespace support;
364 uint64_t Magic = endian::readNext<uint64_t, little, unaligned>(Cur);
369 FormatVersion = endian::readNext<uint64_t, little, unaligned>(Cur);
374 MaxFunctionCount = endian::readNext<uint64_t, little, unaligned>(Cur);
378 endian::readNext<uint64_t, little, unaligned>(Cur));
381 uint64_t HashOffset = endian::readNext<uint64_t, little, unaligned>(Cur);
385 Start + HashOffset, Cur, Start,
388 RecordIterator = Index->data_begin();
395 auto Iter = Index->find(FuncName);
396 if (Iter == Index->end())
404 for (
unsigned I = 0, E = Data.
size();
I < E; ++
I) {
406 if (Data[
I].
Hash == FuncHash) {
407 Counts = Data[
I].Counts;
417 if (RecordIterator == Index->data_end())
420 if ((*RecordIterator).empty())
423 static unsigned RecordIndex = 0;
425 Record = Data[RecordIndex++];
426 if (RecordIndex >= Data.
size()) {
std::error_code readNextRecord(InstrProfRecord &Record) override
Read a single record.
std::error_code getError() const
Represents either an error or a value T.
size_t size() const
size - Get the string size.
const char * getBufferStart() const
virtual std::error_code readHeader()=0
Read the header. Required before reading first record.
static bool hasFormat(const MemoryBuffer &DataBuffer)
Return true if the given buffer is in an indexed instrprof format.
std::error_code success()
Clear the current error code and return a successful one.
std::error_code readNextRecord(InstrProfRecord &Record) override
Read a single record.
static std::error_code initializeReader(InstrProfReader &Reader)
data_type ReadData(StringRef K, const unsigned char *D, offset_type N)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
std::error_code error(std::error_code EC)
Set the current std::error_code and return same.
InstrProfLookupTrait::data_type data_type
static StringRef getName(Value *V)
RawInstrProfReader< uint32_t > RawInstrProfReader32
InstrProfLookupTrait::offset_type offset_type
uint64_t getRawMagic< uint64_t >()
static ErrorOr< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(std::string Path)
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
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)...
static std::error_code error(DiagnosticHandlerFunction DiagnosticHandler, std::error_code EC, const Twine &Message)
Reader for the simple text based instrprof format.
uint64_t getRawMagic< uint32_t >()
std::error_code readNextRecord(InstrProfRecord &Record) override
Read a single record.
size_t size() const
size - Get the array size.
static bool hasFormat(const MemoryBuffer &DataBuffer)
static OnDiskIterableChainedHashTable * Create(const unsigned char *Buckets, const unsigned char *const Payload, const unsigned char *const Base, const Info &InfoObj=Info())
Create the hash table.
std::error_code getFunctionCounts(StringRef FuncName, uint64_t FuncHash, std::vector< uint64_t > &Counts)
Fill Counts with the profile data for the given function name.
hash_value_type ComputeHash(StringRef K)
std::error_code readHeader() override
Read the file header.
static uint64_t getRawMagic()
Base class and interface for reading profiling data of any known instrprof format.
bool is_at_end() const
Return true if we're an "end" iterator or have reached EOF.
bool empty() const
empty - Check if the array is empty.
static const char *const Magic
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, int64_t FileSize=-1)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
static uint64_t getRawVersion()
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...
static ErrorOr< std::unique_ptr< InstrProfReader > > create(std::string Path)
Factory method to create an appropriately typed reader for the given instrprof file.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
std::error_code readHeader() override
Read the header. Required before reading first record.
unsigned char getSwappedBytes(unsigned char C)
size_t getBufferSize() const
RawInstrProfReader< uint64_t > RawInstrProfReader64
std::vector< uint64_t > Counts
virtual std::error_code readNextRecord(InstrProfRecord &Record)=0
Read a single record.
Profiling information for a single function.
ArrayRef< InstrProfRecord > data_type
static uint64_t ComputeHash(HashT Type, StringRef K)
InstrProfLookupTrait(IndexedInstrProf::HashT HashType, unsigned FormatVersion)
std::string Hash(const Unit &U)
StringRef - Represent a constant reference to a string, i.e.
Reader for the indexed binary instrprof format.
static ErrorOr< std::unique_ptr< IndexedInstrProfReader > > create(std::string Path)
Factory method to create an indexed reader.
bool empty() const
empty - Check if the string is empty.