LLVM 23.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"
35#include <algorithm>
36#include <cassert>
37#include <cstddef>
38#include <cstdint>
39#include <iterator>
40#include <memory>
41#include <utility>
42#include <vector>
43
44namespace llvm {
45
46class InstrProfReader;
47
48namespace vfs {
49class FileSystem;
50} // namespace vfs
51
52/// A file format agnostic iterator over profiling data.
53template <class record_type = NamedInstrProfRecord,
54 class reader_type = InstrProfReader>
56public:
57 using iterator_category = std::input_iterator_tag;
58 using value_type = record_type;
59 using difference_type = std::ptrdiff_t;
62
63private:
64 reader_type *Reader = nullptr;
65 value_type Record;
66
67 void increment() {
68 if (Error E = Reader->readNextRecord(Record)) {
69 // Handle errors in the reader.
70 InstrProfError::take(std::move(E));
71 *this = InstrProfIterator();
72 }
73 }
74
75public:
76 InstrProfIterator() = default;
77 InstrProfIterator(reader_type *Reader) : Reader(Reader) { increment(); }
78
80 increment();
81 return *this;
82 }
83 bool operator==(const InstrProfIterator &RHS) const {
84 return Reader == RHS.Reader;
85 }
86 bool operator!=(const InstrProfIterator &RHS) const {
87 return Reader != RHS.Reader;
88 }
89 value_type &operator*() { return Record; }
90 value_type *operator->() { return &Record; }
91};
92
93/// Base class and interface for reading profiling data of any known instrprof
94/// format. Provides an iterator over NamedInstrProfRecords.
97 std::string LastErrorMsg;
98
99public:
100 InstrProfReader() = default;
101 virtual ~InstrProfReader() = default;
102
103 /// Read the header. Required before reading first record.
104 virtual Error readHeader() = 0;
105
106 /// Read a single record.
108
109 /// Read a list of binary ids.
110 virtual Error readBinaryIds(std::vector<llvm::object::BuildID> &BinaryIds) {
111 return success();
112 }
113
114 /// Print binary ids.
115 virtual Error printBinaryIds(raw_ostream &OS) { return success(); };
116
117 /// Iterator over profile data.
120
121 /// Return the profile version.
122 virtual uint64_t getVersion() const = 0;
123
124 virtual bool isIRLevelProfile() const = 0;
125
126 virtual bool hasCSIRLevelProfile() const = 0;
127
128 virtual bool instrEntryBBEnabled() const = 0;
129
130 /// Return true if the profile instruments all loop entries.
131 virtual bool instrLoopEntriesEnabled() const = 0;
132
133 /// Return true if the profile has single byte counters representing coverage.
134 virtual bool hasSingleByteCoverage() const = 0;
135
136 /// Return true if the profile only instruments function entries.
137 virtual bool functionEntryOnly() const = 0;
138
139 /// Return true if profile includes a memory profile.
140 virtual bool hasMemoryProfile() const = 0;
141
142 /// Return true if this has a temporal profile.
143 virtual bool hasTemporalProfile() const = 0;
144
145 /// Returns a BitsetEnum describing the attributes of the profile. To check
146 /// individual attributes prefer using the helpers above.
147 virtual InstrProfKind getProfileKind() const = 0;
148
149 /// Return the PGO symtab. There are three different readers:
150 /// Raw, Text, and Indexed profile readers. The first two types
151 /// of readers are used only by llvm-profdata tool, while the indexed
152 /// profile reader is also used by llvm-cov tool and the compiler (
153 /// backend or frontend). Since creating PGO symtab can create
154 /// significant runtime and memory overhead (as it touches data
155 /// for the whole program), InstrProfSymtab for the indexed profile
156 /// reader should be created on demand and it is recommended to be
157 /// only used for dumping purpose with llvm-proftool, not with the
158 /// compiler.
160
161 /// Compute the sum of counts and return in Sum.
162 LLVM_ABI void accumulateCounts(CountSumOrPercent &Sum, bool IsCS);
163
164protected:
165 std::unique_ptr<InstrProfSymtab> Symtab;
166 /// A list of temporal profile traces.
168 /// The total number of temporal profile traces seen.
170
171 /// Set the current error and return same.
172 Error error(instrprof_error Err, const std::string &ErrMsg = "") {
173 LastError = Err;
174 LastErrorMsg = ErrMsg;
175 if (Err == instrprof_error::success)
176 return Error::success();
177 return make_error<InstrProfError>(Err, ErrMsg);
178 }
179
181 handleAllErrors(std::move(E), [&](const InstrProfError &IPE) {
182 LastError = IPE.get();
183 LastErrorMsg = IPE.getMessage();
184 });
185 return make_error<InstrProfError>(LastError, LastErrorMsg);
186 }
187
188 /// Clear the current error and return a successful one.
190
191public:
192 /// Return true if the reader has finished reading the profile data.
193 bool isEOF() { return LastError == instrprof_error::eof; }
194
195 /// Return true if the reader encountered an error reading profiling data.
196 bool hasError() { return LastError != instrprof_error::success && !isEOF(); }
197
198 /// Get the current error.
200 if (hasError())
201 return make_error<InstrProfError>(LastError, LastErrorMsg);
202 return Error::success();
203 }
204
205 /// Factory method to create an appropriately typed reader for the given
206 /// instrprof file.
208 const Twine &Path, vfs::FileSystem &FS,
209 const InstrProfCorrelator *Correlator = nullptr,
210 const object::BuildIDFetcher *BIDFetcher = nullptr,
211 const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind =
213 std::function<void(Error)> Warn = nullptr);
214
216 std::unique_ptr<MemoryBuffer> Buffer,
217 const InstrProfCorrelator *Correlator = nullptr,
218 const object::BuildIDFetcher *BIDFetcher = nullptr,
219 const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind =
221 std::function<void(Error)> Warn = nullptr);
222
223 /// \param Weight for raw profiles use this as the temporal profile trace
224 /// weight
225 /// \returns a list of temporal profile traces.
227 getTemporalProfTraces(std::optional<uint64_t> Weight = {}) {
228 // For non-raw profiles we ignore the input weight and instead use the
229 // weights already in the traces.
230 return TemporalProfTraces;
231 }
232 /// \returns the total number of temporal profile traces seen.
236};
237
238/// Reader for the simple text based instrprof format.
239///
240/// This format is a simple text format that's suitable for test data. Records
241/// are separated by one or more blank lines, and record fields are separated by
242/// new lines.
243///
244/// Each record consists of a function name, a function hash, a number of
245/// counters, and then each counter value, in that order.
247private:
248 /// The profile data file contents.
249 std::unique_ptr<MemoryBuffer> DataBuffer;
250 /// Iterator over the profile data.
251 line_iterator Line;
252 /// The attributes of the current profile.
254
255 Error readValueProfileData(InstrProfRecord &Record);
256
257 Error readTemporalProfTraceData();
258
259public:
260 TextInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer_)
261 : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#') {}
264
265 /// Return true if the given buffer is in text instrprof format.
266 static bool hasFormat(const MemoryBuffer &Buffer);
267
268 // Text format does not have version, so return 0.
269 uint64_t getVersion() const override { return 0; }
270
271 bool isIRLevelProfile() const override {
272 return static_cast<bool>(ProfileKind & InstrProfKind::IRInstrumentation);
273 }
274
275 bool hasCSIRLevelProfile() const override {
276 return static_cast<bool>(ProfileKind & InstrProfKind::ContextSensitive);
277 }
278
279 bool instrEntryBBEnabled() const override {
280 return static_cast<bool>(ProfileKind &
282 }
283
284 bool instrLoopEntriesEnabled() const override {
285 return static_cast<bool>(ProfileKind &
287 }
288
289 bool hasSingleByteCoverage() const override {
290 return static_cast<bool>(ProfileKind & InstrProfKind::SingleByteCoverage);
291 }
292
293 bool functionEntryOnly() const override {
294 return static_cast<bool>(ProfileKind & InstrProfKind::FunctionEntryOnly);
295 }
296
297 bool hasMemoryProfile() const override {
298 // TODO: Add support for text format memory profiles.
299 return false;
300 }
301
302 bool hasTemporalProfile() const override {
303 return static_cast<bool>(ProfileKind & InstrProfKind::TemporalProfile);
304 }
305
306 InstrProfKind getProfileKind() const override { return ProfileKind; }
307
308 /// Read the header.
309 Error readHeader() override;
310
311 /// Read a single record.
312 Error readNextRecord(NamedInstrProfRecord &Record) override;
313
315 assert(Symtab);
316 return *Symtab;
317 }
318};
319
320/// Reader for the raw instrprof binary format from runtime.
321///
322/// This format is a raw memory dump of the instrumentation-based profiling data
323/// from the runtime. It has no index.
324///
325/// Templated on the unsigned type whose size matches pointers on the platform
326/// that wrote the profile.
327template <class IntPtrT>
329private:
330 /// The profile data file contents.
331 std::unique_ptr<MemoryBuffer> DataBuffer;
332 /// If available, this hold the ProfileData array used to correlate raw
333 /// instrumentation data to their functions.
334 const InstrProfCorrelatorImpl<IntPtrT> *Correlator;
335 /// Fetches debuginfo by build id to correlate profiles.
336 const object::BuildIDFetcher *BIDFetcher;
337 /// Correlates profiles with build id fetcher by fetching debuginfo with build
338 /// ID.
339 std::unique_ptr<InstrProfCorrelator> BIDFetcherCorrelator;
340 /// Indicates if should use debuginfo or binary to correlate with build id
341 /// fetcher.
342 InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind;
343 /// A list of timestamps paired with a function name reference.
344 std::vector<std::pair<uint64_t, uint64_t>> TemporalProfTimestamps;
345 bool ShouldSwapBytes;
346 // The value of the version field of the raw profile data header. The lower 32
347 // bits specifies the format version and the most significant 32 bits specify
348 // the variant types of the profile.
349 uint64_t Version;
350 uint64_t CountersDelta;
351 uint64_t BitmapDelta;
352 uint64_t UniformCountersDelta;
353 uint64_t NamesDelta;
356 const RawInstrProf::VTableProfileData<IntPtrT> *VTableBegin = nullptr;
357 const RawInstrProf::VTableProfileData<IntPtrT> *VTableEnd = nullptr;
358 const char *CountersStart;
359 const char *CountersEnd;
360 const char *BitmapStart;
361 const char *BitmapEnd;
362 const char *UniformCountersStart;
363 const char *UniformCountersEnd;
364 const char *NamesStart;
365 const char *NamesEnd;
366 const char *VNamesStart = nullptr;
367 const char *VNamesEnd = nullptr;
368 // After value profile is all read, this pointer points to
369 // the header of next profile data (if exists)
370 const uint8_t *ValueDataStart;
371 uint32_t ValueKindLast;
372 uint32_t CurValueDataSize;
373 std::vector<llvm::object::BuildID> BinaryIds;
374
375 std::function<void(Error)> Warn;
376
377 /// Maxium counter value 2^56.
378 static const uint64_t MaxCounterValue = (1ULL << 56);
379
380public:
382 std::unique_ptr<MemoryBuffer> DataBuffer,
383 const InstrProfCorrelator *Correlator,
384 const object::BuildIDFetcher *BIDFetcher,
385 const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind,
386 std::function<void(Error)> Warn)
387 : DataBuffer(std::move(DataBuffer)),
389 Correlator)),
390 BIDFetcher(BIDFetcher),
391 BIDFetcherCorrelatorKind(BIDFetcherCorrelatorKind), Warn(Warn) {}
392
395
396 static bool hasFormat(const MemoryBuffer &DataBuffer);
397 Error readHeader() override;
399 Error readBinaryIds(std::vector<llvm::object::BuildID> &BinaryIds) override;
401
402 uint64_t getVersion() const override { return Version; }
403
404 bool isIRLevelProfile() const override {
405 return (Version & VARIANT_MASK_IR_PROF) != 0;
406 }
407
408 bool hasCSIRLevelProfile() const override {
409 return (Version & VARIANT_MASK_CSIR_PROF) != 0;
410 }
411
412 bool instrEntryBBEnabled() const override {
413 return (Version & VARIANT_MASK_INSTR_ENTRY) != 0;
414 }
415
416 bool instrLoopEntriesEnabled() const override {
417 return (Version & VARIANT_MASK_INSTR_LOOP_ENTRIES) != 0;
418 }
419
420 bool hasSingleByteCoverage() const override {
421 return (Version & VARIANT_MASK_BYTE_COVERAGE) != 0;
422 }
423
424 bool functionEntryOnly() const override {
425 return (Version & VARIANT_MASK_FUNCTION_ENTRY_ONLY) != 0;
426 }
427
428 bool hasMemoryProfile() const override {
429 // Memory profiles have a separate raw format, so this should never be set.
430 assert(!(Version & VARIANT_MASK_MEMPROF));
431 return false;
432 }
433
434 bool hasTemporalProfile() const override {
435 return (Version & VARIANT_MASK_TEMPORAL_PROF) != 0;
436 }
437
438 /// Returns a BitsetEnum describing the attributes of the raw instr profile.
440
442 assert(Symtab.get());
443 return *Symtab.get();
444 }
445
447 getTemporalProfTraces(std::optional<uint64_t> Weight = {}) override;
448
449private:
450 Error createSymtab(InstrProfSymtab &Symtab);
451 Error readNextHeader(const char *CurrentPos);
453
454 template <class IntT> IntT swap(IntT Int) const {
455 return ShouldSwapBytes ? llvm::byteswap(Int) : Int;
456 }
457
458 llvm::endianness getDataEndianness() const {
459 if (!ShouldSwapBytes)
463 else
465 }
466
467 inline uint8_t getNumPaddingBytes(uint64_t SizeInBytes) {
468 return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t));
469 }
470
471 Error readName(NamedInstrProfRecord &Record);
472 Error readFuncHash(NamedInstrProfRecord &Record);
473 Error readRawCounts(InstrProfRecord &Record);
474 Error readRawBitmapBytes(InstrProfRecord &Record);
475 Error readRawUniformCounters(InstrProfRecord &Record);
476 Error readValueProfilingData(InstrProfRecord &Record);
477 bool atEnd() const { return Data == DataEnd; }
478
479 void advanceData() {
480 // `CountersDelta` and `BitmapDelta` are constant zero when using debug info
481 // correlation.
482 if (!Correlator && !BIDFetcherCorrelator) {
483 // The initial CountersDelta is the in-memory address difference between
484 // the data and counts sections:
485 // start(__llvm_prf_cnts) - start(__llvm_prf_data)
486 // As we advance to the next record, we maintain the correct CountersDelta
487 // with respect to the next record.
488 CountersDelta -= sizeof(*Data);
489 BitmapDelta -= sizeof(*Data);
490 UniformCountersDelta -= sizeof(*Data);
491 }
492 Data++;
493 ValueDataStart += CurValueDataSize;
494 }
495
496 const char *getNextHeaderPos() const {
497 assert(atEnd());
498 return (const char *)ValueDataStart;
499 }
500
501 StringRef getName(uint64_t NameRef) const {
502 return Symtab->getFuncOrVarName(swap(NameRef));
503 }
504
505 int getCounterTypeSize() const {
506 return hasSingleByteCoverage() ? sizeof(uint8_t) : sizeof(uint64_t);
507 }
508};
509
512
513namespace IndexedInstrProf {
514
515enum class HashT : uint32_t;
516
517} // end namespace IndexedInstrProf
518
519/// Trait for lookups into the on-disk hash table for the binary instrprof
520/// format.
522 std::vector<NamedInstrProfRecord> DataBuffer;
524 unsigned FormatVersion;
525 // Endianness of the input value profile data.
526 // It should be LE by default, but can be changed
527 // for testing purpose.
528 llvm::endianness ValueProfDataEndianness = llvm::endianness::little;
529
530public:
531 InstrProfLookupTrait(IndexedInstrProf::HashT HashType, unsigned FormatVersion)
532 : HashType(HashType), FormatVersion(FormatVersion) {}
533
535
540
541 static bool EqualKey(StringRef A, StringRef B) { return A == B; }
542 static StringRef GetInternalKey(StringRef K) { return K; }
543 static StringRef GetExternalKey(StringRef K) { return K; }
544
545 LLVM_ABI hash_value_type ComputeHash(StringRef K);
546
547 static std::pair<offset_type, offset_type>
548 ReadKeyDataLength(const unsigned char *&D) {
549 using namespace support;
550
551 offset_type KeyLen =
553 offset_type DataLen =
555 return std::make_pair(KeyLen, DataLen);
556 }
557
558 StringRef ReadKey(const unsigned char *D, offset_type N) {
559 return StringRef((const char *)D, N);
560 }
561
562 LLVM_ABI bool readValueProfilingData(const unsigned char *&D,
563 const unsigned char *const End);
564 LLVM_ABI data_type ReadData(StringRef K, const unsigned char *D,
565 offset_type N);
566
567 // Used for testing purpose only.
569 ValueProfDataEndianness = Endianness;
570 }
571};
572
574 virtual ~InstrProfReaderIndexBase() = default;
575
576 // Read all the profile records with the same key pointed to the current
577 // iterator.
579
580 // Read all the profile records with the key equal to FuncName
581 virtual Error getRecords(StringRef FuncName,
583 virtual void advanceToNextKey() = 0;
584 virtual bool atEnd() const = 0;
585 virtual void setValueProfDataEndianness(llvm::endianness Endianness) = 0;
586 virtual uint64_t getVersion() const = 0;
587 virtual bool isIRLevelProfile() const = 0;
588 virtual bool hasCSIRLevelProfile() const = 0;
589 virtual bool instrEntryBBEnabled() const = 0;
590 virtual bool instrLoopEntriesEnabled() const = 0;
591 virtual bool hasSingleByteCoverage() const = 0;
592 virtual bool functionEntryOnly() const = 0;
593 virtual bool hasMemoryProfile() const = 0;
594 virtual bool hasTemporalProfile() const = 0;
595 virtual InstrProfKind getProfileKind() const = 0;
597};
598
601
608
609template <typename HashTableImpl>
611
612template <typename HashTableImpl>
614private:
615 std::unique_ptr<HashTableImpl> HashTable;
616 typename HashTableImpl::data_iterator RecordIterator;
617 uint64_t FormatVersion;
618
619 friend class InstrProfReaderItaniumRemapper<HashTableImpl>;
620
621public:
622 InstrProfReaderIndex(const unsigned char *Buckets,
623 const unsigned char *const Payload,
624 const unsigned char *const Base,
626 ~InstrProfReaderIndex() override = default;
627
629 Error getRecords(StringRef FuncName,
631 void advanceToNextKey() override { RecordIterator++; }
632
633 bool atEnd() const override {
634 return RecordIterator == HashTable->data_end();
635 }
636
638 HashTable->getInfoObj().setValueProfDataEndianness(Endianness);
639 }
640
641 uint64_t getVersion() const override { return GET_VERSION(FormatVersion); }
642
643 bool isIRLevelProfile() const override {
644 return (FormatVersion & VARIANT_MASK_IR_PROF) != 0;
645 }
646
647 bool hasCSIRLevelProfile() const override {
648 return (FormatVersion & VARIANT_MASK_CSIR_PROF) != 0;
649 }
650
651 bool instrEntryBBEnabled() const override {
652 return (FormatVersion & VARIANT_MASK_INSTR_ENTRY) != 0;
653 }
654
655 bool instrLoopEntriesEnabled() const override {
656 return (FormatVersion & VARIANT_MASK_INSTR_LOOP_ENTRIES) != 0;
657 }
658
659 bool hasSingleByteCoverage() const override {
660 return (FormatVersion & VARIANT_MASK_BYTE_COVERAGE) != 0;
661 }
662
663 bool functionEntryOnly() const override {
664 return (FormatVersion & VARIANT_MASK_FUNCTION_ENTRY_ONLY) != 0;
665 }
666
667 bool hasMemoryProfile() const override {
668 return (FormatVersion & VARIANT_MASK_MEMPROF) != 0;
669 }
670
671 bool hasTemporalProfile() const override {
672 return (FormatVersion & VARIANT_MASK_TEMPORAL_PROF) != 0;
673 }
674
675 InstrProfKind getProfileKind() const override;
676
678 // FIXME: the create method calls 'finalizeSymtab' and sorts a bunch of
679 // arrays/maps. Since there are other data sources other than 'HashTable' to
680 // populate a symtab, it might make sense to have something like this
681 // 1. Let each data source populate Symtab and init the arrays/maps without
682 // calling 'finalizeSymtab'
683 // 2. Call 'finalizeSymtab' once to get all arrays/maps sorted if needed.
684 return Symtab.create(HashTable->keys());
685 }
686};
687
688/// Name matcher supporting fuzzy matching of symbol names to names in profiles.
690public:
691 virtual ~InstrProfReaderRemapper() = default;
693 virtual Error getRecords(StringRef FuncName,
695};
696
698private:
699 /// The MemProf version.
702 /// MemProf summary (if available, version >= 4).
703 std::unique_ptr<memprof::MemProfSummary> MemProfSum;
704 /// MemProf profile schema (if available).
706 /// MemProf record profile data on-disk indexed via llvm::md5(FunctionName).
707 std::unique_ptr<MemProfRecordHashTable> MemProfRecordTable;
708 /// MemProf frame profile data on-disk indexed via frame id.
709 std::unique_ptr<MemProfFrameHashTable> MemProfFrameTable;
710 /// MemProf call stack data on-disk indexed via call stack id.
711 std::unique_ptr<MemProfCallStackHashTable> MemProfCallStackTable;
712 /// The starting address of the frame array.
713 const unsigned char *FrameBase = nullptr;
714 /// The starting address of the call stack array.
715 const unsigned char *CallStackBase = nullptr;
716 // The number of elements in the radix tree array.
717 unsigned RadixTreeSize = 0;
718 /// The data access profiles, deserialized from binary data.
719 std::unique_ptr<memprof::DataAccessProfData> DataAccessProfileData;
720
721 Error deserializeV2(const unsigned char *Start, const unsigned char *Ptr);
722 Error deserializeRadixTreeBased(const unsigned char *Start,
723 const unsigned char *Ptr,
725
726public:
728
729 LLVM_ABI Error deserialize(const unsigned char *Start,
730 uint64_t MemProfOffset);
731
733 getMemProfRecord(const uint64_t FuncNameHash) const;
734
737
738 // Returns non-owned pointer to data access profile data.
740 return DataAccessProfileData.get();
741 }
742
743 // Return the entire MemProf profile.
745
746 memprof::MemProfSummary *getSummary() const { return MemProfSum.get(); }
747};
748
749/// Reader for the indexed binary instrprof format.
751private:
752 /// The profile data file contents.
753 std::unique_ptr<MemoryBuffer> DataBuffer;
754 /// The profile remapping file contents.
755 std::unique_ptr<MemoryBuffer> RemappingBuffer;
756 /// The index into the profile data.
757 std::unique_ptr<InstrProfReaderIndexBase> Index;
758 /// The profile remapping file contents.
759 std::unique_ptr<InstrProfReaderRemapper> Remapper;
760 /// Profile summary data.
761 std::unique_ptr<ProfileSummary> Summary;
762 /// Context sensitive profile summary data.
763 std::unique_ptr<ProfileSummary> CS_Summary;
764 IndexedMemProfReader MemProfReader;
765 /// The compressed vtable names, to be used for symtab construction.
766 /// A compiler that reads indexed profiles could construct symtab from module
767 /// IR so it doesn't need the decompressed names.
768 StringRef VTableName;
769 /// A memory buffer holding binary ids.
770 ArrayRef<uint8_t> BinaryIdsBuffer;
771
772 // Index to the current record in the record array.
773 unsigned RecordIndex = 0;
774
775 // Read the profile summary. Return a pointer pointing to one byte past the
776 // end of the summary data if it exists or the input \c Cur.
777 // \c UseCS indicates whether to use the context-sensitive profile summary.
778 const unsigned char *readSummary(IndexedInstrProf::ProfVersion Version,
779 const unsigned char *Cur, bool UseCS);
780
781public:
783 std::unique_ptr<MemoryBuffer> DataBuffer,
784 std::unique_ptr<MemoryBuffer> RemappingBuffer = nullptr)
785 : DataBuffer(std::move(DataBuffer)),
786 RemappingBuffer(std::move(RemappingBuffer)) {}
789
790 /// Return the profile version.
791 uint64_t getVersion() const override { return Index->getVersion(); }
792 bool isIRLevelProfile() const override { return Index->isIRLevelProfile(); }
793 bool hasCSIRLevelProfile() const override {
794 return Index->hasCSIRLevelProfile();
795 }
796
797 bool instrEntryBBEnabled() const override {
798 return Index->instrEntryBBEnabled();
799 }
800
801 bool instrLoopEntriesEnabled() const override {
802 return Index->instrLoopEntriesEnabled();
803 }
804
805 bool hasSingleByteCoverage() const override {
806 return Index->hasSingleByteCoverage();
807 }
808
809 bool functionEntryOnly() const override { return Index->functionEntryOnly(); }
810
811 bool hasMemoryProfile() const override { return Index->hasMemoryProfile(); }
812
813 bool hasTemporalProfile() const override {
814 return Index->hasTemporalProfile();
815 }
816
817 /// Returns a BitsetEnum describing the attributes of the indexed instr
818 /// profile.
819 InstrProfKind getProfileKind() const override {
820 return Index->getProfileKind();
821 }
822
823 /// Return true if the given buffer is in an indexed instrprof format.
824 static bool hasFormat(const MemoryBuffer &DataBuffer);
825
826 /// Read the file header.
827 Error readHeader() override;
828 /// Read a single record.
829 Error readNextRecord(NamedInstrProfRecord &Record) override;
830
831 /// Return the NamedInstrProfRecord associated with FuncName and FuncHash.
832 /// When return a hash_mismatch error and MismatchedFuncSum is not nullptr,
833 /// the sum of all counters in the mismatched function will be set to
834 /// MismatchedFuncSum. If there are multiple instances of mismatched
835 /// functions, MismatchedFuncSum returns the maximum. If \c FuncName is not
836 /// found, try to lookup \c DeprecatedFuncName to handle profiles built by
837 /// older compilers.
839 getInstrProfRecord(StringRef FuncName, uint64_t FuncHash,
840 StringRef DeprecatedFuncName = "",
841 uint64_t *MismatchedFuncSum = nullptr);
842
843 /// Return the memprof record for the function identified by
844 /// llvm::md5(Name).
846 return MemProfReader.getMemProfRecord(FuncNameHash);
847 }
848
851 return MemProfReader.getMemProfCallerCalleePairs();
852 }
853
855 return MemProfReader.getAllMemProfData();
856 }
857
858 /// Fill Counts with the profile data for the given function name.
859 Error getFunctionCounts(StringRef FuncName, uint64_t FuncHash,
860 std::vector<uint64_t> &Counts);
861
862 /// Fill Bitmap with the profile data for the given function name.
863 Error getFunctionBitmap(StringRef FuncName, uint64_t FuncHash,
864 BitVector &Bitmap);
865
866 /// Return the maximum of all known function counts.
867 /// \c UseCS indicates whether to use the context-sensitive count.
869 if (UseCS) {
870 assert(CS_Summary && "No context sensitive profile summary");
871 return CS_Summary->getMaxFunctionCount();
872 } else {
873 assert(Summary && "No profile summary");
874 return Summary->getMaxFunctionCount();
875 }
876 }
877
878 /// Factory method to create an indexed reader.
880 create(const Twine &Path, vfs::FileSystem &FS,
881 const Twine &RemappingPath = "");
882
884 create(std::unique_ptr<MemoryBuffer> Buffer,
885 std::unique_ptr<MemoryBuffer> RemappingBuffer = nullptr);
886
887 // Used for testing purpose only.
889 Index->setValueProfDataEndianness(Endianness);
890 }
891
892 // See description in the base class. This interface is designed
893 // to be used by llvm-profdata (for dumping). Avoid using this when
894 // the client is the compiler.
895 InstrProfSymtab &getSymtab() override;
896
897 /// Return the profile summary.
898 /// \c UseCS indicates whether to use the context-sensitive summary.
900 if (UseCS) {
901 assert(CS_Summary && "No context sensitive summary");
902 return *CS_Summary;
903 } else {
904 assert(Summary && "No profile summary");
905 return *Summary;
906 }
907 }
908
909 /// Return the MemProf summary. Will be null if unavailable (version < 4).
911 return MemProfReader.getSummary();
912 }
913
914 /// Returns non-owned pointer to the data access profile data.
915 /// Will be null if unavailable (version < 4).
917 return MemProfReader.getDataAccessProfileData();
918 }
919
920 Error readBinaryIds(std::vector<llvm::object::BuildID> &BinaryIds) override;
921 Error printBinaryIds(raw_ostream &OS) override;
922};
923
924} // end namespace llvm
925
926#endif // LLVM_PROFILEDATA_INSTRPROFREADER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
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)
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:482
const std::string & getMessage() const
Definition InstrProf.h:477
instrprof_error get() const
Definition InstrProf.h:476
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:517
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:40
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:81
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:1917
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:860
#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:906