File indexing completed on 2026-05-10 08:44:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_PROFILEDATA_INSTRPROFREADER_H
0015 #define LLVM_PROFILEDATA_INSTRPROFREADER_H
0016
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/IR/ProfileSummary.h"
0020 #include "llvm/Object/BuildID.h"
0021 #include "llvm/ProfileData/InstrProf.h"
0022 #include "llvm/ProfileData/InstrProfCorrelator.h"
0023 #include "llvm/ProfileData/MemProf.h"
0024 #include "llvm/ProfileData/MemProfYAML.h"
0025 #include "llvm/Support/Endian.h"
0026 #include "llvm/Support/Error.h"
0027 #include "llvm/Support/LineIterator.h"
0028 #include "llvm/Support/MathExtras.h"
0029 #include "llvm/Support/MemoryBuffer.h"
0030 #include "llvm/Support/OnDiskHashTable.h"
0031 #include "llvm/Support/SwapByteOrder.h"
0032 #include <algorithm>
0033 #include <cassert>
0034 #include <cstddef>
0035 #include <cstdint>
0036 #include <iterator>
0037 #include <memory>
0038 #include <utility>
0039 #include <vector>
0040
0041 namespace llvm {
0042
0043 class InstrProfReader;
0044
0045 namespace vfs {
0046 class FileSystem;
0047 }
0048
0049
0050 template <class record_type = NamedInstrProfRecord,
0051 class reader_type = InstrProfReader>
0052 class InstrProfIterator {
0053 public:
0054 using iterator_category = std::input_iterator_tag;
0055 using value_type = record_type;
0056 using difference_type = std::ptrdiff_t;
0057 using pointer = value_type *;
0058 using reference = value_type &;
0059
0060 private:
0061 reader_type *Reader = nullptr;
0062 value_type Record;
0063
0064 void increment() {
0065 if (Error E = Reader->readNextRecord(Record)) {
0066
0067 InstrProfError::take(std::move(E));
0068 *this = InstrProfIterator();
0069 }
0070 }
0071
0072 public:
0073 InstrProfIterator() = default;
0074 InstrProfIterator(reader_type *Reader) : Reader(Reader) { increment(); }
0075
0076 InstrProfIterator &operator++() {
0077 increment();
0078 return *this;
0079 }
0080 bool operator==(const InstrProfIterator &RHS) const {
0081 return Reader == RHS.Reader;
0082 }
0083 bool operator!=(const InstrProfIterator &RHS) const {
0084 return Reader != RHS.Reader;
0085 }
0086 value_type &operator*() { return Record; }
0087 value_type *operator->() { return &Record; }
0088 };
0089
0090
0091
0092 class InstrProfReader {
0093 instrprof_error LastError = instrprof_error::success;
0094 std::string LastErrorMsg;
0095
0096 public:
0097 InstrProfReader() = default;
0098 virtual ~InstrProfReader() = default;
0099
0100
0101 virtual Error readHeader() = 0;
0102
0103
0104 virtual Error readNextRecord(NamedInstrProfRecord &Record) = 0;
0105
0106
0107 virtual Error readBinaryIds(std::vector<llvm::object::BuildID> &BinaryIds) {
0108 return success();
0109 }
0110
0111
0112 virtual Error printBinaryIds(raw_ostream &OS) { return success(); };
0113
0114
0115 InstrProfIterator<> begin() { return InstrProfIterator<>(this); }
0116 InstrProfIterator<> end() { return InstrProfIterator<>(); }
0117
0118
0119 virtual uint64_t getVersion() const = 0;
0120
0121 virtual bool isIRLevelProfile() const = 0;
0122
0123 virtual bool hasCSIRLevelProfile() const = 0;
0124
0125 virtual bool instrEntryBBEnabled() const = 0;
0126
0127
0128 virtual bool instrLoopEntriesEnabled() const = 0;
0129
0130
0131 virtual bool hasSingleByteCoverage() const = 0;
0132
0133
0134 virtual bool functionEntryOnly() const = 0;
0135
0136
0137 virtual bool hasMemoryProfile() const = 0;
0138
0139
0140 virtual bool hasTemporalProfile() const = 0;
0141
0142
0143
0144 virtual InstrProfKind getProfileKind() const = 0;
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 virtual InstrProfSymtab &getSymtab() = 0;
0157
0158
0159 void accumulateCounts(CountSumOrPercent &Sum, bool IsCS);
0160
0161 protected:
0162 std::unique_ptr<InstrProfSymtab> Symtab;
0163
0164 SmallVector<TemporalProfTraceTy> TemporalProfTraces;
0165
0166 uint64_t TemporalProfTraceStreamSize = 0;
0167
0168
0169 Error error(instrprof_error Err, const std::string &ErrMsg = "") {
0170 LastError = Err;
0171 LastErrorMsg = ErrMsg;
0172 if (Err == instrprof_error::success)
0173 return Error::success();
0174 return make_error<InstrProfError>(Err, ErrMsg);
0175 }
0176
0177 Error error(Error &&E) {
0178 handleAllErrors(std::move(E), [&](const InstrProfError &IPE) {
0179 LastError = IPE.get();
0180 LastErrorMsg = IPE.getMessage();
0181 });
0182 return make_error<InstrProfError>(LastError, LastErrorMsg);
0183 }
0184
0185
0186 Error success() { return error(instrprof_error::success); }
0187
0188 public:
0189
0190 bool isEOF() { return LastError == instrprof_error::eof; }
0191
0192
0193 bool hasError() { return LastError != instrprof_error::success && !isEOF(); }
0194
0195
0196 Error getError() {
0197 if (hasError())
0198 return make_error<InstrProfError>(LastError, LastErrorMsg);
0199 return Error::success();
0200 }
0201
0202
0203
0204 static Expected<std::unique_ptr<InstrProfReader>> create(
0205 const Twine &Path, vfs::FileSystem &FS,
0206 const InstrProfCorrelator *Correlator = nullptr,
0207 const object::BuildIDFetcher *BIDFetcher = nullptr,
0208 const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind =
0209 InstrProfCorrelator::ProfCorrelatorKind::NONE,
0210 std::function<void(Error)> Warn = nullptr);
0211
0212 static Expected<std::unique_ptr<InstrProfReader>> create(
0213 std::unique_ptr<MemoryBuffer> Buffer,
0214 const InstrProfCorrelator *Correlator = nullptr,
0215 const object::BuildIDFetcher *BIDFetcher = nullptr,
0216 const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind =
0217 InstrProfCorrelator::ProfCorrelatorKind::NONE,
0218 std::function<void(Error)> Warn = nullptr);
0219
0220
0221
0222
0223 virtual SmallVector<TemporalProfTraceTy> &
0224 getTemporalProfTraces(std::optional<uint64_t> Weight = {}) {
0225
0226
0227 return TemporalProfTraces;
0228 }
0229
0230 uint64_t getTemporalProfTraceStreamSize() {
0231 return TemporalProfTraceStreamSize;
0232 }
0233 };
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243 class TextInstrProfReader : public InstrProfReader {
0244 private:
0245
0246 std::unique_ptr<MemoryBuffer> DataBuffer;
0247
0248 line_iterator Line;
0249
0250 InstrProfKind ProfileKind = InstrProfKind::Unknown;
0251
0252 Error readValueProfileData(InstrProfRecord &Record);
0253
0254 Error readTemporalProfTraceData();
0255
0256 public:
0257 TextInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer_)
0258 : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#') {}
0259 TextInstrProfReader(const TextInstrProfReader &) = delete;
0260 TextInstrProfReader &operator=(const TextInstrProfReader &) = delete;
0261
0262
0263 static bool hasFormat(const MemoryBuffer &Buffer);
0264
0265
0266 uint64_t getVersion() const override { return 0; }
0267
0268 bool isIRLevelProfile() const override {
0269 return static_cast<bool>(ProfileKind & InstrProfKind::IRInstrumentation);
0270 }
0271
0272 bool hasCSIRLevelProfile() const override {
0273 return static_cast<bool>(ProfileKind & InstrProfKind::ContextSensitive);
0274 }
0275
0276 bool instrEntryBBEnabled() const override {
0277 return static_cast<bool>(ProfileKind &
0278 InstrProfKind::FunctionEntryInstrumentation);
0279 }
0280
0281 bool instrLoopEntriesEnabled() const override {
0282 return static_cast<bool>(ProfileKind &
0283 InstrProfKind::LoopEntriesInstrumentation);
0284 }
0285
0286 bool hasSingleByteCoverage() const override {
0287 return static_cast<bool>(ProfileKind & InstrProfKind::SingleByteCoverage);
0288 }
0289
0290 bool functionEntryOnly() const override {
0291 return static_cast<bool>(ProfileKind & InstrProfKind::FunctionEntryOnly);
0292 }
0293
0294 bool hasMemoryProfile() const override {
0295
0296 return false;
0297 }
0298
0299 bool hasTemporalProfile() const override {
0300 return static_cast<bool>(ProfileKind & InstrProfKind::TemporalProfile);
0301 }
0302
0303 InstrProfKind getProfileKind() const override { return ProfileKind; }
0304
0305
0306 Error readHeader() override;
0307
0308
0309 Error readNextRecord(NamedInstrProfRecord &Record) override;
0310
0311 InstrProfSymtab &getSymtab() override {
0312 assert(Symtab);
0313 return *Symtab;
0314 }
0315 };
0316
0317
0318
0319
0320
0321
0322
0323
0324 template <class IntPtrT>
0325 class RawInstrProfReader : public InstrProfReader {
0326 private:
0327
0328 std::unique_ptr<MemoryBuffer> DataBuffer;
0329
0330
0331 const InstrProfCorrelatorImpl<IntPtrT> *Correlator;
0332
0333 const object::BuildIDFetcher *BIDFetcher;
0334
0335
0336 std::unique_ptr<InstrProfCorrelator> BIDFetcherCorrelator;
0337
0338
0339 InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind;
0340
0341 std::vector<std::pair<uint64_t, uint64_t>> TemporalProfTimestamps;
0342 bool ShouldSwapBytes;
0343
0344
0345
0346 uint64_t Version;
0347 uint64_t CountersDelta;
0348 uint64_t BitmapDelta;
0349 uint64_t NamesDelta;
0350 const RawInstrProf::ProfileData<IntPtrT> *Data;
0351 const RawInstrProf::ProfileData<IntPtrT> *DataEnd;
0352 const RawInstrProf::VTableProfileData<IntPtrT> *VTableBegin = nullptr;
0353 const RawInstrProf::VTableProfileData<IntPtrT> *VTableEnd = nullptr;
0354 const char *CountersStart;
0355 const char *CountersEnd;
0356 const char *BitmapStart;
0357 const char *BitmapEnd;
0358 const char *NamesStart;
0359 const char *NamesEnd;
0360 const char *VNamesStart = nullptr;
0361 const char *VNamesEnd = nullptr;
0362
0363
0364 const uint8_t *ValueDataStart;
0365 uint32_t ValueKindLast;
0366 uint32_t CurValueDataSize;
0367 std::vector<llvm::object::BuildID> BinaryIds;
0368
0369 std::function<void(Error)> Warn;
0370
0371
0372 static const uint64_t MaxCounterValue = (1ULL << 56);
0373
0374 public:
0375 RawInstrProfReader(
0376 std::unique_ptr<MemoryBuffer> DataBuffer,
0377 const InstrProfCorrelator *Correlator,
0378 const object::BuildIDFetcher *BIDFetcher,
0379 const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind,
0380 std::function<void(Error)> Warn)
0381 : DataBuffer(std::move(DataBuffer)),
0382 Correlator(dyn_cast_or_null<const InstrProfCorrelatorImpl<IntPtrT>>(
0383 Correlator)),
0384 BIDFetcher(BIDFetcher),
0385 BIDFetcherCorrelatorKind(BIDFetcherCorrelatorKind), Warn(Warn) {}
0386
0387 RawInstrProfReader(const RawInstrProfReader &) = delete;
0388 RawInstrProfReader &operator=(const RawInstrProfReader &) = delete;
0389
0390 static bool hasFormat(const MemoryBuffer &DataBuffer);
0391 Error readHeader() override;
0392 Error readNextRecord(NamedInstrProfRecord &Record) override;
0393 Error readBinaryIds(std::vector<llvm::object::BuildID> &BinaryIds) override;
0394 Error printBinaryIds(raw_ostream &OS) override;
0395
0396 uint64_t getVersion() const override { return Version; }
0397
0398 bool isIRLevelProfile() const override {
0399 return (Version & VARIANT_MASK_IR_PROF) != 0;
0400 }
0401
0402 bool hasCSIRLevelProfile() const override {
0403 return (Version & VARIANT_MASK_CSIR_PROF) != 0;
0404 }
0405
0406 bool instrEntryBBEnabled() const override {
0407 return (Version & VARIANT_MASK_INSTR_ENTRY) != 0;
0408 }
0409
0410 bool instrLoopEntriesEnabled() const override {
0411 return (Version & VARIANT_MASK_INSTR_LOOP_ENTRIES) != 0;
0412 }
0413
0414 bool hasSingleByteCoverage() const override {
0415 return (Version & VARIANT_MASK_BYTE_COVERAGE) != 0;
0416 }
0417
0418 bool functionEntryOnly() const override {
0419 return (Version & VARIANT_MASK_FUNCTION_ENTRY_ONLY) != 0;
0420 }
0421
0422 bool hasMemoryProfile() const override {
0423
0424 assert(!(Version & VARIANT_MASK_MEMPROF));
0425 return false;
0426 }
0427
0428 bool hasTemporalProfile() const override {
0429 return (Version & VARIANT_MASK_TEMPORAL_PROF) != 0;
0430 }
0431
0432
0433 InstrProfKind getProfileKind() const override;
0434
0435 InstrProfSymtab &getSymtab() override {
0436 assert(Symtab.get());
0437 return *Symtab.get();
0438 }
0439
0440 SmallVector<TemporalProfTraceTy> &
0441 getTemporalProfTraces(std::optional<uint64_t> Weight = {}) override;
0442
0443 private:
0444 Error createSymtab(InstrProfSymtab &Symtab);
0445 Error readNextHeader(const char *CurrentPos);
0446 Error readHeader(const RawInstrProf::Header &Header);
0447
0448 template <class IntT> IntT swap(IntT Int) const {
0449 return ShouldSwapBytes ? llvm::byteswap(Int) : Int;
0450 }
0451
0452 llvm::endianness getDataEndianness() const {
0453 if (!ShouldSwapBytes)
0454 return llvm::endianness::native;
0455 if (llvm::endianness::native == llvm::endianness::little)
0456 return llvm::endianness::big;
0457 else
0458 return llvm::endianness::little;
0459 }
0460
0461 inline uint8_t getNumPaddingBytes(uint64_t SizeInBytes) {
0462 return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t));
0463 }
0464
0465 Error readName(NamedInstrProfRecord &Record);
0466 Error readFuncHash(NamedInstrProfRecord &Record);
0467 Error readRawCounts(InstrProfRecord &Record);
0468 Error readRawBitmapBytes(InstrProfRecord &Record);
0469 Error readValueProfilingData(InstrProfRecord &Record);
0470 bool atEnd() const { return Data == DataEnd; }
0471
0472 void advanceData() {
0473
0474 if (!Correlator && !BIDFetcherCorrelator) {
0475
0476
0477
0478
0479
0480 CountersDelta -= sizeof(*Data);
0481 BitmapDelta -= sizeof(*Data);
0482 }
0483 Data++;
0484 ValueDataStart += CurValueDataSize;
0485 }
0486
0487 const char *getNextHeaderPos() const {
0488 assert(atEnd());
0489 return (const char *)ValueDataStart;
0490 }
0491
0492 StringRef getName(uint64_t NameRef) const {
0493 return Symtab->getFuncOrVarName(swap(NameRef));
0494 }
0495
0496 int getCounterTypeSize() const {
0497 return hasSingleByteCoverage() ? sizeof(uint8_t) : sizeof(uint64_t);
0498 }
0499 };
0500
0501 using RawInstrProfReader32 = RawInstrProfReader<uint32_t>;
0502 using RawInstrProfReader64 = RawInstrProfReader<uint64_t>;
0503
0504 namespace IndexedInstrProf {
0505
0506 enum class HashT : uint32_t;
0507
0508 }
0509
0510
0511
0512 class InstrProfLookupTrait {
0513 std::vector<NamedInstrProfRecord> DataBuffer;
0514 IndexedInstrProf::HashT HashType;
0515 unsigned FormatVersion;
0516
0517
0518
0519 llvm::endianness ValueProfDataEndianness = llvm::endianness::little;
0520
0521 public:
0522 InstrProfLookupTrait(IndexedInstrProf::HashT HashType, unsigned FormatVersion)
0523 : HashType(HashType), FormatVersion(FormatVersion) {}
0524
0525 using data_type = ArrayRef<NamedInstrProfRecord>;
0526
0527 using internal_key_type = StringRef;
0528 using external_key_type = StringRef;
0529 using hash_value_type = uint64_t;
0530 using offset_type = uint64_t;
0531
0532 static bool EqualKey(StringRef A, StringRef B) { return A == B; }
0533 static StringRef GetInternalKey(StringRef K) { return K; }
0534 static StringRef GetExternalKey(StringRef K) { return K; }
0535
0536 hash_value_type ComputeHash(StringRef K);
0537
0538 static std::pair<offset_type, offset_type>
0539 ReadKeyDataLength(const unsigned char *&D) {
0540 using namespace support;
0541
0542 offset_type KeyLen =
0543 endian::readNext<offset_type, llvm::endianness::little>(D);
0544 offset_type DataLen =
0545 endian::readNext<offset_type, llvm::endianness::little>(D);
0546 return std::make_pair(KeyLen, DataLen);
0547 }
0548
0549 StringRef ReadKey(const unsigned char *D, offset_type N) {
0550 return StringRef((const char *)D, N);
0551 }
0552
0553 bool readValueProfilingData(const unsigned char *&D,
0554 const unsigned char *const End);
0555 data_type ReadData(StringRef K, const unsigned char *D, offset_type N);
0556
0557
0558 void setValueProfDataEndianness(llvm::endianness Endianness) {
0559 ValueProfDataEndianness = Endianness;
0560 }
0561 };
0562
0563 struct InstrProfReaderIndexBase {
0564 virtual ~InstrProfReaderIndexBase() = default;
0565
0566
0567
0568 virtual Error getRecords(ArrayRef<NamedInstrProfRecord> &Data) = 0;
0569
0570
0571 virtual Error getRecords(StringRef FuncName,
0572 ArrayRef<NamedInstrProfRecord> &Data) = 0;
0573 virtual void advanceToNextKey() = 0;
0574 virtual bool atEnd() const = 0;
0575 virtual void setValueProfDataEndianness(llvm::endianness Endianness) = 0;
0576 virtual uint64_t getVersion() const = 0;
0577 virtual bool isIRLevelProfile() const = 0;
0578 virtual bool hasCSIRLevelProfile() const = 0;
0579 virtual bool instrEntryBBEnabled() const = 0;
0580 virtual bool instrLoopEntriesEnabled() const = 0;
0581 virtual bool hasSingleByteCoverage() const = 0;
0582 virtual bool functionEntryOnly() const = 0;
0583 virtual bool hasMemoryProfile() const = 0;
0584 virtual bool hasTemporalProfile() const = 0;
0585 virtual InstrProfKind getProfileKind() const = 0;
0586 virtual Error populateSymtab(InstrProfSymtab &) = 0;
0587 };
0588
0589 using OnDiskHashTableImplV3 =
0590 OnDiskIterableChainedHashTable<InstrProfLookupTrait>;
0591
0592 using MemProfRecordHashTable =
0593 OnDiskIterableChainedHashTable<memprof::RecordLookupTrait>;
0594 using MemProfFrameHashTable =
0595 OnDiskIterableChainedHashTable<memprof::FrameLookupTrait>;
0596 using MemProfCallStackHashTable =
0597 OnDiskIterableChainedHashTable<memprof::CallStackLookupTrait>;
0598
0599 template <typename HashTableImpl>
0600 class InstrProfReaderItaniumRemapper;
0601
0602 template <typename HashTableImpl>
0603 class InstrProfReaderIndex : public InstrProfReaderIndexBase {
0604 private:
0605 std::unique_ptr<HashTableImpl> HashTable;
0606 typename HashTableImpl::data_iterator RecordIterator;
0607 uint64_t FormatVersion;
0608
0609 friend class InstrProfReaderItaniumRemapper<HashTableImpl>;
0610
0611 public:
0612 InstrProfReaderIndex(const unsigned char *Buckets,
0613 const unsigned char *const Payload,
0614 const unsigned char *const Base,
0615 IndexedInstrProf::HashT HashType, uint64_t Version);
0616 ~InstrProfReaderIndex() override = default;
0617
0618 Error getRecords(ArrayRef<NamedInstrProfRecord> &Data) override;
0619 Error getRecords(StringRef FuncName,
0620 ArrayRef<NamedInstrProfRecord> &Data) override;
0621 void advanceToNextKey() override { RecordIterator++; }
0622
0623 bool atEnd() const override {
0624 return RecordIterator == HashTable->data_end();
0625 }
0626
0627 void setValueProfDataEndianness(llvm::endianness Endianness) override {
0628 HashTable->getInfoObj().setValueProfDataEndianness(Endianness);
0629 }
0630
0631 uint64_t getVersion() const override { return GET_VERSION(FormatVersion); }
0632
0633 bool isIRLevelProfile() const override {
0634 return (FormatVersion & VARIANT_MASK_IR_PROF) != 0;
0635 }
0636
0637 bool hasCSIRLevelProfile() const override {
0638 return (FormatVersion & VARIANT_MASK_CSIR_PROF) != 0;
0639 }
0640
0641 bool instrEntryBBEnabled() const override {
0642 return (FormatVersion & VARIANT_MASK_INSTR_ENTRY) != 0;
0643 }
0644
0645 bool instrLoopEntriesEnabled() const override {
0646 return (FormatVersion & VARIANT_MASK_INSTR_LOOP_ENTRIES) != 0;
0647 }
0648
0649 bool hasSingleByteCoverage() const override {
0650 return (FormatVersion & VARIANT_MASK_BYTE_COVERAGE) != 0;
0651 }
0652
0653 bool functionEntryOnly() const override {
0654 return (FormatVersion & VARIANT_MASK_FUNCTION_ENTRY_ONLY) != 0;
0655 }
0656
0657 bool hasMemoryProfile() const override {
0658 return (FormatVersion & VARIANT_MASK_MEMPROF) != 0;
0659 }
0660
0661 bool hasTemporalProfile() const override {
0662 return (FormatVersion & VARIANT_MASK_TEMPORAL_PROF) != 0;
0663 }
0664
0665 InstrProfKind getProfileKind() const override;
0666
0667 Error populateSymtab(InstrProfSymtab &Symtab) override {
0668
0669
0670
0671
0672
0673
0674 return Symtab.create(HashTable->keys());
0675 }
0676 };
0677
0678
0679 class InstrProfReaderRemapper {
0680 public:
0681 virtual ~InstrProfReaderRemapper() = default;
0682 virtual Error populateRemappings() { return Error::success(); }
0683 virtual Error getRecords(StringRef FuncName,
0684 ArrayRef<NamedInstrProfRecord> &Data) = 0;
0685 };
0686
0687 class IndexedMemProfReader {
0688 private:
0689
0690 memprof::IndexedVersion Version =
0691 static_cast<memprof::IndexedVersion>(memprof::MinimumSupportedVersion);
0692
0693 memprof::MemProfSchema Schema;
0694
0695 std::unique_ptr<MemProfRecordHashTable> MemProfRecordTable;
0696
0697 std::unique_ptr<MemProfFrameHashTable> MemProfFrameTable;
0698
0699 std::unique_ptr<MemProfCallStackHashTable> MemProfCallStackTable;
0700
0701 const unsigned char *FrameBase = nullptr;
0702
0703 const unsigned char *CallStackBase = nullptr;
0704
0705 unsigned RadixTreeSize = 0;
0706
0707 Error deserializeV2(const unsigned char *Start, const unsigned char *Ptr);
0708 Error deserializeV3(const unsigned char *Start, const unsigned char *Ptr);
0709
0710 public:
0711 IndexedMemProfReader() = default;
0712
0713 Error deserialize(const unsigned char *Start, uint64_t MemProfOffset);
0714
0715 Expected<memprof::MemProfRecord>
0716 getMemProfRecord(const uint64_t FuncNameHash) const;
0717
0718 DenseMap<uint64_t, SmallVector<memprof::CallEdgeTy, 0>>
0719 getMemProfCallerCalleePairs() const;
0720
0721
0722 memprof::AllMemProfData getAllMemProfData() const;
0723 };
0724
0725
0726 class IndexedInstrProfReader : public InstrProfReader {
0727 private:
0728
0729 std::unique_ptr<MemoryBuffer> DataBuffer;
0730
0731 std::unique_ptr<MemoryBuffer> RemappingBuffer;
0732
0733 std::unique_ptr<InstrProfReaderIndexBase> Index;
0734
0735 std::unique_ptr<InstrProfReaderRemapper> Remapper;
0736
0737 std::unique_ptr<ProfileSummary> Summary;
0738
0739 std::unique_ptr<ProfileSummary> CS_Summary;
0740 IndexedMemProfReader MemProfReader;
0741
0742
0743
0744 StringRef VTableName;
0745
0746 ArrayRef<uint8_t> BinaryIdsBuffer;
0747
0748
0749 unsigned RecordIndex = 0;
0750
0751
0752
0753
0754 const unsigned char *readSummary(IndexedInstrProf::ProfVersion Version,
0755 const unsigned char *Cur, bool UseCS);
0756
0757 public:
0758 IndexedInstrProfReader(
0759 std::unique_ptr<MemoryBuffer> DataBuffer,
0760 std::unique_ptr<MemoryBuffer> RemappingBuffer = nullptr)
0761 : DataBuffer(std::move(DataBuffer)),
0762 RemappingBuffer(std::move(RemappingBuffer)) {}
0763 IndexedInstrProfReader(const IndexedInstrProfReader &) = delete;
0764 IndexedInstrProfReader &operator=(const IndexedInstrProfReader &) = delete;
0765
0766
0767 uint64_t getVersion() const override { return Index->getVersion(); }
0768 bool isIRLevelProfile() const override { return Index->isIRLevelProfile(); }
0769 bool hasCSIRLevelProfile() const override {
0770 return Index->hasCSIRLevelProfile();
0771 }
0772
0773 bool instrEntryBBEnabled() const override {
0774 return Index->instrEntryBBEnabled();
0775 }
0776
0777 bool instrLoopEntriesEnabled() const override {
0778 return Index->instrLoopEntriesEnabled();
0779 }
0780
0781 bool hasSingleByteCoverage() const override {
0782 return Index->hasSingleByteCoverage();
0783 }
0784
0785 bool functionEntryOnly() const override { return Index->functionEntryOnly(); }
0786
0787 bool hasMemoryProfile() const override { return Index->hasMemoryProfile(); }
0788
0789 bool hasTemporalProfile() const override {
0790 return Index->hasTemporalProfile();
0791 }
0792
0793
0794
0795 InstrProfKind getProfileKind() const override {
0796 return Index->getProfileKind();
0797 }
0798
0799
0800 static bool hasFormat(const MemoryBuffer &DataBuffer);
0801
0802
0803 Error readHeader() override;
0804
0805 Error readNextRecord(NamedInstrProfRecord &Record) override;
0806
0807
0808
0809
0810
0811
0812
0813
0814 Expected<InstrProfRecord>
0815 getInstrProfRecord(StringRef FuncName, uint64_t FuncHash,
0816 StringRef DeprecatedFuncName = "",
0817 uint64_t *MismatchedFuncSum = nullptr);
0818
0819
0820
0821 Expected<memprof::MemProfRecord> getMemProfRecord(uint64_t FuncNameHash) {
0822 return MemProfReader.getMemProfRecord(FuncNameHash);
0823 }
0824
0825 DenseMap<uint64_t, SmallVector<memprof::CallEdgeTy, 0>>
0826 getMemProfCallerCalleePairs() {
0827 return MemProfReader.getMemProfCallerCalleePairs();
0828 }
0829
0830 memprof::AllMemProfData getAllMemProfData() const {
0831 return MemProfReader.getAllMemProfData();
0832 }
0833
0834
0835 Error getFunctionCounts(StringRef FuncName, uint64_t FuncHash,
0836 std::vector<uint64_t> &Counts);
0837
0838
0839 Error getFunctionBitmap(StringRef FuncName, uint64_t FuncHash,
0840 BitVector &Bitmap);
0841
0842
0843
0844 uint64_t getMaximumFunctionCount(bool UseCS) {
0845 if (UseCS) {
0846 assert(CS_Summary && "No context sensitive profile summary");
0847 return CS_Summary->getMaxFunctionCount();
0848 } else {
0849 assert(Summary && "No profile summary");
0850 return Summary->getMaxFunctionCount();
0851 }
0852 }
0853
0854
0855 static Expected<std::unique_ptr<IndexedInstrProfReader>>
0856 create(const Twine &Path, vfs::FileSystem &FS,
0857 const Twine &RemappingPath = "");
0858
0859 static Expected<std::unique_ptr<IndexedInstrProfReader>>
0860 create(std::unique_ptr<MemoryBuffer> Buffer,
0861 std::unique_ptr<MemoryBuffer> RemappingBuffer = nullptr);
0862
0863
0864 void setValueProfDataEndianness(llvm::endianness Endianness) {
0865 Index->setValueProfDataEndianness(Endianness);
0866 }
0867
0868
0869
0870
0871 InstrProfSymtab &getSymtab() override;
0872
0873
0874
0875 ProfileSummary &getSummary(bool UseCS) {
0876 if (UseCS) {
0877 assert(CS_Summary && "No context sensitive summary");
0878 return *CS_Summary;
0879 } else {
0880 assert(Summary && "No profile summary");
0881 return *Summary;
0882 }
0883 }
0884
0885 Error readBinaryIds(std::vector<llvm::object::BuildID> &BinaryIds) override;
0886 Error printBinaryIds(raw_ostream &OS) override;
0887 };
0888
0889 }
0890
0891 #endif