LLVM 24.0.0git
InstrProfReader.h
Go to the documentation of this file.
1//===- InstrProfReader.h - Instrumented profiling readers -------*- C++ -*-===//
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 support for reading profiling data for instrumentation
10// based PGO and coverage.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_PROFILEDATA_INSTRPROFREADER_H
15#define LLVM_PROFILEDATA_INSTRPROFREADER_H
16
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/StringRef.h"
20#include "llvm/Object/BuildID.h"
28#include "llvm/Support/Endian.h"
29#include "llvm/Support/Error.h"
36#include <algorithm>
37#include <cassert>
38#include <cstddef>
39#include <cstdint>
40#include <iterator>
41#include <memory>
42#include <utility>
43#include <vector>
44
45namespace llvm {
46
47class InstrProfReader;
48
49/// A file format agnostic iterator over profiling data.
50template <class record_type = NamedInstrProfRecord,
51 class reader_type = InstrProfReader>
53public:
54 using iterator_category = std::input_iterator_tag;
55 using value_type = record_type;
56 using difference_type = std::ptrdiff_t;
59
60private:
61 reader_type *Reader = nullptr;
62 value_type Record;
63
64 void increment() {
65 if (Error E = Reader->readNextRecord(Record)) {
66 // Handle errors in the reader.
67 InstrProfError::take(std::move(E));
68 *this = InstrProfIterator();
69 }
70 }
71
72public:
73 InstrProfIterator() = default;
74 InstrProfIterator(reader_type *Reader) : Reader(Reader) { increment(); }
75
77 increment();
78 return *this;
79 }
80 bool operator==(const InstrProfIterator &RHS) const {
81 return Reader == RHS.Reader;
82 }
83 bool operator!=(const InstrProfIterator &RHS) const {
84 return Reader != RHS.Reader;
85 }
86 value_type &operator*() { return Record; }
87 value_type *operator->() { return &Record; }
88};
89
90/// Base class and interface for reading profiling data of any known instrprof
91/// format. Provides an iterator over NamedInstrProfRecords.
94 std::string LastErrorMsg;
95
96public:
97 InstrProfReader() = default;
98 virtual ~InstrProfReader() = default;
99
100 /// Read the header. Required before reading first record.
101 virtual Error readHeader() = 0;
102
103 /// Read a single record.
105
106 /// Read a list of binary ids.
107 virtual Error readBinaryIds(std::vector<llvm::object::BuildID> &BinaryIds) {
108 return success();
109 }
110
111 /// Print binary ids.
112 virtual Error printBinaryIds(raw_ostream &OS) { return success(); };
113
114 /// Iterator over profile data.
117
118 /// Return the profile version.
119 virtual uint64_t getVersion() const = 0;
120
121 virtual bool isIRLevelProfile() const = 0;
122
123 virtual bool hasCSIRLevelProfile() const = 0;
124
125 virtual bool instrEntryBBEnabled() const = 0;
126
127 /// Return true if the profile instruments all loop entries.
128 virtual bool instrLoopEntriesEnabled() const = 0;
129
130 /// Return true if the profile has single byte counters representing coverage.
131 virtual bool hasSingleByteCoverage() const = 0;
132
133 /// Return true if the profile only instruments function entries.
134 virtual bool functionEntryOnly() const = 0;
135
136 /// Return true if profile includes a memory profile.
137 virtual bool hasMemoryProfile() const = 0;
138
139 /// Return true if this has a temporal profile.
140 virtual bool hasTemporalProfile() const = 0;
141
142 /// Returns a BitsetEnum describing the attributes of the profile. To check
143 /// individual attributes prefer using the helpers above.
144 virtual InstrProfKind getProfileKind() const = 0;
145
146 /// Return the PGO symtab. There are three different readers:
147 /// Raw, Text, and Indexed profile readers. The first two types
148 /// of readers are used only by llvm-profdata tool, while the indexed
149 /// profile reader is also used by llvm-cov tool and the compiler (
150 /// backend or frontend). Since creating PGO symtab can create
151 /// significant runtime and memory overhead (as it touches data
152 /// for the whole program), InstrProfSymtab for the indexed profile
153 /// reader should be created on demand and it is recommended to be
154 /// only used for dumping purpose with llvm-proftool, not with the
155 /// compiler.
157
158 /// Compute the sum of counts and return in Sum.
159 LLVM_ABI void accumulateCounts(CountSumOrPercent &Sum, bool IsCS);
160
161protected:
162 std::unique_ptr<InstrProfSymtab> Symtab;
163 /// A list of temporal profile traces.
165 /// The total number of temporal profile traces seen.
167
168 /// Set the current error and return same.
169 Error error(instrprof_error Err, const std::string &ErrMsg = "") {
170 LastError = Err;
171 LastErrorMsg = ErrMsg;
172 if (Err == instrprof_error::success)
173 return Error::success();
174 return make_error<InstrProfError>(Err, ErrMsg);
175 }
176
178 handleAllErrors(std::move(E), [&](const InstrProfError &IPE) {
179 LastError = IPE.get();
180 LastErrorMsg = IPE.getMessage();
181 });
182 return make_error<InstrProfError>(LastError, LastErrorMsg);
183 }
184
185 /// Clear the current error and return a successful one.
187
188public:
189 /// Return true if the reader has finished reading the profile data.
190 bool isEOF() { return LastError == instrprof_error::eof; }
191
192 /// Return true if the reader encountered an error reading profiling data.
193 bool hasError() { return LastError != instrprof_error::success && !isEOF(); }
194
195 /// Get the current error.
197 if (hasError())
198 return make_error<InstrProfError>(LastError, LastErrorMsg);
199 return Error::success();
200 }
201
202 /// Factory method to create an appropriately typed reader for the given
203 /// instrprof file.
205 const Twine &Path, vfs::FileSystem &FS,
206 const InstrProfCorrelator *Correlator = nullptr,
207 const object::BuildIDFetcher *BIDFetcher = nullptr,
208 const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind =
210 std::function<void(Error)> Warn = nullptr);
211
213 std::unique_ptr<MemoryBuffer> Buffer,
214 const InstrProfCorrelator *Correlator = nullptr,
215 const object::BuildIDFetcher *BIDFetcher = nullptr,
216 const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind =
218 std::function<void(Error)> Warn = nullptr);
219
220 /// \param Weight for raw profiles use this as the temporal profile trace
221 /// weight
222 /// \returns a list of temporal profile traces.
224 getTemporalProfTraces(std::optional<uint64_t> Weight = {}) {
225 // For non-raw profiles we ignore the input weight and instead use the
226 // weights already in the traces.
227 return TemporalProfTraces;
228 }
229 /// \returns the total number of temporal profile traces seen.
233};
234
235/// Reader for the simple text based instrprof format.
236///
237/// This format is a simple text format that's suitable for test data. Records
238/// are separated by one or more blank lines, and record fields are separated by
239/// new lines.
240///
241/// Each record consists of a function name, a function hash, a number of
242/// counters, and then each counter value, in that order.
244private:
245 /// The profile data file contents.
246 std::unique_ptr<MemoryBuffer> DataBuffer;
247 /// Iterator over the profile data.
248 line_iterator Line;
249 /// The attributes of the current profile.
251
252 Error readValueProfileData(InstrProfRecord &Record);
253
254 Error readTemporalProfTraceData();
255
256public:
257 TextInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer_)
258 : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#') {}
261
262 /// Return true if the given buffer is in text instrprof format.
263 static bool hasFormat(const MemoryBuffer &Buffer);
264
265 // Text format does not have version, so return 0.
266 uint64_t getVersion() const override { return 0; }
267
268 bool isIRLevelProfile() const override {
269 return static_cast<bool>(ProfileKind & InstrProfKind::IRInstrumentation);
270 }
271
272 bool hasCSIRLevelProfile() const override {
273 return static_cast<bool>(ProfileKind & InstrProfKind::ContextSensitive);
274 }
275
276 bool instrEntryBBEnabled() const override {
277 return static_cast<bool>(ProfileKind &
279 }
280
281 bool instrLoopEntriesEnabled() const override {
282 return static_cast<bool>(ProfileKind &
284 }
285
286 bool hasSingleByteCoverage() const override {
287 return static_cast<bool>(ProfileKind & InstrProfKind::SingleByteCoverage);
288 }
289
290 bool functionEntryOnly() const override {
291 return static_cast<bool>(ProfileKind & InstrProfKind::FunctionEntryOnly);
292 }
293
294 bool hasMemoryProfile() const override {
295 // TODO: Add support for text format memory profiles.
296 return false;
297 }
298
299 bool hasTemporalProfile() const override {
300 return static_cast<bool>(ProfileKind & InstrProfKind::TemporalProfile);
301 }
302
303 InstrProfKind getProfileKind() const override { return ProfileKind; }
304
305 /// Read the header.
306 Error readHeader() override;
307
308 /// Read a single record.
309 Error readNextRecord(NamedInstrProfRecord &Record) override;
310
312 assert(Symtab);
313 return *Symtab;
314 }
315};
316
317/// Reader for the raw instrprof binary format from runtime.
318///
319/// This format is a raw memory dump of the instrumentation-based profiling data
320/// from the runtime. It has no index.
321///
322/// Templated on the unsigned type whose size matches pointers on the platform
323/// that wrote the profile.
324template <class IntPtrT>
326private:
327 /// The profile data file contents.
328 std::unique_ptr<MemoryBuffer> DataBuffer;
329 /// If available, this hold the ProfileData array used to correlate raw
330 /// instrumentation data to their functions.
331 const InstrProfCorrelatorImpl<IntPtrT> *Correlator;
332 /// Fetches debuginfo by build id to correlate profiles.
333 const object::BuildIDFetcher *BIDFetcher;
334 /// Correlates profiles with build id fetcher by fetching debuginfo with build
335 /// ID.
336 std::unique_ptr<InstrProfCorrelator> BIDFetcherCorrelator;
337 /// Indicates if should use debuginfo or binary to correlate with build id
338 /// fetcher.
339 InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind;
340 /// A list of timestamps paired with a function name reference.
341 std::vector<std::pair<uint64_t, uint64_t>> TemporalProfTimestamps;
342 bool ShouldSwapBytes;
343 // The value of the version field of the raw profile data header. The lower 32
344 // bits specifies the format version and the most significant 32 bits specify
345 // the variant types of the profile.
346 uint64_t Version;
347 uint64_t CountersDelta;
348 uint64_t BitmapDelta;
349 uint64_t UniformCountersDelta;
350 uint64_t NamesDelta;
353 const RawInstrProf::VTableProfileData<IntPtrT> *VTableBegin = nullptr;
354 const RawInstrProf::VTableProfileData<IntPtrT> *VTableEnd = nullptr;
355 const char *CountersStart;
356 const char *CountersEnd;
357 const char *BitmapStart;
358 const char *BitmapEnd;
359 const char *UniformCountersStart;
360 const char *UniformCountersEnd;
361 const char *NamesStart;
362 const char *NamesEnd;
363 const char *VNamesStart = nullptr;
364 const char *VNamesEnd = nullptr;
365 // After value profile is all read, this pointer points to
366 // the header of next profile data (if exists)
367 const uint8_t *ValueDataStart;
368 uint32_t ValueKindLast;
369 uint32_t CurValueDataSize;
370 std::vector<llvm::object::BuildID> BinaryIds;
371
372 std::function<void(Error)> Warn;
373
374 /// Maxium counter value 2^56.
375 static const uint64_t MaxCounterValue = (1ULL << 56);
376
377public:
379 std::unique_ptr<MemoryBuffer> DataBuffer,
380 const InstrProfCorrelator *Correlator,
381 const object::BuildIDFetcher *BIDFetcher,
382 const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind,
383 std::function<void(Error)> Warn)
384 : DataBuffer(std::move(DataBuffer)),
386 Correlator)),
387 BIDFetcher(BIDFetcher),
388 BIDFetcherCorrelatorKind(BIDFetcherCorrelatorKind), Warn(Warn) {}
389
392
393 static bool hasFormat(const MemoryBuffer &DataBuffer);
394 Error readHeader() override;
396 Error readBinaryIds(std::vector<llvm::object::BuildID> &BinaryIds) override;
398
399 uint64_t getVersion() const override { return Version; }
400
401 bool isIRLevelProfile() const override {
402 return (Version & VARIANT_MASK_IR_PROF) != 0;
403 }
404
405 bool hasCSIRLevelProfile() const override {
406 return (Version & VARIANT_MASK_CSIR_PROF) != 0;
407 }
408
409 bool instrEntryBBEnabled() const override {
410 return (Version & VARIANT_MASK_INSTR_ENTRY) != 0;
411 }
412
413 bool instrLoopEntriesEnabled() const override {
414 return (Version & VARIANT_MASK_INSTR_LOOP_ENTRIES) != 0;
415 }
416
417 bool hasSingleByteCoverage() const override {
418 return (Version & VARIANT_MASK_BYTE_COVERAGE) != 0;
419 }
420
421 bool functionEntryOnly() const override {
422 return (Version & VARIANT_MASK_FUNCTION_ENTRY_ONLY) != 0;
423 }
424
425 bool hasMemoryProfile() const override {
426 // Memory profiles have a separate raw format, so this should never be set.
427 assert(!(Version & VARIANT_MASK_MEMPROF));
428 return false;
429 }
430
431 bool hasTemporalProfile() const override {
432 return (Version & VARIANT_MASK_TEMPORAL_PROF) != 0;
433 }
434
435 /// Returns a BitsetEnum describing the attributes of the raw instr profile.
437
439 assert(Symtab.get());
440 return *Symtab.get();
441 }
442
444 getTemporalProfTraces(std::optional<uint64_t> Weight = {}) override;
445
446private:
447 Error createSymtab(InstrProfSymtab &Symtab);
448 Error readNextHeader(const char *CurrentPos);
450
451 template <class IntT> IntT swap(IntT Int) const {
452 return ShouldSwapBytes ? llvm::byteswap(Int) : Int;
453 }
454
455 llvm::endianness getDataEndianness() const {
456 if (!ShouldSwapBytes)
460 else
462 }
463
464 inline uint8_t getNumPaddingBytes(uint64_t SizeInBytes) {
465 return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t));
466 }
467
468 Error readName(NamedInstrProfRecord &Record);
469 Error readFuncHash(NamedInstrProfRecord &Record);
470 Error readRawCounts(InstrProfRecord &Record);
471 Error readRawBitmapBytes(InstrProfRecord &Record);
472 Error readRawUniformCounters(InstrProfRecord &Record);
473 Error readValueProfilingData(InstrProfRecord &Record);
474 bool atEnd() const { return Data == DataEnd; }
475
476 void advanceData() {
477 // `CountersDelta` and `BitmapDelta` are constant zero when using debug info
478 // correlation.
479 if (!Correlator && !BIDFetcherCorrelator) {
480 // The initial CountersDelta is the in-memory address difference between
481 // the data and counts sections:
482 // start(__llvm_prf_cnts) - start(__llvm_prf_data)
483 // As we advance to the next record, we maintain the correct CountersDelta
484 // with respect to the next record.
485 CountersDelta -= sizeof(*Data);
486 BitmapDelta -= sizeof(*Data);
487 UniformCountersDelta -= sizeof(*Data);
488 }
489 Data++;
490 ValueDataStart += CurValueDataSize;
491 }
492
493 const char *getNextHeaderPos() const {
494 assert(atEnd());
495 return (const char *)ValueDataStart;
496 }
497
498 StringRef getName(uint64_t NameRef) const {
499 return Symtab->getFuncOrVarName(swap(NameRef));
500 }
501
502 int getCounterTypeSize() const {
503 return hasSingleByteCoverage() ? sizeof(uint8_t) : sizeof(uint64_t);
504 }
505};
506
509
510namespace IndexedInstrProf {
511
512enum class HashT : uint32_t;
513
514} // end namespace IndexedInstrProf
515
516/// Trait for lookups into the on-disk hash table for the binary instrprof
517/// format.
519 std::vector<NamedInstrProfRecord> DataBuffer;
521 unsigned FormatVersion;
522 // Endianness of the input value profile data.
523 // It should be LE by default, but can be changed
524 // for testing purpose.
525 llvm::endianness ValueProfDataEndianness = llvm::endianness::little;
526
527public:
528 InstrProfLookupTrait(IndexedInstrProf::HashT HashType, unsigned FormatVersion)
529 : HashType(HashType), FormatVersion(FormatVersion) {}
530
532
537
538 static bool EqualKey(StringRef A, StringRef B) { return A == B; }
541
542 LLVM_ABI hash_value_type ComputeHash(StringRef K);
543
544 static std::pair<offset_type, offset_type>
545 ReadKeyDataLength(const unsigned char *&D) {
546 using namespace support;
547
548 offset_type KeyLen =
550 offset_type DataLen =
552 return std::make_pair(KeyLen, DataLen);
553 }
554
555 StringRef ReadKey(const unsigned char *D, offset_type N) {
556 return StringRef((const char *)D, N);
557 }
558
559 LLVM_ABI bool readValueProfilingData(const unsigned char *&D,
560 const unsigned char *const End);
561 LLVM_ABI data_type ReadData(StringRef K, const unsigned char *D,
562 offset_type N);
563
564 // Used for testing purpose only.
566 ValueProfDataEndianness = Endianness;
567 }
568};
569
571 virtual ~InstrProfReaderIndexBase() = default;
572
573 // Read all the profile records with the same key pointed to the current
574 // iterator.
576
577 // Read all the profile records with the key equal to FuncName
578 virtual Error getRecords(StringRef FuncName,
580 virtual void advanceToNextKey() = 0;
581 virtual bool atEnd() const = 0;
582 virtual void setValueProfDataEndianness(llvm::endianness Endianness) = 0;
583 virtual uint64_t getVersion() const = 0;
584 virtual bool isIRLevelProfile() const = 0;
585 virtual bool hasCSIRLevelProfile() const = 0;
586 virtual bool instrEntryBBEnabled() const = 0;
587 virtual bool instrLoopEntriesEnabled() const = 0;
588 virtual bool hasSingleByteCoverage() const = 0;
589 virtual bool functionEntryOnly() const = 0;
590 virtual bool hasMemoryProfile() const = 0;
591 virtual bool hasTemporalProfile() const = 0;
592 virtual InstrProfKind getProfileKind() const = 0;
594};
595
598
605
606template <typename HashTableImpl>
608
609template <typename HashTableImpl>
611private:
612 std::unique_ptr<HashTableImpl> HashTable;
613 typename HashTableImpl::data_iterator RecordIterator;
614 uint64_t FormatVersion;
615
616 friend class InstrProfReaderItaniumRemapper<HashTableImpl>;
617
618public:
619 InstrProfReaderIndex(const unsigned char *Buckets,
620 const unsigned char *const Payload,
621 const unsigned char *const Base,
623 ~InstrProfReaderIndex() override = default;
624
626 Error getRecords(StringRef FuncName,
628 void advanceToNextKey() override { RecordIterator++; }
629
630 bool atEnd() const override {
631 return RecordIterator == HashTable->data_end();
632 }
633
635 HashTable->getInfoObj().setValueProfDataEndianness(Endianness);
636 }
637
638 uint64_t getVersion() const override { return GET_VERSION(FormatVersion); }
639
640 bool isIRLevelProfile() const override {
641 return (FormatVersion & VARIANT_MASK_IR_PROF) != 0;
642 }
643
644 bool hasCSIRLevelProfile() const override {
645 return (FormatVersion & VARIANT_MASK_CSIR_PROF) != 0;
646 }
647
648 bool instrEntryBBEnabled() const override {
649 return (FormatVersion & VARIANT_MASK_INSTR_ENTRY) != 0;
650 }
651
652 bool instrLoopEntriesEnabled() const override {
653 return (FormatVersion & VARIANT_MASK_INSTR_LOOP_ENTRIES) != 0;
654 }
655
656 bool hasSingleByteCoverage() const override {
657 return (FormatVersion & VARIANT_MASK_BYTE_COVERAGE) != 0;
658 }
659
660 bool functionEntryOnly() const override {
661 return (FormatVersion & VARIANT_MASK_FUNCTION_ENTRY_ONLY) != 0;
662 }
663
664 bool hasMemoryProfile() const override {
665 return (FormatVersion & VARIANT_MASK_MEMPROF) != 0;
666 }
667
668 bool hasTemporalProfile() const override {
669 return (FormatVersion & VARIANT_MASK_TEMPORAL_PROF) != 0;
670 }
671
672 InstrProfKind getProfileKind() const override;
673
675 // FIXME: the create method calls 'finalizeSymtab' and sorts a bunch of
676 // arrays/maps. Since there are other data sources other than 'HashTable' to
677 // populate a symtab, it might make sense to have something like this
678 // 1. Let each data source populate Symtab and init the arrays/maps without
679 // calling 'finalizeSymtab'
680 // 2. Call 'finalizeSymtab' once to get all arrays/maps sorted if needed.
681 return Symtab.create(HashTable->keys());
682 }
683};
684
685/// Name matcher supporting fuzzy matching of symbol names to names in profiles.
687public:
688 virtual ~InstrProfReaderRemapper() = default;
690 virtual Error getRecords(StringRef FuncName,
692};
693
695private:
696 /// The MemProf version.
699 /// MemProf summary (if available, version >= 4).
700 std::unique_ptr<memprof::MemProfSummary> MemProfSum;
701 /// MemProf profile schema (if available).
703 /// MemProf record profile data on-disk indexed via llvm::md5(FunctionName).
704 std::unique_ptr<MemProfRecordHashTable> MemProfRecordTable;
705 /// MemProf frame profile data on-disk indexed via frame id.
706 std::unique_ptr<MemProfFrameHashTable> MemProfFrameTable;
707 /// MemProf call stack data on-disk indexed via call stack id.
708 std::unique_ptr<MemProfCallStackHashTable> MemProfCallStackTable;
709 /// The starting address of the frame array.
710 const unsigned char *FrameBase = nullptr;
711 /// The starting address of the call stack array.
712 const unsigned char *CallStackBase = nullptr;
713 // The number of elements in the radix tree array.
714 unsigned RadixTreeSize = 0;
715 /// The data access profiles, deserialized from binary data.
716 std::unique_ptr<memprof::DataAccessProfData> DataAccessProfileData;
717
718 Error deserializeV2(const unsigned char *Start, const unsigned char *Ptr);
719 Error deserializeRadixTreeBased(const unsigned char *Start,
720 const unsigned char *Ptr,
722
723public:
725
726 LLVM_ABI Error deserialize(const unsigned char *Start,
727 uint64_t MemProfOffset);
728
730 getMemProfRecord(const uint64_t FuncNameHash) const;
731
734
735 // Returns non-owned pointer to data access profile data.
737 return DataAccessProfileData.get();
738 }
739
740 // Return the entire MemProf profile.
742
743 memprof::MemProfSummary *getSummary() const { return MemProfSum.get(); }
744};
745
746/// Reader for the indexed binary instrprof format.
748private:
749 /// The profile data file contents.
750 std::unique_ptr<MemoryBuffer> DataBuffer;
751 /// The profile remapping file contents.
752 std::unique_ptr<MemoryBuffer> RemappingBuffer;
753 /// The index into the profile data.
754 std::unique_ptr<InstrProfReaderIndexBase> Index;
755 /// The profile remapping file contents.
756 std::unique_ptr<InstrProfReaderRemapper> Remapper;
757 /// Profile summary data.
758 std::unique_ptr<ProfileSummary> Summary;
759 /// Context sensitive profile summary data.
760 std::unique_ptr<ProfileSummary> CS_Summary;
761 IndexedMemProfReader MemProfReader;
762 /// The compressed vtable names, to be used for symtab construction.
763 /// A compiler that reads indexed profiles could construct symtab from module
764 /// IR so it doesn't need the decompressed names.
765 StringRef VTableName;
766 /// A memory buffer holding binary ids.
767 ArrayRef<uint8_t> BinaryIdsBuffer;
768
769 // Index to the current record in the record array.
770 unsigned RecordIndex = 0;
771
772 // Read the profile summary. Return a pointer pointing to one byte past the
773 // end of the summary data if it exists or the input \c Cur.
774 // \c UseCS indicates whether to use the context-sensitive profile summary.
775 const unsigned char *readSummary(IndexedInstrProf::ProfVersion Version,
776 const unsigned char *Cur, bool UseCS);
777
778public:
780 std::unique_ptr<MemoryBuffer> DataBuffer,
781 std::unique_ptr<MemoryBuffer> RemappingBuffer = nullptr)
782 : DataBuffer(std::move(DataBuffer)),
783 RemappingBuffer(std::move(RemappingBuffer)) {}
786
787 /// Return the profile version.
788 uint64_t getVersion() const override { return Index->getVersion(); }
789 bool isIRLevelProfile() const override { return Index->isIRLevelProfile(); }
790 bool hasCSIRLevelProfile() const override {
791 return Index->hasCSIRLevelProfile();
792 }
793
794 bool instrEntryBBEnabled() const override {
795 return Index->instrEntryBBEnabled();
796 }
797
798 bool instrLoopEntriesEnabled() const override {
799 return Index->instrLoopEntriesEnabled();
800 }
801
802 bool hasSingleByteCoverage() const override {
803 return Index->hasSingleByteCoverage();
804 }
805
806 bool functionEntryOnly() const override { return Index->functionEntryOnly(); }
807
808 bool hasMemoryProfile() const override { return Index->hasMemoryProfile(); }
809
810 bool hasTemporalProfile() const override {
811 return Index->hasTemporalProfile();
812 }
813
814 /// Returns a BitsetEnum describing the attributes of the indexed instr
815 /// profile.
816 InstrProfKind getProfileKind() const override {
817 return Index->getProfileKind();
818 }
819
820 /// Return true if the given buffer is in an indexed instrprof format.
821 static bool hasFormat(const MemoryBuffer &DataBuffer);
822
823 /// Read the file header.
824 Error readHeader() override;
825 /// Read a single record.
826 Error readNextRecord(NamedInstrProfRecord &Record) override;
827
828 /// Return the NamedInstrProfRecord associated with FuncName and FuncHash.
829 /// When return a hash_mismatch error and MismatchedFuncSum is not nullptr,
830 /// the sum of all counters in the mismatched function will be set to
831 /// MismatchedFuncSum. If there are multiple instances of mismatched
832 /// functions, MismatchedFuncSum returns the maximum. If \c FuncName is not
833 /// found, try to lookup \c DeprecatedFuncName to handle profiles built by
834 /// older compilers.
836 getInstrProfRecord(StringRef FuncName, uint64_t FuncHash,
837 StringRef DeprecatedFuncName = "",
838 uint64_t *MismatchedFuncSum = nullptr);
839
840 /// Return the memprof record for the function identified by
841 /// llvm::md5(Name).
843 return MemProfReader.getMemProfRecord(FuncNameHash);
844 }
845
848 return MemProfReader.getMemProfCallerCalleePairs();
849 }
850
852 return MemProfReader.getAllMemProfData();
853 }
854
855 /// Fill Counts with the profile data for the given function name.
856 Error getFunctionCounts(StringRef FuncName, uint64_t FuncHash,
857 std::vector<uint64_t> &Counts);
858
859 /// Fill Bitmap with the profile data for the given function name.
860 Error getFunctionBitmap(StringRef FuncName, uint64_t FuncHash,
861 BitVector &Bitmap);
862
863 /// Return the maximum of all known function counts.
864 /// \c UseCS indicates whether to use the context-sensitive count.
866 if (UseCS) {
867 assert(CS_Summary && "No context sensitive profile summary");
868 return CS_Summary->getMaxFunctionCount();
869 } else {
870 assert(Summary && "No profile summary");
871 return Summary->getMaxFunctionCount();
872 }
873 }
874
875 /// Factory method to create an indexed reader.
877 create(const Twine &Path, vfs::FileSystem &FS,
878 const Twine &RemappingPath = "");
879
881 create(std::unique_ptr<MemoryBuffer> Buffer,
882 std::unique_ptr<MemoryBuffer> RemappingBuffer = nullptr);
883
884 // Used for testing purpose only.
886 Index->setValueProfDataEndianness(Endianness);
887 }
888
889 // See description in the base class. This interface is designed
890 // to be used by llvm-profdata (for dumping). Avoid using this when
891 // the client is the compiler.
892 InstrProfSymtab &getSymtab() override;
893
894 /// Return the profile summary.
895 /// \c UseCS indicates whether to use the context-sensitive summary.
897 if (UseCS) {
898 assert(CS_Summary && "No context sensitive summary");
899 return *CS_Summary;
900 } else {
901 assert(Summary && "No profile summary");
902 return *Summary;
903 }
904 }
905
906 /// Return the MemProf summary. Will be null if unavailable (version < 4).
908 return MemProfReader.getSummary();
909 }
910
911 /// Returns non-owned pointer to the data access profile data.
912 /// Will be null if unavailable (version < 4).
914 return MemProfReader.getDataAccessProfileData();
915 }
916
917 Error readBinaryIds(std::vector<llvm::object::BuildID> &BinaryIds) override;
918 Error printBinaryIds(raw_ostream &OS) override;
919};
920
921} // end namespace llvm
922
923#endif // LLVM_PROFILEDATA_INSTRPROFREADER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
unsigned uint64_t
This file declares a library for handling Build IDs and using them to find debug info.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
InstrProfLookupTrait::offset_type offset_type
InstrProfLookupTrait::data_type data_type
#define GET_VERSION(V)
#define VARIANT_MASK_CSIR_PROF
#define VARIANT_MASK_MEMPROF
#define VARIANT_MASK_TEMPORAL_PROF
#define VARIANT_MASK_IR_PROF
#define VARIANT_MASK_BYTE_COVERAGE
#define VARIANT_MASK_INSTR_ENTRY
#define VARIANT_MASK_FUNCTION_ENTRY_ONLY
#define VARIANT_MASK_INSTR_LOOP_ENTRIES
Defines facilities for reading and writing on-disk hash tables.
#define error(X)
Contains the forward declaration for vfs::FileSystem, as well as the IntrusiveRefCntPtrInfo specializ...
Value * RHS
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
uint64_t getVersion() const override
Return the profile version.
IndexedInstrProfReader(const IndexedInstrProfReader &)=delete
bool hasTemporalProfile() const override
Return true if this has a temporal profile.
Expected< memprof::MemProfRecord > getMemProfRecord(uint64_t FuncNameHash)
Return the memprof record for the function identified by llvm::md5(Name).
bool hasSingleByteCoverage() const override
Return true if the profile has single byte counters representing coverage.
bool instrLoopEntriesEnabled() const override
Return true if the profile instruments all loop entries.
memprof::MemProfSummary * getMemProfSummary() const
Return the MemProf summary. Will be null if unavailable (version < 4).
ProfileSummary & getSummary(bool UseCS)
Return the profile summary.
bool hasMemoryProfile() const override
Return true if profile includes a memory profile.
bool functionEntryOnly() const override
Return true if the profile only instruments function entries.
uint64_t getMaximumFunctionCount(bool UseCS)
Return the maximum of all known function counts.
DenseMap< uint64_t, SmallVector< memprof::CallEdgeTy, 0 > > getMemProfCallerCalleePairs()
InstrProfKind getProfileKind() const override
Returns a BitsetEnum describing the attributes of the indexed instr profile.
void setValueProfDataEndianness(llvm::endianness Endianness)
memprof::DataAccessProfData * getDataAccessProfileData() const
Returns non-owned pointer to the data access profile data.
memprof::AllMemProfData getAllMemProfData() const
IndexedInstrProfReader(std::unique_ptr< MemoryBuffer > DataBuffer, std::unique_ptr< MemoryBuffer > RemappingBuffer=nullptr)
bool hasCSIRLevelProfile() const override
IndexedInstrProfReader & operator=(const IndexedInstrProfReader &)=delete
bool instrEntryBBEnabled() const override
bool isIRLevelProfile() const override
LLVM_ABI Error deserialize(const unsigned char *Start, uint64_t MemProfOffset)
memprof::MemProfSummary * getSummary() const
LLVM_ABI memprof::AllMemProfData getAllMemProfData() const
memprof::DataAccessProfData * getDataAccessProfileData() const
LLVM_ABI Expected< memprof::MemProfRecord > getMemProfRecord(const uint64_t FuncNameHash) const
LLVM_ABI DenseMap< uint64_t, SmallVector< memprof::CallEdgeTy, 0 > > getMemProfCallerCalleePairs() const
InstrProfCorrelatorImpl - A child of InstrProfCorrelator with a template pointer type so that the Pro...
InstrProfCorrelator - A base class used to create raw instrumentation data to their functions.
ProfCorrelatorKind
Indicate if we should use the debug info or profile metadata sections to correlate.
static std::pair< instrprof_error, std::string > take(Error E)
Consume an Error and return the raw enum value contained within it, and the optional error message.
Definition InstrProf.h:484
const std::string & getMessage() const
Definition InstrProf.h:479
instrprof_error get() const
Definition InstrProf.h:478
A file format agnostic iterator over profiling data.
bool operator==(const InstrProfIterator &RHS) const
InstrProfIterator(reader_type *Reader)
InstrProfIterator & operator++()
bool operator!=(const InstrProfIterator &RHS) const
std::ptrdiff_t difference_type
std::input_iterator_tag iterator_category
InstrProfLookupTrait(IndexedInstrProf::HashT HashType, unsigned FormatVersion)
void setValueProfDataEndianness(llvm::endianness Endianness)
StringRef ReadKey(const unsigned char *D, offset_type N)
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
static StringRef GetExternalKey(StringRef K)
LLVM_ABI data_type ReadData(StringRef K, const unsigned char *D, offset_type N)
LLVM_ABI bool readValueProfilingData(const unsigned char *&D, const unsigned char *const End)
LLVM_ABI hash_value_type ComputeHash(StringRef K)
static bool EqualKey(StringRef A, StringRef B)
static StringRef GetInternalKey(StringRef K)
ArrayRef< NamedInstrProfRecord > data_type
Error populateSymtab(InstrProfSymtab &Symtab) override
bool hasSingleByteCoverage() const override
bool hasCSIRLevelProfile() const override
void setValueProfDataEndianness(llvm::endianness Endianness) override
InstrProfKind getProfileKind() const override
Error getRecords(ArrayRef< NamedInstrProfRecord > &Data) override
bool functionEntryOnly() const override
~InstrProfReaderIndex() override=default
bool instrLoopEntriesEnabled() const override
uint64_t getVersion() const override
bool isIRLevelProfile() const override
bool hasMemoryProfile() const override
bool hasTemporalProfile() const override
bool instrEntryBBEnabled() const override
InstrProfReaderIndex(const unsigned char *Buckets, const unsigned char *const Payload, const unsigned char *const Base, IndexedInstrProf::HashT HashType, uint64_t Version)
bool atEnd() const override
A remapper that applies remappings based on a symbol remapping file.
Name matcher supporting fuzzy matching of symbol names to names in profiles.
virtual Error getRecords(StringRef FuncName, ArrayRef< NamedInstrProfRecord > &Data)=0
virtual ~InstrProfReaderRemapper()=default
Base class and interface for reading profiling data of any known instrprof format.
InstrProfIterator begin()
Iterator over profile data.
virtual bool instrEntryBBEnabled() const =0
virtual Error readNextRecord(NamedInstrProfRecord &Record)=0
Read a single record.
Error error(Error &&E)
InstrProfIterator end()
virtual Error readBinaryIds(std::vector< llvm::object::BuildID > &BinaryIds)
Read a list of binary ids.
virtual bool functionEntryOnly() const =0
Return true if the profile only instruments function entries.
std::unique_ptr< InstrProfSymtab > Symtab
Error getError()
Get the current error.
virtual InstrProfSymtab & getSymtab()=0
Return the PGO symtab.
virtual bool hasSingleByteCoverage() const =0
Return true if the profile has single byte counters representing coverage.
virtual bool hasTemporalProfile() const =0
Return true if this has a temporal profile.
Error success()
Clear the current error and return a successful one.
bool hasError()
Return true if the reader encountered an error reading profiling data.
virtual InstrProfKind getProfileKind() const =0
Returns a BitsetEnum describing the attributes of the profile.
SmallVector< TemporalProfTraceTy > TemporalProfTraces
A list of temporal profile traces.
uint64_t TemporalProfTraceStreamSize
The total number of temporal profile traces seen.
virtual Error printBinaryIds(raw_ostream &OS)
Print binary ids.
uint64_t getTemporalProfTraceStreamSize()
virtual uint64_t getVersion() const =0
Return the profile version.
virtual bool hasMemoryProfile() const =0
Return true if profile includes a memory profile.
virtual bool instrLoopEntriesEnabled() const =0
Return true if the profile instruments all loop entries.
virtual SmallVector< TemporalProfTraceTy > & getTemporalProfTraces(std::optional< uint64_t > Weight={})
virtual bool hasCSIRLevelProfile() const =0
virtual bool isIRLevelProfile() const =0
virtual ~InstrProfReader()=default
virtual Error readHeader()=0
Read the header. Required before reading first record.
Error error(instrprof_error Err, const std::string &ErrMsg="")
Set the current error and return same.
LLVM_ABI void accumulateCounts(CountSumOrPercent &Sum, bool IsCS)
Compute the sum of counts and return in Sum.
static LLVM_ABI Expected< std::unique_ptr< InstrProfReader > > create(const Twine &Path, vfs::FileSystem &FS, const InstrProfCorrelator *Correlator=nullptr, const object::BuildIDFetcher *BIDFetcher=nullptr, const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind=InstrProfCorrelator::ProfCorrelatorKind::NONE, std::function< void(Error)> Warn=nullptr)
Factory method to create an appropriately typed reader for the given instrprof file.
bool isEOF()
Return true if the reader has finished reading the profile data.
A symbol table used for function [IR]PGO name look-up with keys (such as pointers,...
Definition InstrProf.h:519
LLVM_ABI Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Provides lookup and iteration over an on disk hash table.
Reader for the raw instrprof binary format from runtime.
bool functionEntryOnly() const override
Return true if the profile only instruments function entries.
RawInstrProfReader(std::unique_ptr< MemoryBuffer > DataBuffer, const InstrProfCorrelator *Correlator, const object::BuildIDFetcher *BIDFetcher, const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind, std::function< void(Error)> Warn)
Error readHeader() override
Read the header. Required before reading first record.
Error readNextRecord(NamedInstrProfRecord &Record) override
Read a single record.
Error printBinaryIds(raw_ostream &OS) override
Print binary ids.
static bool hasFormat(const MemoryBuffer &DataBuffer)
RawInstrProfReader & operator=(const RawInstrProfReader &)=delete
bool hasSingleByteCoverage() const override
Return true if the profile has single byte counters representing coverage.
bool isIRLevelProfile() const override
InstrProfKind getProfileKind() const override
Returns a BitsetEnum describing the attributes of the raw instr profile.
bool hasMemoryProfile() const override
Return true if profile includes a memory profile.
bool instrLoopEntriesEnabled() const override
Return true if the profile instruments all loop entries.
InstrProfSymtab & getSymtab() override
Return the PGO symtab.
Error readBinaryIds(std::vector< llvm::object::BuildID > &BinaryIds) override
Read a list of binary ids.
bool hasTemporalProfile() const override
Return true if this has a temporal profile.
bool instrEntryBBEnabled() const override
uint64_t getVersion() const override
Return the profile version.
SmallVector< TemporalProfTraceTy > & getTemporalProfTraces(std::optional< uint64_t > Weight={}) override
RawInstrProfReader(const RawInstrProfReader &)=delete
bool hasCSIRLevelProfile() const override
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool isIRLevelProfile() const override
uint64_t getVersion() const override
Return the profile version.
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if the given buffer is in text instrprof format.
TextInstrProfReader(std::unique_ptr< MemoryBuffer > DataBuffer_)
bool hasSingleByteCoverage() const override
Return true if the profile has single byte counters representing coverage.
TextInstrProfReader(const TextInstrProfReader &)=delete
bool hasMemoryProfile() const override
Return true if profile includes a memory profile.
bool hasCSIRLevelProfile() const override
InstrProfSymtab & getSymtab() override
Return the PGO symtab.
bool instrEntryBBEnabled() const override
bool functionEntryOnly() const override
Return true if the profile only instruments function entries.
InstrProfKind getProfileKind() const override
Returns a BitsetEnum describing the attributes of the profile.
bool hasTemporalProfile() const override
Return true if this has a temporal profile.
TextInstrProfReader & operator=(const TextInstrProfReader &)=delete
bool instrLoopEntriesEnabled() const override
Return true if the profile instruments all loop entries.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
A forward iterator which reads text lines from a buffer.
Encapsulates the data access profile data and the methods to operate on it.
BuildIDFetcher searches local cache directories for debug info.
Definition BuildID.h:41
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
The virtual file system interface.
llvm::SmallVector< Meta, static_cast< int >(Meta::Size)> MemProfSchema
Definition MemProf.h:76
constexpr uint64_t MinimumSupportedVersion
Definition MemProf.h:52
value_type readNext(const CharT *&memory, endianness endian)
Read a value of a particular endianness from a buffer, and increment the buffer past that value.
Definition Endian.h:67
This is an optimization pass for GlobalISel generic memory operations.
RawInstrProfReader< uint64_t > RawInstrProfReader64
OnDiskIterableChainedHashTable< InstrProfLookupTrait > OnDiskHashTableImplV3
OnDiskIterableChainedHashTable< memprof::RecordLookupTrait > MemProfRecordHashTable
constexpr T byteswap(T V) noexcept
Reverses the bytes in the given integer value V.
Definition bit.h:102
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition Error.h:1013
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
FuncHash
Definition InstrProf.h:78
OnDiskIterableChainedHashTable< memprof::CallStackLookupTrait > MemProfCallStackHashTable
OnDiskIterableChainedHashTable< memprof::FrameLookupTrait > MemProfFrameHashTable
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
instrprof_error
Definition InstrProf.h:410
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
endianness
Definition bit.h:71
InstrProfKind
An enum describing the attributes of an instrumented profile.
Definition InstrProf.h:385
RawInstrProfReader< uint32_t > RawInstrProfReader32
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
#define N
virtual Error populateSymtab(InstrProfSymtab &)=0
virtual Error getRecords(ArrayRef< NamedInstrProfRecord > &Data)=0
virtual ~InstrProfReaderIndexBase()=default
virtual bool instrLoopEntriesEnabled() const =0
virtual InstrProfKind getProfileKind() const =0
virtual bool hasTemporalProfile() const =0
virtual bool isIRLevelProfile() const =0
virtual void advanceToNextKey()=0
virtual bool hasMemoryProfile() const =0
virtual bool hasCSIRLevelProfile() const =0
virtual uint64_t getVersion() const =0
virtual bool atEnd() const =0
virtual bool instrEntryBBEnabled() const =0
virtual Error getRecords(StringRef FuncName, ArrayRef< NamedInstrProfRecord > &Data)=0
virtual void setValueProfDataEndianness(llvm::endianness Endianness)=0
virtual bool functionEntryOnly() const =0
virtual bool hasSingleByteCoverage() const =0
Profiling information for a single function.
Definition InstrProf.h:908