InstrProfReader.h 25 KB

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