Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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