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