InstrProfReader.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- InstrProfReader.h - Instrumented profiling readers -------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file contains support for reading profiling data for instrumentation
  15. // based PGO and coverage.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_PROFILEDATA_INSTRPROFREADER_H
  19. #define LLVM_PROFILEDATA_INSTRPROFREADER_H
  20. #include "llvm/ADT/ArrayRef.h"
  21. #include "llvm/ADT/StringRef.h"
  22. #include "llvm/IR/ProfileSummary.h"
  23. #include "llvm/ProfileData/InstrProf.h"
  24. #include "llvm/ProfileData/InstrProfCorrelator.h"
  25. #include "llvm/Support/Endian.h"
  26. #include "llvm/Support/Error.h"
  27. #include "llvm/Support/LineIterator.h"
  28. #include "llvm/Support/MemoryBuffer.h"
  29. #include "llvm/Support/OnDiskHashTable.h"
  30. #include "llvm/Support/SwapByteOrder.h"
  31. #include <algorithm>
  32. #include <cassert>
  33. #include <cstddef>
  34. #include <cstdint>
  35. #include <iterator>
  36. #include <memory>
  37. #include <utility>
  38. #include <vector>
  39. namespace llvm {
  40. class InstrProfReader;
  41. /// A file format agnostic iterator over profiling data.
  42. class InstrProfIterator {
  43. public:
  44. using iterator_category = std::input_iterator_tag;
  45. using value_type = NamedInstrProfRecord;
  46. using difference_type = std::ptrdiff_t;
  47. using pointer = value_type *;
  48. using reference = value_type &;
  49. private:
  50. InstrProfReader *Reader = nullptr;
  51. value_type Record;
  52. void Increment();
  53. public:
  54. InstrProfIterator() = default;
  55. InstrProfIterator(InstrProfReader *Reader) : Reader(Reader) { Increment(); }
  56. InstrProfIterator &operator++() { Increment(); return *this; }
  57. bool operator==(const InstrProfIterator &RHS) const {
  58. return Reader == RHS.Reader;
  59. }
  60. bool operator!=(const InstrProfIterator &RHS) const {
  61. return Reader != RHS.Reader;
  62. }
  63. value_type &operator*() { return Record; }
  64. value_type *operator->() { return &Record; }
  65. };
  66. /// Base class and interface for reading profiling data of any known instrprof
  67. /// format. Provides an iterator over NamedInstrProfRecords.
  68. class InstrProfReader {
  69. instrprof_error LastError = instrprof_error::success;
  70. std::string LastErrorMsg;
  71. public:
  72. InstrProfReader() = default;
  73. virtual ~InstrProfReader() = default;
  74. /// Read the header. Required before reading first record.
  75. virtual Error readHeader() = 0;
  76. /// Read a single record.
  77. virtual Error readNextRecord(NamedInstrProfRecord &Record) = 0;
  78. /// Print binary ids on stream OS.
  79. virtual Error printBinaryIds(raw_ostream &OS) { return success(); };
  80. /// Iterator over profile data.
  81. InstrProfIterator begin() { return InstrProfIterator(this); }
  82. InstrProfIterator end() { return InstrProfIterator(); }
  83. virtual bool isIRLevelProfile() const = 0;
  84. virtual bool hasCSIRLevelProfile() const = 0;
  85. virtual bool instrEntryBBEnabled() const = 0;
  86. /// Return true if we must provide debug info to create PGO profiles.
  87. virtual bool useDebugInfoCorrelate() const { return false; }
  88. /// Return true if the profile has single byte counters representing coverage.
  89. virtual bool hasSingleByteCoverage() const = 0;
  90. /// Return true if the profile only instruments function entries.
  91. virtual bool functionEntryOnly() const = 0;
  92. /// Returns a BitsetEnum describing the attributes of the profile. To check
  93. /// individual attributes prefer using the helpers above.
  94. virtual InstrProfKind getProfileKind() const = 0;
  95. /// Return the PGO symtab. There are three different readers:
  96. /// Raw, Text, and Indexed profile readers. The first two types
  97. /// of readers are used only by llvm-profdata tool, while the indexed
  98. /// profile reader is also used by llvm-cov tool and the compiler (
  99. /// backend or frontend). Since creating PGO symtab can create
  100. /// significant runtime and memory overhead (as it touches data
  101. /// for the whole program), InstrProfSymtab for the indexed profile
  102. /// reader should be created on demand and it is recommended to be
  103. /// only used for dumping purpose with llvm-proftool, not with the
  104. /// compiler.
  105. virtual InstrProfSymtab &getSymtab() = 0;
  106. /// Compute the sum of counts and return in Sum.
  107. void accumulateCounts(CountSumOrPercent &Sum, bool IsCS);
  108. protected:
  109. std::unique_ptr<InstrProfSymtab> Symtab;
  110. /// Set the current error and return same.
  111. Error error(instrprof_error Err, const std::string &ErrMsg = "") {
  112. LastError = Err;
  113. LastErrorMsg = ErrMsg;
  114. if (Err == instrprof_error::success)
  115. return Error::success();
  116. return make_error<InstrProfError>(Err, ErrMsg);
  117. }
  118. Error error(Error &&E) {
  119. handleAllErrors(std::move(E), [&](const InstrProfError &IPE) {
  120. LastError = IPE.get();
  121. LastErrorMsg = IPE.getMessage();
  122. });
  123. return make_error<InstrProfError>(LastError, LastErrorMsg);
  124. }
  125. /// Clear the current error and return a successful one.
  126. Error success() { return error(instrprof_error::success); }
  127. public:
  128. /// Return true if the reader has finished reading the profile data.
  129. bool isEOF() { return LastError == instrprof_error::eof; }
  130. /// Return true if the reader encountered an error reading profiling data.
  131. bool hasError() { return LastError != instrprof_error::success && !isEOF(); }
  132. /// Get the current error.
  133. Error getError() {
  134. if (hasError())
  135. return make_error<InstrProfError>(LastError, LastErrorMsg);
  136. return Error::success();
  137. }
  138. /// Factory method to create an appropriately typed reader for the given
  139. /// instrprof file.
  140. static Expected<std::unique_ptr<InstrProfReader>>
  141. create(const Twine &Path, const InstrProfCorrelator *Correlator = nullptr);
  142. static Expected<std::unique_ptr<InstrProfReader>>
  143. create(std::unique_ptr<MemoryBuffer> Buffer,
  144. const InstrProfCorrelator *Correlator = nullptr);
  145. };
  146. /// Reader for the simple text based instrprof format.
  147. ///
  148. /// This format is a simple text format that's suitable for test data. Records
  149. /// are separated by one or more blank lines, and record fields are separated by
  150. /// new lines.
  151. ///
  152. /// Each record consists of a function name, a function hash, a number of
  153. /// counters, and then each counter value, in that order.
  154. class TextInstrProfReader : public InstrProfReader {
  155. private:
  156. /// The profile data file contents.
  157. std::unique_ptr<MemoryBuffer> DataBuffer;
  158. /// Iterator over the profile data.
  159. line_iterator Line;
  160. /// The attributes of the current profile.
  161. InstrProfKind ProfileKind = InstrProfKind::Unknown;
  162. Error readValueProfileData(InstrProfRecord &Record);
  163. public:
  164. TextInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer_)
  165. : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#') {}
  166. TextInstrProfReader(const TextInstrProfReader &) = delete;
  167. TextInstrProfReader &operator=(const TextInstrProfReader &) = delete;
  168. /// Return true if the given buffer is in text instrprof format.
  169. static bool hasFormat(const MemoryBuffer &Buffer);
  170. bool isIRLevelProfile() const override {
  171. return static_cast<bool>(ProfileKind & InstrProfKind::IR);
  172. }
  173. bool hasCSIRLevelProfile() const override {
  174. return static_cast<bool>(ProfileKind & InstrProfKind::CS);
  175. }
  176. bool instrEntryBBEnabled() const override {
  177. return static_cast<bool>(ProfileKind & InstrProfKind::BB);
  178. }
  179. bool hasSingleByteCoverage() const override {
  180. return static_cast<bool>(ProfileKind & InstrProfKind::SingleByteCoverage);
  181. }
  182. bool functionEntryOnly() const override {
  183. return static_cast<bool>(ProfileKind & InstrProfKind::FunctionEntryOnly);
  184. }
  185. InstrProfKind getProfileKind() const override { return ProfileKind; }
  186. /// Read the header.
  187. Error readHeader() override;
  188. /// Read a single record.
  189. Error readNextRecord(NamedInstrProfRecord &Record) override;
  190. InstrProfSymtab &getSymtab() override {
  191. assert(Symtab.get());
  192. return *Symtab.get();
  193. }
  194. };
  195. /// Reader for the raw instrprof binary format from runtime.
  196. ///
  197. /// This format is a raw memory dump of the instrumentation-based profiling data
  198. /// from the runtime. It has no index.
  199. ///
  200. /// Templated on the unsigned type whose size matches pointers on the platform
  201. /// that wrote the profile.
  202. template <class IntPtrT>
  203. class RawInstrProfReader : public InstrProfReader {
  204. private:
  205. /// The profile data file contents.
  206. std::unique_ptr<MemoryBuffer> DataBuffer;
  207. /// If available, this hold the ProfileData array used to correlate raw
  208. /// instrumentation data to their functions.
  209. const InstrProfCorrelatorImpl<IntPtrT> *Correlator;
  210. bool ShouldSwapBytes;
  211. // The value of the version field of the raw profile data header. The lower 56
  212. // bits specifies the format version and the most significant 8 bits specify
  213. // the variant types of the profile.
  214. uint64_t Version;
  215. uint64_t CountersDelta;
  216. uint64_t NamesDelta;
  217. const RawInstrProf::ProfileData<IntPtrT> *Data;
  218. const RawInstrProf::ProfileData<IntPtrT> *DataEnd;
  219. const char *CountersStart;
  220. const char *CountersEnd;
  221. const char *NamesStart;
  222. const char *NamesEnd;
  223. // After value profile is all read, this pointer points to
  224. // the header of next profile data (if exists)
  225. const uint8_t *ValueDataStart;
  226. uint32_t ValueKindLast;
  227. uint32_t CurValueDataSize;
  228. uint64_t BinaryIdsSize;
  229. const uint8_t *BinaryIdsStart;
  230. public:
  231. RawInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer,
  232. const InstrProfCorrelator *Correlator)
  233. : DataBuffer(std::move(DataBuffer)),
  234. Correlator(dyn_cast_or_null<const InstrProfCorrelatorImpl<IntPtrT>>(
  235. Correlator)) {}
  236. RawInstrProfReader(const RawInstrProfReader &) = delete;
  237. RawInstrProfReader &operator=(const RawInstrProfReader &) = delete;
  238. static bool hasFormat(const MemoryBuffer &DataBuffer);
  239. Error readHeader() override;
  240. Error readNextRecord(NamedInstrProfRecord &Record) override;
  241. Error printBinaryIds(raw_ostream &OS) override;
  242. bool isIRLevelProfile() const override {
  243. return (Version & VARIANT_MASK_IR_PROF) != 0;
  244. }
  245. bool hasCSIRLevelProfile() const override {
  246. return (Version & VARIANT_MASK_CSIR_PROF) != 0;
  247. }
  248. bool instrEntryBBEnabled() const override {
  249. return (Version & VARIANT_MASK_INSTR_ENTRY) != 0;
  250. }
  251. bool useDebugInfoCorrelate() const override {
  252. return (Version & VARIANT_MASK_DBG_CORRELATE) != 0;
  253. }
  254. bool hasSingleByteCoverage() const override {
  255. return (Version & VARIANT_MASK_BYTE_COVERAGE) != 0;
  256. }
  257. bool functionEntryOnly() const override {
  258. return (Version & VARIANT_MASK_FUNCTION_ENTRY_ONLY) != 0;
  259. }
  260. /// Returns a BitsetEnum describing the attributes of the raw instr profile.
  261. InstrProfKind getProfileKind() const override;
  262. InstrProfSymtab &getSymtab() override {
  263. assert(Symtab.get());
  264. return *Symtab.get();
  265. }
  266. private:
  267. Error createSymtab(InstrProfSymtab &Symtab);
  268. Error readNextHeader(const char *CurrentPos);
  269. Error readHeader(const RawInstrProf::Header &Header);
  270. template <class IntT> IntT swap(IntT Int) const {
  271. return ShouldSwapBytes ? sys::getSwappedBytes(Int) : Int;
  272. }
  273. support::endianness getDataEndianness() const {
  274. support::endianness HostEndian = getHostEndianness();
  275. if (!ShouldSwapBytes)
  276. return HostEndian;
  277. if (HostEndian == support::little)
  278. return support::big;
  279. else
  280. return support::little;
  281. }
  282. inline uint8_t getNumPaddingBytes(uint64_t SizeInBytes) {
  283. return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t));
  284. }
  285. Error readName(NamedInstrProfRecord &Record);
  286. Error readFuncHash(NamedInstrProfRecord &Record);
  287. Error readRawCounts(InstrProfRecord &Record);
  288. Error readValueProfilingData(InstrProfRecord &Record);
  289. bool atEnd() const { return Data == DataEnd; }
  290. void advanceData() {
  291. // `CountersDelta` is a constant zero when using debug info correlation.
  292. if (!Correlator) {
  293. // The initial CountersDelta is the in-memory address difference between
  294. // the data and counts sections:
  295. // start(__llvm_prf_cnts) - start(__llvm_prf_data)
  296. // As we advance to the next record, we maintain the correct CountersDelta
  297. // with respect to the next record.
  298. CountersDelta -= sizeof(*Data);
  299. }
  300. Data++;
  301. ValueDataStart += CurValueDataSize;
  302. }
  303. const char *getNextHeaderPos() const {
  304. assert(atEnd());
  305. return (const char *)ValueDataStart;
  306. }
  307. StringRef getName(uint64_t NameRef) const {
  308. return Symtab->getFuncName(swap(NameRef));
  309. }
  310. int getCounterTypeSize() const {
  311. return hasSingleByteCoverage() ? sizeof(uint8_t) : sizeof(uint64_t);
  312. }
  313. };
  314. using RawInstrProfReader32 = RawInstrProfReader<uint32_t>;
  315. using RawInstrProfReader64 = RawInstrProfReader<uint64_t>;
  316. namespace IndexedInstrProf {
  317. enum class HashT : uint32_t;
  318. } // end namespace IndexedInstrProf
  319. /// Trait for lookups into the on-disk hash table for the binary instrprof
  320. /// format.
  321. class InstrProfLookupTrait {
  322. std::vector<NamedInstrProfRecord> DataBuffer;
  323. IndexedInstrProf::HashT HashType;
  324. unsigned FormatVersion;
  325. // Endianness of the input value profile data.
  326. // It should be LE by default, but can be changed
  327. // for testing purpose.
  328. support::endianness ValueProfDataEndianness = support::little;
  329. public:
  330. InstrProfLookupTrait(IndexedInstrProf::HashT HashType, unsigned FormatVersion)
  331. : HashType(HashType), FormatVersion(FormatVersion) {}
  332. using data_type = ArrayRef<NamedInstrProfRecord>;
  333. using internal_key_type = StringRef;
  334. using external_key_type = StringRef;
  335. using hash_value_type = uint64_t;
  336. using offset_type = uint64_t;
  337. static bool EqualKey(StringRef A, StringRef B) { return A == B; }
  338. static StringRef GetInternalKey(StringRef K) { return K; }
  339. static StringRef GetExternalKey(StringRef K) { return K; }
  340. hash_value_type ComputeHash(StringRef K);
  341. static std::pair<offset_type, offset_type>
  342. ReadKeyDataLength(const unsigned char *&D) {
  343. using namespace support;
  344. offset_type KeyLen = endian::readNext<offset_type, little, unaligned>(D);
  345. offset_type DataLen = endian::readNext<offset_type, little, unaligned>(D);
  346. return std::make_pair(KeyLen, DataLen);
  347. }
  348. StringRef ReadKey(const unsigned char *D, offset_type N) {
  349. return StringRef((const char *)D, N);
  350. }
  351. bool readValueProfilingData(const unsigned char *&D,
  352. const unsigned char *const End);
  353. data_type ReadData(StringRef K, const unsigned char *D, offset_type N);
  354. // Used for testing purpose only.
  355. void setValueProfDataEndianness(support::endianness Endianness) {
  356. ValueProfDataEndianness = Endianness;
  357. }
  358. };
  359. struct InstrProfReaderIndexBase {
  360. virtual ~InstrProfReaderIndexBase() = default;
  361. // Read all the profile records with the same key pointed to the current
  362. // iterator.
  363. virtual Error getRecords(ArrayRef<NamedInstrProfRecord> &Data) = 0;
  364. // Read all the profile records with the key equal to FuncName
  365. virtual Error getRecords(StringRef FuncName,
  366. ArrayRef<NamedInstrProfRecord> &Data) = 0;
  367. virtual void advanceToNextKey() = 0;
  368. virtual bool atEnd() const = 0;
  369. virtual void setValueProfDataEndianness(support::endianness Endianness) = 0;
  370. virtual uint64_t getVersion() const = 0;
  371. virtual bool isIRLevelProfile() const = 0;
  372. virtual bool hasCSIRLevelProfile() const = 0;
  373. virtual bool instrEntryBBEnabled() const = 0;
  374. virtual bool hasSingleByteCoverage() const = 0;
  375. virtual bool functionEntryOnly() const = 0;
  376. virtual InstrProfKind getProfileKind() const = 0;
  377. virtual Error populateSymtab(InstrProfSymtab &) = 0;
  378. };
  379. using OnDiskHashTableImplV3 =
  380. OnDiskIterableChainedHashTable<InstrProfLookupTrait>;
  381. template <typename HashTableImpl>
  382. class InstrProfReaderItaniumRemapper;
  383. template <typename HashTableImpl>
  384. class InstrProfReaderIndex : public InstrProfReaderIndexBase {
  385. private:
  386. std::unique_ptr<HashTableImpl> HashTable;
  387. typename HashTableImpl::data_iterator RecordIterator;
  388. uint64_t FormatVersion;
  389. friend class InstrProfReaderItaniumRemapper<HashTableImpl>;
  390. public:
  391. InstrProfReaderIndex(const unsigned char *Buckets,
  392. const unsigned char *const Payload,
  393. const unsigned char *const Base,
  394. IndexedInstrProf::HashT HashType, uint64_t Version);
  395. ~InstrProfReaderIndex() override = default;
  396. Error getRecords(ArrayRef<NamedInstrProfRecord> &Data) override;
  397. Error getRecords(StringRef FuncName,
  398. ArrayRef<NamedInstrProfRecord> &Data) override;
  399. void advanceToNextKey() override { RecordIterator++; }
  400. bool atEnd() const override {
  401. return RecordIterator == HashTable->data_end();
  402. }
  403. void setValueProfDataEndianness(support::endianness Endianness) override {
  404. HashTable->getInfoObj().setValueProfDataEndianness(Endianness);
  405. }
  406. uint64_t getVersion() const override { return GET_VERSION(FormatVersion); }
  407. bool isIRLevelProfile() const override {
  408. return (FormatVersion & VARIANT_MASK_IR_PROF) != 0;
  409. }
  410. bool hasCSIRLevelProfile() const override {
  411. return (FormatVersion & VARIANT_MASK_CSIR_PROF) != 0;
  412. }
  413. bool instrEntryBBEnabled() const override {
  414. return (FormatVersion & VARIANT_MASK_INSTR_ENTRY) != 0;
  415. }
  416. bool hasSingleByteCoverage() const override {
  417. return (FormatVersion & VARIANT_MASK_BYTE_COVERAGE) != 0;
  418. }
  419. bool functionEntryOnly() const override {
  420. return (FormatVersion & VARIANT_MASK_FUNCTION_ENTRY_ONLY) != 0;
  421. }
  422. InstrProfKind getProfileKind() const override;
  423. Error populateSymtab(InstrProfSymtab &Symtab) override {
  424. return Symtab.create(HashTable->keys());
  425. }
  426. };
  427. /// Name matcher supporting fuzzy matching of symbol names to names in profiles.
  428. class InstrProfReaderRemapper {
  429. public:
  430. virtual ~InstrProfReaderRemapper() = default;
  431. virtual Error populateRemappings() { return Error::success(); }
  432. virtual Error getRecords(StringRef FuncName,
  433. ArrayRef<NamedInstrProfRecord> &Data) = 0;
  434. };
  435. /// Reader for the indexed binary instrprof format.
  436. class IndexedInstrProfReader : public InstrProfReader {
  437. private:
  438. /// The profile data file contents.
  439. std::unique_ptr<MemoryBuffer> DataBuffer;
  440. /// The profile remapping file contents.
  441. std::unique_ptr<MemoryBuffer> RemappingBuffer;
  442. /// The index into the profile data.
  443. std::unique_ptr<InstrProfReaderIndexBase> Index;
  444. /// The profile remapping file contents.
  445. std::unique_ptr<InstrProfReaderRemapper> Remapper;
  446. /// Profile summary data.
  447. std::unique_ptr<ProfileSummary> Summary;
  448. /// Context sensitive profile summary data.
  449. std::unique_ptr<ProfileSummary> CS_Summary;
  450. // Index to the current record in the record array.
  451. unsigned RecordIndex;
  452. // Read the profile summary. Return a pointer pointing to one byte past the
  453. // end of the summary data if it exists or the input \c Cur.
  454. // \c UseCS indicates whether to use the context-sensitive profile summary.
  455. const unsigned char *readSummary(IndexedInstrProf::ProfVersion Version,
  456. const unsigned char *Cur, bool UseCS);
  457. public:
  458. IndexedInstrProfReader(
  459. std::unique_ptr<MemoryBuffer> DataBuffer,
  460. std::unique_ptr<MemoryBuffer> RemappingBuffer = nullptr)
  461. : DataBuffer(std::move(DataBuffer)),
  462. RemappingBuffer(std::move(RemappingBuffer)), RecordIndex(0) {}
  463. IndexedInstrProfReader(const IndexedInstrProfReader &) = delete;
  464. IndexedInstrProfReader &operator=(const IndexedInstrProfReader &) = delete;
  465. /// Return the profile version.
  466. uint64_t getVersion() const { return Index->getVersion(); }
  467. bool isIRLevelProfile() const override { return Index->isIRLevelProfile(); }
  468. bool hasCSIRLevelProfile() const override {
  469. return Index->hasCSIRLevelProfile();
  470. }
  471. bool instrEntryBBEnabled() const override {
  472. return Index->instrEntryBBEnabled();
  473. }
  474. bool hasSingleByteCoverage() const override {
  475. return Index->hasSingleByteCoverage();
  476. }
  477. bool functionEntryOnly() const override { return Index->functionEntryOnly(); }
  478. /// Returns a BitsetEnum describing the attributes of the indexed instr
  479. /// profile.
  480. InstrProfKind getProfileKind() const override {
  481. return Index->getProfileKind();
  482. }
  483. /// Return true if the given buffer is in an indexed instrprof format.
  484. static bool hasFormat(const MemoryBuffer &DataBuffer);
  485. /// Read the file header.
  486. Error readHeader() override;
  487. /// Read a single record.
  488. Error readNextRecord(NamedInstrProfRecord &Record) override;
  489. /// Return the NamedInstrProfRecord associated with FuncName and FuncHash
  490. Expected<InstrProfRecord> getInstrProfRecord(StringRef FuncName,
  491. uint64_t FuncHash);
  492. /// Fill Counts with the profile data for the given function name.
  493. Error getFunctionCounts(StringRef FuncName, uint64_t FuncHash,
  494. std::vector<uint64_t> &Counts);
  495. /// Return the maximum of all known function counts.
  496. /// \c UseCS indicates whether to use the context-sensitive count.
  497. uint64_t getMaximumFunctionCount(bool UseCS) {
  498. if (UseCS) {
  499. assert(CS_Summary && "No context sensitive profile summary");
  500. return CS_Summary->getMaxFunctionCount();
  501. } else {
  502. assert(Summary && "No profile summary");
  503. return Summary->getMaxFunctionCount();
  504. }
  505. }
  506. /// Factory method to create an indexed reader.
  507. static Expected<std::unique_ptr<IndexedInstrProfReader>>
  508. create(const Twine &Path, const Twine &RemappingPath = "");
  509. static Expected<std::unique_ptr<IndexedInstrProfReader>>
  510. create(std::unique_ptr<MemoryBuffer> Buffer,
  511. std::unique_ptr<MemoryBuffer> RemappingBuffer = nullptr);
  512. // Used for testing purpose only.
  513. void setValueProfDataEndianness(support::endianness Endianness) {
  514. Index->setValueProfDataEndianness(Endianness);
  515. }
  516. // See description in the base class. This interface is designed
  517. // to be used by llvm-profdata (for dumping). Avoid using this when
  518. // the client is the compiler.
  519. InstrProfSymtab &getSymtab() override;
  520. /// Return the profile summary.
  521. /// \c UseCS indicates whether to use the context-sensitive summary.
  522. ProfileSummary &getSummary(bool UseCS) {
  523. if (UseCS) {
  524. assert(CS_Summary && "No context sensitive summary");
  525. return *(CS_Summary.get());
  526. } else {
  527. assert(Summary && "No profile summary");
  528. return *(Summary.get());
  529. }
  530. }
  531. };
  532. } // end namespace llvm
  533. #endif // LLVM_PROFILEDATA_INSTRPROFREADER_H
  534. #ifdef __GNUC__
  535. #pragma GCC diagnostic pop
  536. #endif