- //===- InstrProfReader.h - Instrumented profiling readers -------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // This file contains support for reading profiling data for instrumentation 
- // based PGO and coverage. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_PROFILEDATA_INSTRPROFREADER_H 
- #define LLVM_PROFILEDATA_INSTRPROFREADER_H 
-   
- #include "llvm/ADT/ArrayRef.h" 
- #include "llvm/ADT/StringRef.h" 
- #include "llvm/IR/ProfileSummary.h" 
- #include "llvm/Object/BuildID.h" 
- #include "llvm/ProfileData/InstrProf.h" 
- #include "llvm/ProfileData/InstrProfCorrelator.h" 
- #include "llvm/ProfileData/MemProf.h" 
- #include "llvm/Support/Endian.h" 
- #include "llvm/Support/Error.h" 
- #include "llvm/Support/LineIterator.h" 
- #include "llvm/Support/MathExtras.h" 
- #include "llvm/Support/MemoryBuffer.h" 
- #include "llvm/Support/OnDiskHashTable.h" 
- #include "llvm/Support/SwapByteOrder.h" 
- #include <algorithm> 
- #include <cassert> 
- #include <cstddef> 
- #include <cstdint> 
- #include <iterator> 
- #include <memory> 
- #include <utility> 
- #include <vector> 
-   
- namespace llvm { 
-   
- class InstrProfReader; 
-   
- /// A file format agnostic iterator over profiling data. 
- template <class record_type = NamedInstrProfRecord, 
-           class reader_type = InstrProfReader> 
- class InstrProfIterator { 
- public: 
-   using iterator_category = std::input_iterator_tag; 
-   using value_type = record_type; 
-   using difference_type = std::ptrdiff_t; 
-   using pointer = value_type *; 
-   using reference = value_type &; 
-   
- private: 
-   reader_type *Reader = nullptr; 
-   value_type Record; 
-   
-   void increment() { 
-     if (Error E = Reader->readNextRecord(Record)) { 
-       // Handle errors in the reader. 
-       InstrProfError::take(std::move(E)); 
-       *this = InstrProfIterator(); 
-     } 
-   } 
-   
- public: 
-   InstrProfIterator() = default; 
-   InstrProfIterator(reader_type *Reader) : Reader(Reader) { increment(); } 
-   
-   InstrProfIterator &operator++() { 
-     increment(); 
-     return *this; 
-   } 
-   bool operator==(const InstrProfIterator &RHS) const { 
-     return Reader == RHS.Reader; 
-   } 
-   bool operator!=(const InstrProfIterator &RHS) const { 
-     return Reader != RHS.Reader; 
-   } 
-   value_type &operator*() { return Record; } 
-   value_type *operator->() { return &Record; } 
- }; 
-   
- /// Base class and interface for reading profiling data of any known instrprof 
- /// format. Provides an iterator over NamedInstrProfRecords. 
- class InstrProfReader { 
-   instrprof_error LastError = instrprof_error::success; 
-   std::string LastErrorMsg; 
-   
- public: 
-   InstrProfReader() = default; 
-   virtual ~InstrProfReader() = default; 
-   
-   /// Read the header.  Required before reading first record. 
-   virtual Error readHeader() = 0; 
-   
-   /// Read a single record. 
-   virtual Error readNextRecord(NamedInstrProfRecord &Record) = 0; 
-   
-   /// Read a list of binary ids. 
-   virtual Error readBinaryIds(std::vector<llvm::object::BuildID> &BinaryIds) { 
-     return success(); 
-   } 
-   
-   /// Print binary ids. 
-   virtual Error printBinaryIds(raw_ostream &OS) { return success(); }; 
-   
-   /// Iterator over profile data. 
-   InstrProfIterator<> begin() { return InstrProfIterator<>(this); } 
-   InstrProfIterator<> end() { return InstrProfIterator<>(); } 
-   
-   /// Return the profile version. 
-   virtual uint64_t getVersion() const = 0; 
-   
-   virtual bool isIRLevelProfile() const = 0; 
-   
-   virtual bool hasCSIRLevelProfile() const = 0; 
-   
-   virtual bool instrEntryBBEnabled() const = 0; 
-   
-   /// Return true if we must provide debug info to create PGO profiles. 
-   virtual bool useDebugInfoCorrelate() const { return false; } 
-   
-   /// Return true if the profile has single byte counters representing coverage. 
-   virtual bool hasSingleByteCoverage() const = 0; 
-   
-   /// Return true if the profile only instruments function entries. 
-   virtual bool functionEntryOnly() const = 0; 
-   
-   /// Return true if profile includes a memory profile. 
-   virtual bool hasMemoryProfile() const = 0; 
-   
-   /// Returns a BitsetEnum describing the attributes of the profile. To check 
-   /// individual attributes prefer using the helpers above. 
-   virtual InstrProfKind getProfileKind() const = 0; 
-   
-   /// Return the PGO symtab. There are three different readers: 
-   /// Raw, Text, and Indexed profile readers. The first two types 
-   /// of readers are used only by llvm-profdata tool, while the indexed 
-   /// profile reader is also used by llvm-cov tool and the compiler ( 
-   /// backend or frontend). Since creating PGO symtab can create 
-   /// significant runtime and memory overhead (as it touches data 
-   /// for the whole program), InstrProfSymtab for the indexed profile 
-   /// reader should be created on demand and it is recommended to be 
-   /// only used for dumping purpose with llvm-proftool, not with the 
-   /// compiler. 
-   virtual InstrProfSymtab &getSymtab() = 0; 
-   
-   /// Compute the sum of counts and return in Sum. 
-   void accumulateCounts(CountSumOrPercent &Sum, bool IsCS); 
-   
- protected: 
-   std::unique_ptr<InstrProfSymtab> Symtab; 
-   
-   /// Set the current error and return same. 
-   Error error(instrprof_error Err, const std::string &ErrMsg = "") { 
-     LastError = Err; 
-     LastErrorMsg = ErrMsg; 
-     if (Err == instrprof_error::success) 
-       return Error::success(); 
-     return make_error<InstrProfError>(Err, ErrMsg); 
-   } 
-   
-   Error error(Error &&E) { 
-     handleAllErrors(std::move(E), [&](const InstrProfError &IPE) { 
-       LastError = IPE.get(); 
-       LastErrorMsg = IPE.getMessage(); 
-     }); 
-     return make_error<InstrProfError>(LastError, LastErrorMsg); 
-   } 
-   
-   /// Clear the current error and return a successful one. 
-   Error success() { return error(instrprof_error::success); } 
-   
- public: 
-   /// Return true if the reader has finished reading the profile data. 
-   bool isEOF() { return LastError == instrprof_error::eof; } 
-   
-   /// Return true if the reader encountered an error reading profiling data. 
-   bool hasError() { return LastError != instrprof_error::success && !isEOF(); } 
-   
-   /// Get the current error. 
-   Error getError() { 
-     if (hasError()) 
-       return make_error<InstrProfError>(LastError, LastErrorMsg); 
-     return Error::success(); 
-   } 
-   
-   /// Factory method to create an appropriately typed reader for the given 
-   /// instrprof file. 
-   static Expected<std::unique_ptr<InstrProfReader>> 
-   create(const Twine &Path, const InstrProfCorrelator *Correlator = nullptr); 
-   
-   static Expected<std::unique_ptr<InstrProfReader>> 
-   create(std::unique_ptr<MemoryBuffer> Buffer, 
-          const InstrProfCorrelator *Correlator = nullptr); 
- }; 
-   
- /// Reader for the simple text based instrprof format. 
- /// 
- /// This format is a simple text format that's suitable for test data. Records 
- /// are separated by one or more blank lines, and record fields are separated by 
- /// new lines. 
- /// 
- /// Each record consists of a function name, a function hash, a number of 
- /// counters, and then each counter value, in that order. 
- class TextInstrProfReader : public InstrProfReader { 
- private: 
-   /// The profile data file contents. 
-   std::unique_ptr<MemoryBuffer> DataBuffer; 
-   /// Iterator over the profile data. 
-   line_iterator Line; 
-   /// The attributes of the current profile. 
-   InstrProfKind ProfileKind = InstrProfKind::Unknown; 
-   
-   Error readValueProfileData(InstrProfRecord &Record); 
-   
- public: 
-   TextInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer_) 
-       : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#') {} 
-   TextInstrProfReader(const TextInstrProfReader &) = delete; 
-   TextInstrProfReader &operator=(const TextInstrProfReader &) = delete; 
-   
-   /// Return true if the given buffer is in text instrprof format. 
-   static bool hasFormat(const MemoryBuffer &Buffer); 
-   
-   // Text format does not have version, so return 0. 
-   uint64_t getVersion() const override { return 0; } 
-   
-   bool isIRLevelProfile() const override { 
-     return static_cast<bool>(ProfileKind & InstrProfKind::IRInstrumentation); 
-   } 
-   
-   bool hasCSIRLevelProfile() const override { 
-     return static_cast<bool>(ProfileKind & InstrProfKind::ContextSensitive); 
-   } 
-   
-   bool instrEntryBBEnabled() const override { 
-     return static_cast<bool>(ProfileKind & 
-                              InstrProfKind::FunctionEntryInstrumentation); 
-   } 
-   
-   bool hasSingleByteCoverage() const override { 
-     return static_cast<bool>(ProfileKind & InstrProfKind::SingleByteCoverage); 
-   } 
-   
-   bool functionEntryOnly() const override { 
-     return static_cast<bool>(ProfileKind & InstrProfKind::FunctionEntryOnly); 
-   } 
-   
-   bool hasMemoryProfile() const override { 
-     // TODO: Add support for text format memory profiles. 
-     return false; 
-   } 
-   
-   InstrProfKind getProfileKind() const override { return ProfileKind; } 
-   
-   /// Read the header. 
-   Error readHeader() override; 
-   
-   /// Read a single record. 
-   Error readNextRecord(NamedInstrProfRecord &Record) override; 
-   
-   InstrProfSymtab &getSymtab() override { 
-     assert(Symtab); 
-     return *Symtab; 
-   } 
- }; 
-   
- /// Reader for the raw instrprof binary format from runtime. 
- /// 
- /// This format is a raw memory dump of the instrumentation-based profiling data 
- /// from the runtime.  It has no index. 
- /// 
- /// Templated on the unsigned type whose size matches pointers on the platform 
- /// that wrote the profile. 
- template <class IntPtrT> 
- class RawInstrProfReader : public InstrProfReader { 
- private: 
-   /// The profile data file contents. 
-   std::unique_ptr<MemoryBuffer> DataBuffer; 
-   /// If available, this hold the ProfileData array used to correlate raw 
-   /// instrumentation data to their functions. 
-   const InstrProfCorrelatorImpl<IntPtrT> *Correlator; 
-   bool ShouldSwapBytes; 
-   // The value of the version field of the raw profile data header. The lower 56 
-   // bits specifies the format version and the most significant 8 bits specify 
-   // the variant types of the profile. 
-   uint64_t Version; 
-   uint64_t CountersDelta; 
-   uint64_t NamesDelta; 
-   const RawInstrProf::ProfileData<IntPtrT> *Data; 
-   const RawInstrProf::ProfileData<IntPtrT> *DataEnd; 
-   const char *CountersStart; 
-   const char *CountersEnd; 
-   const char *NamesStart; 
-   const char *NamesEnd; 
-   // After value profile is all read, this pointer points to 
-   // the header of next profile data (if exists) 
-   const uint8_t *ValueDataStart; 
-   uint32_t ValueKindLast; 
-   uint32_t CurValueDataSize; 
-   
-   /// Total size of binary ids. 
-   uint64_t BinaryIdsSize{0}; 
-   /// Start address of binary id length and data pairs. 
-   const uint8_t *BinaryIdsStart; 
-   
- public: 
-   RawInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer, 
-                      const InstrProfCorrelator *Correlator) 
-       : DataBuffer(std::move(DataBuffer)), 
-         Correlator(dyn_cast_or_null<const InstrProfCorrelatorImpl<IntPtrT>>( 
-             Correlator)) {} 
-   RawInstrProfReader(const RawInstrProfReader &) = delete; 
-   RawInstrProfReader &operator=(const RawInstrProfReader &) = delete; 
-   
-   static bool hasFormat(const MemoryBuffer &DataBuffer); 
-   Error readHeader() override; 
-   Error readNextRecord(NamedInstrProfRecord &Record) override; 
-   Error readBinaryIds(std::vector<llvm::object::BuildID> &BinaryIds) override; 
-   Error printBinaryIds(raw_ostream &OS) override; 
-   
-   uint64_t getVersion() const override { return Version; } 
-   
-   bool isIRLevelProfile() const override { 
-     return (Version & VARIANT_MASK_IR_PROF) != 0; 
-   } 
-   
-   bool hasCSIRLevelProfile() const override { 
-     return (Version & VARIANT_MASK_CSIR_PROF) != 0; 
-   } 
-   
-   bool instrEntryBBEnabled() const override { 
-     return (Version & VARIANT_MASK_INSTR_ENTRY) != 0; 
-   } 
-   
-   bool useDebugInfoCorrelate() const override { 
-     return (Version & VARIANT_MASK_DBG_CORRELATE) != 0; 
-   } 
-   
-   bool hasSingleByteCoverage() const override { 
-     return (Version & VARIANT_MASK_BYTE_COVERAGE) != 0; 
-   } 
-   
-   bool functionEntryOnly() const override { 
-     return (Version & VARIANT_MASK_FUNCTION_ENTRY_ONLY) != 0; 
-   } 
-   
-   bool hasMemoryProfile() const override { 
-     // Memory profiles have a separate raw format, so this should never be set. 
-     assert(!(Version & VARIANT_MASK_MEMPROF)); 
-     return false; 
-   } 
-   
-   /// Returns a BitsetEnum describing the attributes of the raw instr profile. 
-   InstrProfKind getProfileKind() const override; 
-   
-   InstrProfSymtab &getSymtab() override { 
-     assert(Symtab.get()); 
-     return *Symtab.get(); 
-   } 
-   
- private: 
-   Error createSymtab(InstrProfSymtab &Symtab); 
-   Error readNextHeader(const char *CurrentPos); 
-   Error readHeader(const RawInstrProf::Header &Header); 
-   
-   template <class IntT> IntT swap(IntT Int) const { 
-     return ShouldSwapBytes ? sys::getSwappedBytes(Int) : Int; 
-   } 
-   
-   support::endianness getDataEndianness() const { 
-     support::endianness HostEndian = getHostEndianness(); 
-     if (!ShouldSwapBytes) 
-       return HostEndian; 
-     if (HostEndian == support::little) 
-       return support::big; 
-     else 
-       return support::little; 
-   } 
-   
-   inline uint8_t getNumPaddingBytes(uint64_t SizeInBytes) { 
-     return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t)); 
-   } 
-   
-   Error readName(NamedInstrProfRecord &Record); 
-   Error readFuncHash(NamedInstrProfRecord &Record); 
-   Error readRawCounts(InstrProfRecord &Record); 
-   Error readValueProfilingData(InstrProfRecord &Record); 
-   bool atEnd() const { return Data == DataEnd; } 
-   
-   void advanceData() { 
-     // `CountersDelta` is a constant zero when using debug info correlation. 
-     if (!Correlator) { 
-       // The initial CountersDelta is the in-memory address difference between 
-       // the data and counts sections: 
-       // start(__llvm_prf_cnts) - start(__llvm_prf_data) 
-       // As we advance to the next record, we maintain the correct CountersDelta 
-       // with respect to the next record. 
-       CountersDelta -= sizeof(*Data); 
-     } 
-     Data++; 
-     ValueDataStart += CurValueDataSize; 
-   } 
-   
-   const char *getNextHeaderPos() const { 
-       assert(atEnd()); 
-       return (const char *)ValueDataStart; 
-   } 
-   
-   StringRef getName(uint64_t NameRef) const { 
-     return Symtab->getFuncName(swap(NameRef)); 
-   } 
-   
-   int getCounterTypeSize() const { 
-     return hasSingleByteCoverage() ? sizeof(uint8_t) : sizeof(uint64_t); 
-   } 
- }; 
-   
- using RawInstrProfReader32 = RawInstrProfReader<uint32_t>; 
- using RawInstrProfReader64 = RawInstrProfReader<uint64_t>; 
-   
- namespace IndexedInstrProf { 
-   
- enum class HashT : uint32_t; 
-   
- } // end namespace IndexedInstrProf 
-   
- /// Trait for lookups into the on-disk hash table for the binary instrprof 
- /// format. 
- class InstrProfLookupTrait { 
-   std::vector<NamedInstrProfRecord> DataBuffer; 
-   IndexedInstrProf::HashT HashType; 
-   unsigned FormatVersion; 
-   // Endianness of the input value profile data. 
-   // It should be LE by default, but can be changed 
-   // for testing purpose. 
-   support::endianness ValueProfDataEndianness = support::little; 
-   
- public: 
-   InstrProfLookupTrait(IndexedInstrProf::HashT HashType, unsigned FormatVersion) 
-       : HashType(HashType), FormatVersion(FormatVersion) {} 
-   
-   using data_type = ArrayRef<NamedInstrProfRecord>; 
-   
-   using internal_key_type = StringRef; 
-   using external_key_type = StringRef; 
-   using hash_value_type = uint64_t; 
-   using offset_type = uint64_t; 
-   
-   static bool EqualKey(StringRef A, StringRef B) { return A == B; } 
-   static StringRef GetInternalKey(StringRef K) { return K; } 
-   static StringRef GetExternalKey(StringRef K) { return K; } 
-   
-   hash_value_type ComputeHash(StringRef K); 
-   
-   static std::pair<offset_type, offset_type> 
-   ReadKeyDataLength(const unsigned char *&D) { 
-     using namespace support; 
-   
-     offset_type KeyLen = endian::readNext<offset_type, little, unaligned>(D); 
-     offset_type DataLen = endian::readNext<offset_type, little, unaligned>(D); 
-     return std::make_pair(KeyLen, DataLen); 
-   } 
-   
-   StringRef ReadKey(const unsigned char *D, offset_type N) { 
-     return StringRef((const char *)D, N); 
-   } 
-   
-   bool readValueProfilingData(const unsigned char *&D, 
-                               const unsigned char *const End); 
-   data_type ReadData(StringRef K, const unsigned char *D, offset_type N); 
-   
-   // Used for testing purpose only. 
-   void setValueProfDataEndianness(support::endianness Endianness) { 
-     ValueProfDataEndianness = Endianness; 
-   } 
- }; 
-   
- struct InstrProfReaderIndexBase { 
-   virtual ~InstrProfReaderIndexBase() = default; 
-   
-   // Read all the profile records with the same key pointed to the current 
-   // iterator. 
-   virtual Error getRecords(ArrayRef<NamedInstrProfRecord> &Data) = 0; 
-   
-   // Read all the profile records with the key equal to FuncName 
-   virtual Error getRecords(StringRef FuncName, 
-                                      ArrayRef<NamedInstrProfRecord> &Data) = 0; 
-   virtual void advanceToNextKey() = 0; 
-   virtual bool atEnd() const = 0; 
-   virtual void setValueProfDataEndianness(support::endianness Endianness) = 0; 
-   virtual uint64_t getVersion() const = 0; 
-   virtual bool isIRLevelProfile() const = 0; 
-   virtual bool hasCSIRLevelProfile() const = 0; 
-   virtual bool instrEntryBBEnabled() const = 0; 
-   virtual bool hasSingleByteCoverage() const = 0; 
-   virtual bool functionEntryOnly() const = 0; 
-   virtual bool hasMemoryProfile() const = 0; 
-   virtual InstrProfKind getProfileKind() const = 0; 
-   virtual Error populateSymtab(InstrProfSymtab &) = 0; 
- }; 
-   
- using OnDiskHashTableImplV3 = 
-     OnDiskIterableChainedHashTable<InstrProfLookupTrait>; 
-   
- using MemProfRecordHashTable = 
-     OnDiskIterableChainedHashTable<memprof::RecordLookupTrait>; 
- using MemProfFrameHashTable = 
-     OnDiskIterableChainedHashTable<memprof::FrameLookupTrait>; 
-   
- template <typename HashTableImpl> 
- class InstrProfReaderItaniumRemapper; 
-   
- template <typename HashTableImpl> 
- class InstrProfReaderIndex : public InstrProfReaderIndexBase { 
- private: 
-   std::unique_ptr<HashTableImpl> HashTable; 
-   typename HashTableImpl::data_iterator RecordIterator; 
-   uint64_t FormatVersion; 
-   
-   friend class InstrProfReaderItaniumRemapper<HashTableImpl>; 
-   
- public: 
-   InstrProfReaderIndex(const unsigned char *Buckets, 
-                        const unsigned char *const Payload, 
-                        const unsigned char *const Base, 
-                        IndexedInstrProf::HashT HashType, uint64_t Version); 
-   ~InstrProfReaderIndex() override = default; 
-   
-   Error getRecords(ArrayRef<NamedInstrProfRecord> &Data) override; 
-   Error getRecords(StringRef FuncName, 
-                    ArrayRef<NamedInstrProfRecord> &Data) override; 
-   void advanceToNextKey() override { RecordIterator++; } 
-   
-   bool atEnd() const override { 
-     return RecordIterator == HashTable->data_end(); 
-   } 
-   
-   void setValueProfDataEndianness(support::endianness Endianness) override { 
-     HashTable->getInfoObj().setValueProfDataEndianness(Endianness); 
-   } 
-   
-   uint64_t getVersion() const override { return GET_VERSION(FormatVersion); } 
-   
-   bool isIRLevelProfile() const override { 
-     return (FormatVersion & VARIANT_MASK_IR_PROF) != 0; 
-   } 
-   
-   bool hasCSIRLevelProfile() const override { 
-     return (FormatVersion & VARIANT_MASK_CSIR_PROF) != 0; 
-   } 
-   
-   bool instrEntryBBEnabled() const override { 
-     return (FormatVersion & VARIANT_MASK_INSTR_ENTRY) != 0; 
-   } 
-   
-   bool hasSingleByteCoverage() const override { 
-     return (FormatVersion & VARIANT_MASK_BYTE_COVERAGE) != 0; 
-   } 
-   
-   bool functionEntryOnly() const override { 
-     return (FormatVersion & VARIANT_MASK_FUNCTION_ENTRY_ONLY) != 0; 
-   } 
-   
-   bool hasMemoryProfile() const override { 
-     return (FormatVersion & VARIANT_MASK_MEMPROF) != 0; 
-   } 
-   
-   InstrProfKind getProfileKind() const override; 
-   
-   Error populateSymtab(InstrProfSymtab &Symtab) override { 
-     return Symtab.create(HashTable->keys()); 
-   } 
- }; 
-   
- /// Name matcher supporting fuzzy matching of symbol names to names in profiles. 
- class InstrProfReaderRemapper { 
- public: 
-   virtual ~InstrProfReaderRemapper() = default; 
-   virtual Error populateRemappings() { return Error::success(); } 
-   virtual Error getRecords(StringRef FuncName, 
-                            ArrayRef<NamedInstrProfRecord> &Data) = 0; 
- }; 
-   
- /// Reader for the indexed binary instrprof format. 
- class IndexedInstrProfReader : public InstrProfReader { 
- private: 
-   /// The profile data file contents. 
-   std::unique_ptr<MemoryBuffer> DataBuffer; 
-   /// The profile remapping file contents. 
-   std::unique_ptr<MemoryBuffer> RemappingBuffer; 
-   /// The index into the profile data. 
-   std::unique_ptr<InstrProfReaderIndexBase> Index; 
-   /// The profile remapping file contents. 
-   std::unique_ptr<InstrProfReaderRemapper> Remapper; 
-   /// Profile summary data. 
-   std::unique_ptr<ProfileSummary> Summary; 
-   /// Context sensitive profile summary data. 
-   std::unique_ptr<ProfileSummary> CS_Summary; 
-   /// MemProf profile schema (if available). 
-   memprof::MemProfSchema Schema; 
-   /// MemProf record profile data on-disk indexed via llvm::md5(FunctionName). 
-   std::unique_ptr<MemProfRecordHashTable> MemProfRecordTable; 
-   /// MemProf frame profile data on-disk indexed via frame id. 
-   std::unique_ptr<MemProfFrameHashTable> MemProfFrameTable; 
-   /// Total size of binary ids. 
-   uint64_t BinaryIdsSize{0}; 
-   /// Start address of binary id length and data pairs. 
-   const uint8_t *BinaryIdsStart = nullptr; 
-   
-   // Index to the current record in the record array. 
-   unsigned RecordIndex; 
-   
-   // Read the profile summary. Return a pointer pointing to one byte past the 
-   // end of the summary data if it exists or the input \c Cur. 
-   // \c UseCS indicates whether to use the context-sensitive profile summary. 
-   const unsigned char *readSummary(IndexedInstrProf::ProfVersion Version, 
-                                    const unsigned char *Cur, bool UseCS); 
-   
- public: 
-   IndexedInstrProfReader( 
-       std::unique_ptr<MemoryBuffer> DataBuffer, 
-       std::unique_ptr<MemoryBuffer> RemappingBuffer = nullptr) 
-       : DataBuffer(std::move(DataBuffer)), 
-         RemappingBuffer(std::move(RemappingBuffer)), RecordIndex(0) {} 
-   IndexedInstrProfReader(const IndexedInstrProfReader &) = delete; 
-   IndexedInstrProfReader &operator=(const IndexedInstrProfReader &) = delete; 
-   
-   /// Return the profile version. 
-   uint64_t getVersion() const override { return Index->getVersion(); } 
-   bool isIRLevelProfile() const override { return Index->isIRLevelProfile(); } 
-   bool hasCSIRLevelProfile() const override { 
-     return Index->hasCSIRLevelProfile(); 
-   } 
-   
-   bool instrEntryBBEnabled() const override { 
-     return Index->instrEntryBBEnabled(); 
-   } 
-   
-   bool hasSingleByteCoverage() const override { 
-     return Index->hasSingleByteCoverage(); 
-   } 
-   
-   bool functionEntryOnly() const override { return Index->functionEntryOnly(); } 
-   
-   bool hasMemoryProfile() const override { return Index->hasMemoryProfile(); } 
-   
-   /// Returns a BitsetEnum describing the attributes of the indexed instr 
-   /// profile. 
-   InstrProfKind getProfileKind() const override { 
-     return Index->getProfileKind(); 
-   } 
-   
-   /// Return true if the given buffer is in an indexed instrprof format. 
-   static bool hasFormat(const MemoryBuffer &DataBuffer); 
-   
-   /// Read the file header. 
-   Error readHeader() override; 
-   /// Read a single record. 
-   Error readNextRecord(NamedInstrProfRecord &Record) override; 
-   
-   /// Return the NamedInstrProfRecord associated with FuncName and FuncHash. 
-   /// When return a hash_mismatch error and MismatchedFuncSum is not nullptr, 
-   /// the sum of all counters in the mismatched function will be set to 
-   /// MismatchedFuncSum. If there are multiple instances of mismatched 
-   /// functions, MismatchedFuncSum returns the maximum. 
-   Expected<InstrProfRecord> 
-   getInstrProfRecord(StringRef FuncName, uint64_t FuncHash, 
-                      uint64_t *MismatchedFuncSum = nullptr); 
-   
-   /// Return the memprof record for the function identified by 
-   /// llvm::md5(Name). 
-   Expected<memprof::MemProfRecord> getMemProfRecord(uint64_t FuncNameHash); 
-   
-   /// Fill Counts with the profile data for the given function name. 
-   Error getFunctionCounts(StringRef FuncName, uint64_t FuncHash, 
-                           std::vector<uint64_t> &Counts); 
-   
-   /// Return the maximum of all known function counts. 
-   /// \c UseCS indicates whether to use the context-sensitive count. 
-   uint64_t getMaximumFunctionCount(bool UseCS) { 
-     if (UseCS) { 
-       assert(CS_Summary && "No context sensitive profile summary"); 
-       return CS_Summary->getMaxFunctionCount(); 
-     } else { 
-       assert(Summary && "No profile summary"); 
-       return Summary->getMaxFunctionCount(); 
-     } 
-   } 
-   
-   /// Factory method to create an indexed reader. 
-   static Expected<std::unique_ptr<IndexedInstrProfReader>> 
-   create(const Twine &Path, const Twine &RemappingPath = ""); 
-   
-   static Expected<std::unique_ptr<IndexedInstrProfReader>> 
-   create(std::unique_ptr<MemoryBuffer> Buffer, 
-          std::unique_ptr<MemoryBuffer> RemappingBuffer = nullptr); 
-   
-   // Used for testing purpose only. 
-   void setValueProfDataEndianness(support::endianness Endianness) { 
-     Index->setValueProfDataEndianness(Endianness); 
-   } 
-   
-   // See description in the base class. This interface is designed 
-   // to be used by llvm-profdata (for dumping). Avoid using this when 
-   // the client is the compiler. 
-   InstrProfSymtab &getSymtab() override; 
-   
-   /// Return the profile summary. 
-   /// \c UseCS indicates whether to use the context-sensitive summary. 
-   ProfileSummary &getSummary(bool UseCS) { 
-     if (UseCS) { 
-       assert(CS_Summary && "No context sensitive summary"); 
-       return *CS_Summary; 
-     } else { 
-       assert(Summary && "No profile summary"); 
-       return *Summary; 
-     } 
-   } 
-   
-   Error readBinaryIds(std::vector<llvm::object::BuildID> &BinaryIds) override; 
-   Error printBinaryIds(raw_ostream &OS) override; 
- }; 
-   
- } // end namespace llvm 
-   
- #endif // LLVM_PROFILEDATA_INSTRPROFREADER_H 
-