35 #include <system_error> 45 if (std::error_code EC = BufferOrErr.
getError())
47 return std::move(BufferOrErr.
get());
58 if (
Error E = BufferOrError.takeError())
69 if (Buffer->getBufferSize() == 0)
72 std::unique_ptr<InstrProfReader> Result;
89 return std::move(Result);
96 if (
Error E = BufferOrError.takeError())
100 std::unique_ptr<MemoryBuffer> RemappingBuffer;
101 std::string RemappingPathStr = RemappingPath.
str();
102 if (!RemappingPathStr.empty()) {
104 if (
Error E = RemappingBufferOrError.takeError())
106 RemappingBuffer = std::move(RemappingBufferOrError.get());
110 std::move(RemappingBuffer));
115 std::unique_ptr<MemoryBuffer> RemappingBuffer) {
123 auto Result = llvm::make_unique<IndexedInstrProfReader>(
124 std::move(Buffer), std::move(RemappingBuffer));
130 return std::move(Result);
133 void InstrProfIterator::Increment() {
134 if (
auto E = Reader->readNextRecord(
Record)) {
148 [](
char c) {
return isPrint(c) || ::isspace(c); });
156 bool IsIRInstr =
false;
157 if (!Line->startswith(
":")) {
158 IsIRLevelProfile =
false;
170 IsIRLevelProfile = IsIRInstr;
177 #define CHECK_LINE_END(Line) \ 178 if (Line.is_at_end()) \ 179 return error(instrprof_error::truncated); 180 #define READ_NUM(Str, Dst) \ 181 if ((Str).getAsInteger(10, (Dst))) \ 182 return error(instrprof_error::malformed); 183 #define VP_READ_ADVANCE(Val) \ 184 CHECK_LINE_END(Line); \ 186 READ_NUM((*Line), (Val)); \ 189 if (Line.is_at_end())
193 if (Line->getAsInteger(10, NumValueKinds)) {
197 if (NumValueKinds == 0 || NumValueKinds > IPVK_Last + 1)
201 for (
uint32_t VK = 0; VK < NumValueKinds; VK++) {
210 for (
uint32_t S = 0; S < NumValueSites; S++) {
213 std::vector<InstrProfValueData> CurrentValues;
214 for (
uint32_t V = 0; V < NumValueData; V++) {
216 std::pair<StringRef, StringRef> VD = Line->rsplit(
':');
217 uint64_t TakenCount,
Value;
218 if (
ValueKind == IPVK_IndirectCallTarget) {
230 CurrentValues.push_back({Value, TakenCount});
239 #undef CHECK_LINE_END 241 #undef VP_READ_ADVANCE 246 while (!Line.is_at_end() && (Line->empty() || Line->startswith(
"#")))
249 if (Line.is_at_end()) {
254 Record.
Name = *Line++;
256 return error(std::move(
E));
259 if (Line.is_at_end())
261 if ((Line++)->getAsInteger(0, Record.
Hash))
265 uint64_t NumCounters;
266 if (Line.is_at_end())
268 if ((Line++)->getAsInteger(10, NumCounters))
270 if (NumCounters == 0)
275 Record.
Counts.reserve(NumCounters);
276 for (uint64_t
I = 0;
I < NumCounters; ++
I) {
277 if (Line.is_at_end())
280 if ((Line++)->getAsInteger(10, Count))
282 Record.
Counts.push_back(Count);
286 if (
Error E = readValueProfileData(Record))
287 return error(std::move(
E));
292 template <
class IntPtrT>
298 return RawInstrProf::getMagic<IntPtrT>() == Magic ||
302 template <
class IntPtrT>
304 if (!hasFormat(*DataBuffer))
309 DataBuffer->getBufferStart());
310 ShouldSwapBytes = Header->Magic != RawInstrProf::getMagic<IntPtrT>();
314 template <
class IntPtrT>
316 const char *End = DataBuffer->getBufferEnd();
318 while (CurrentPos != End && *CurrentPos == 0)
321 if (CurrentPos == End)
328 if (reinterpret_cast<size_t>(CurrentPos) %
alignof(uint64_t))
331 uint64_t
Magic = *
reinterpret_cast<const uint64_t *
>(CurrentPos);
332 if (Magic !=
swap(RawInstrProf::getMagic<IntPtrT>()))
340 template <
class IntPtrT>
343 return error(std::move(
E));
345 const IntPtrT FPtr =
swap(
I->FunctionPointer);
353 template <
class IntPtrT>
360 CountersDelta =
swap(Header.CountersDelta);
361 NamesDelta =
swap(Header.NamesDelta);
362 auto DataSize =
swap(Header.DataSize);
363 auto CountersSize =
swap(Header.CountersSize);
364 NamesSize =
swap(Header.NamesSize);
365 ValueKindLast =
swap(Header.ValueKindLast);
368 auto PaddingSize = getNumPaddingBytes(NamesSize);
371 ptrdiff_t CountersOffset = DataOffset + DataSizeInBytes;
372 ptrdiff_t NamesOffset = CountersOffset +
sizeof(uint64_t) * CountersSize;
373 ptrdiff_t ValueDataOffset = NamesOffset + NamesSize + PaddingSize;
375 auto *Start =
reinterpret_cast<const char *
>(&Header);
376 if (Start + ValueDataOffset > DataBuffer->getBufferEnd())
381 DataEnd =
Data + DataSize;
382 CountersStart =
reinterpret_cast<const uint64_t *
>(Start + CountersOffset);
383 NamesStart = Start + NamesOffset;
384 ValueDataStart =
reinterpret_cast<const uint8_t *
>(Start + ValueDataOffset);
386 std::unique_ptr<InstrProfSymtab> NewSymtab = make_unique<InstrProfSymtab>();
387 if (
Error E = createSymtab(*NewSymtab.get()))
390 Symtab = std::move(NewSymtab);
394 template <
class IntPtrT>
400 template <
class IntPtrT>
406 template <
class IntPtrT>
410 IntPtrT CounterPtr =
Data->CounterPtr;
411 if (NumCounters == 0)
414 auto RawCounts =
makeArrayRef(getCounter(CounterPtr), NumCounters);
415 auto *NamesStartAsCounter =
reinterpret_cast<const uint64_t *
>(NamesStart);
418 if (RawCounts.data() < CountersStart ||
419 RawCounts.data() + RawCounts.size() > NamesStartAsCounter)
422 if (ShouldSwapBytes) {
424 Record.
Counts.reserve(RawCounts.size());
425 for (uint64_t Count : RawCounts)
428 Record.
Counts = RawCounts;
433 template <
class IntPtrT>
437 CurValueDataSize = 0;
441 NumValueKinds += (
Data->NumValueSites[
I] != 0);
447 ValueProfData::getValueProfData(
448 ValueDataStart, (
const unsigned char *)DataBuffer->getBufferEnd(),
449 getDataEndianness());
457 VDataPtrOrErr.
get()->deserializeTo(Record, Symtab.get());
458 CurValueDataSize = VDataPtrOrErr.
get()->getSize();
462 template <
class IntPtrT>
466 if (
Error E = readNextHeader(getNextHeaderPos()))
467 return error(std::move(
E));
470 if (
Error E = readName(Record))
471 return error(std::move(
E));
474 if (
Error E = readFuncHash(Record))
475 return error(std::move(
E));
478 if (
Error E = readRawCounts(Record))
479 return error(std::move(
E));
482 if (
Error E = readValueProfilingData(Record))
483 return error(std::move(
E));
506 const unsigned char *&
D,
const unsigned char *
const End) {
508 ValueProfData::getValueProfData(D, End, ValueProfDataEndianness);
513 VDataPtrOrErr.
get()->deserializeTo(DataBuffer.back(),
nullptr);
514 D += VDataPtrOrErr.
get()->TotalSize;
521 using namespace support;
524 if (N %
sizeof(uint64_t))
528 std::vector<uint64_t> CounterBuffer;
530 const unsigned char *End = D +
N;
533 if (D +
sizeof(uint64_t) >= End)
535 uint64_t Hash = endian::readNext<uint64_t, little, unaligned>(
D);
538 uint64_t CountsSize = N /
sizeof(uint64_t) - 1;
541 if (D +
sizeof(uint64_t) > End)
543 CountsSize = endian::readNext<uint64_t, little, unaligned>(
D);
546 if (D + CountsSize *
sizeof(uint64_t) > End)
549 CounterBuffer.clear();
550 CounterBuffer.reserve(CountsSize);
551 for (uint64_t J = 0; J < CountsSize; ++J)
552 CounterBuffer.push_back(endian::readNext<uint64_t, little, unaligned>(D));
554 DataBuffer.emplace_back(K, Hash, std::move(CounterBuffer));
558 !readValueProfilingData(D, End)) {
566 template <
typename HashTableImpl>
569 auto Iter = HashTable->find(FuncName);
570 if (Iter == HashTable->end())
580 template <
typename HashTableImpl>
586 Data = *RecordIterator;
594 template <
typename HashTableImpl>
596 const unsigned char *Buckets,
const unsigned char *
const Payload,
600 HashTable.reset(HashTableImpl::Create(
601 Buckets, Payload, Base,
602 typename HashTableImpl::InfoType(HashType, Version)));
603 RecordIterator = HashTable->data_begin();
623 template <
typename HashTableImpl>
628 std::unique_ptr<MemoryBuffer> RemapBuffer,
630 : RemapBuffer(
std::move(RemapBuffer)), Underlying(Underlying) {
638 std::pair<StringRef, StringRef> Parts = {
StringRef(), Name};
640 Parts = Parts.second.
split(
':');
641 if (Parts.first.startswith(
"_Z"))
643 if (Parts.second.empty())
660 if (
Error E = Remappings.read(*RemapBuffer))
664 if (
auto Key = Remappings.insert(RealName)) {
668 MappedNames.insert({
Key, RealName});
676 StringRef RealName = extractName(FuncName);
677 if (
auto Key = Remappings.lookup(RealName)) {
679 if (!Remapped.
empty()) {
681 RealName.
end() == FuncName.
end())
686 reconstituteName(FuncName, RealName, Remapped, Reconstituted);
694 std::move(E), [](std::unique_ptr<InstrProfError> Err) {
697 :
Error(std::move(Err));
709 std::unique_ptr<MemoryBuffer> RemapBuffer;
725 using namespace support;
730 endian::read<uint64_t, little, aligned>(DataBuffer.
getBufferStart());
735 const unsigned char *
737 const unsigned char *Cur) {
738 using namespace IndexedInstrProf;
739 using namespace support;
750 std::unique_ptr<IndexedInstrProf::Summary> SummaryData =
753 const uint64_t *Src =
reinterpret_cast<const uint64_t *
>(SummaryInLE);
754 uint64_t *Dst =
reinterpret_cast<uint64_t *
>(SummaryData.get());
755 for (
unsigned I = 0;
I < SummarySize /
sizeof(uint64_t);
I++)
756 Dst[
I] = endian::byte_swap<uint64_t, little>(Src[
I]);
759 for (
unsigned I = 0; I < SummaryData->NumCutoffEntries; I++) {
765 this->Summary = llvm::make_unique<ProfileSummary>(
767 SummaryData->get(Summary::TotalBlockCount),
768 SummaryData->get(Summary::MaxBlockCount),
769 SummaryData->get(Summary::MaxInternalBlockCount),
770 SummaryData->get(Summary::MaxFunctionCount),
771 SummaryData->get(Summary::TotalNumBlocks),
772 SummaryData->get(Summary::TotalNumFunctions));
773 return Cur + SummarySize;
776 using namespace IndexedInstrProf;
787 using namespace support;
789 const unsigned char *Start =
790 (
const unsigned char *)DataBuffer->getBufferStart();
791 const unsigned char *Cur = Start;
792 if ((
const unsigned char *)DataBuffer->getBufferEnd() - Cur < 24)
799 uint64_t
Magic = endian::byte_swap<uint64_t, little>(Header->Magic);
804 uint64_t FormatVersion = endian::byte_swap<uint64_t, little>(Header->Version);
805 if (GET_VERSION(FormatVersion) >
813 endian::byte_swap<uint64_t, little>(Header->HashType));
817 uint64_t HashOffset = endian::byte_swap<uint64_t, little>(Header->HashOffset);
821 llvm::make_unique<InstrProfReaderIndex<OnDiskHashTableImplV3>>(
822 Start + HashOffset, Cur, Start,
HashType, FormatVersion);
825 if (RemappingBuffer) {
828 std::move(RemappingBuffer), *IndexPtr);
829 if (
Error E = Remapper->populateRemappings())
832 Remapper = llvm::make_unique<InstrProfReaderNullRemapper>(*IndexPtr);
834 Index = std::move(IndexPtr);
841 return *Symtab.get();
843 std::unique_ptr<InstrProfSymtab> NewSymtab = make_unique<InstrProfSymtab>();
844 if (
Error E =
Index->populateSymtab(*NewSymtab.get())) {
848 Symtab = std::move(NewSymtab);
849 return *Symtab.get();
856 Error Err = Remapper->getRecords(FuncName, Data);
858 return std::move(Err);
860 for (
unsigned I = 0,
E = Data.
size();
I <
E; ++
I) {
862 if (Data[
I].Hash == FuncHash) {
863 return std::move(Data[
I]);
871 std::vector<uint64_t> &Counts) {
874 return error(std::move(
E));
876 Counts = Record.
get().Counts;
885 return error(std::move(E));
887 Record = Data[RecordIndex++];
888 if (RecordIndex >= Data.
size()) {
889 Index->advanceToNextKey();
#define VP_READ_ADVANCE(Val)
Represents either an error or a value T.
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
Error readHeader() override
Read the header. Required before reading first record.
static uint32_t getSize(uint32_t NumSumFields, uint32_t NumCutoffEntries)
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
uint64_t NumCutoffEntries
bool isPrint(char C)
Checks whether character C is printable.
This class represents lattice values for constants.
uint64_t MinBlockCount
The minimum execution count for this percentile.
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
void addValueData(uint32_t ValueKind, uint32_t Site, InstrProfValueData *VData, uint32_t N, InstrProfSymtab *SymTab)
Add ValueData for ValueKind at value Site.
static bool hasFormat(const MemoryBuffer &DataBuffer)
Return true if the given buffer is in an indexed instrprof format.
static instrprof_error take(Error E)
Consume an Error and return the raw enum value contained within it.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
static bool isExternalSymbol(const StringRef &Symbol)
True if Symbol is the value used to represent external symbols.
A remapper that applies remappings based on a symbol remapping file.
Error error(instrprof_error Err)
Set the current error and return same.
std::unique_ptr< Summary > allocSummary(uint32_t TotalSize)
static const ArrayRef< uint32_t > DefaultCutoffs
A vector of useful cutoff values for detailed summary.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
InstrProfSymtab & getSymtab() override
Return the PGO symtab.
size_t getBufferSize() const
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&... args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
Error takeError()
Take ownership of the stored error.
void reserve(size_type N)
InstrProfLookupTrait::offset_type offset_type
Error readNextRecord(NamedInstrProfRecord &Record) override
Read a single record.
void reserveSites(uint32_t ValueKind, uint32_t NumValueSites)
Reserve space for NumValueSites sites.
Error readHeader() override
Read the header.
data_type ReadData(StringRef K, const unsigned char *D, offset_type N)
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Expected< std::unique_ptr< InstrProfReader > > create(const Twine &Path)
Factory method to create an appropriately typed reader for the given instrprof file.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
static StringRef getName(Value *V)
Tagged union holding either a T or a Error.
uint64_t NumSummaryFields
void mapAddress(uint64_t Addr, uint64_t MD5Val)
Map a function address to its name's MD5 hash.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if the given buffer is in text instrprof format.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static StringRef extractName(StringRef Name)
Extract the original function name from a PGO function name.
Reader for the simple text based instrprof format.
uint64_t NumBlocks
Number of blocks >= the minumum execution count.
Error getRecords(StringRef FuncName, ArrayRef< NamedInstrProfRecord > &Data) override
static bool hasFormat(const MemoryBuffer &DataBuffer)
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
InstrProfLookupTrait::data_type data_type
hash_value_type ComputeHash(StringRef K)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
ArrayRef< NamedInstrProfRecord > data_type
Base class and interface for reading profiling data of any known instrprof format.
uint64_t Cutoff
The required percentile of total execution count.
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
std::error_code getError() const
bool readValueProfilingData(const unsigned char *&D, const unsigned char *const End)
std::unique_ptr< InstrProfSymtab > Symtab
std::underlying_type< E >::type Underlying(E Val)
Check that Val is in range for E, and return Val cast to E's underlying type.
uint64_t ComputeHash(StringRef K)
virtual Error getRecords(ArrayRef< NamedInstrProfRecord > &Data)=0
Error getRecords(ArrayRef< NamedInstrProfRecord > &Data) override
void consumeError(Error Err)
Consume a Error without doing anything.
#define CHECK_LINE_END(Line)
#define READ_NUM(Str, Dst)
void clearValueData()
Clear value data entries.
static const char *const Magic
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Path)
Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
Name matcher supporting fuzzy matching of symbol names to names in profiles.
static ErrorSuccess success()
Create a success value.
Error readNextRecord(NamedInstrProfRecord &Record) override
Read a single record.
RawInstrProfReader< uint32_t > RawInstrProfReader32
std::unique_ptr< ProfileSummary > getSummary()
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
A file format agnostic iterator over profiling data.
Reader for the raw instrprof binary format from runtime.
reference get()
Returns a reference to the stored T value.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
RawInstrProfReader< uint64_t > RawInstrProfReader64
This interface provides simple read-only access to a block of memory, and provides simple methods for...
InstrProfReaderIndex(const unsigned char *Buckets, const unsigned char *const Payload, const unsigned char *const Base, IndexedInstrProf::HashT HashType, uint64_t Version)
InstrProfReaderItaniumRemapper(std::unique_ptr< MemoryBuffer > RemapBuffer, InstrProfReaderIndex< HashTableImpl > &Underlying)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Error readNextRecord(NamedInstrProfRecord &Record) override
Read a single record.
iterator insert(iterator I, T &&Elt)
unsigned char getSwappedBytes(unsigned char C)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
std::vector< uint64_t > Counts
Error readHeader() override
Read the file header.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
virtual Error readHeader()=0
Read the header. Required before reading first record.
Profiling information for a single function.
Expected< InstrProfRecord > getInstrProfRecord(StringRef FuncName, uint64_t FuncHash)
Return the NamedInstrProfRecord associated with FuncName and FuncHash.
Reader for symbol remapping files.
static void reconstituteName(StringRef OrigName, StringRef ExtractedName, StringRef Replacement, SmallVectorImpl< char > &Out)
Given a mangled name extracted from a PGO function name, and a new form for that mangled name...
Error populateRemappings() override
const char * getBufferStart() const
std::string str() const
Return the twine contents as a std::string.
Provides ErrorOr<T> smart pointer.
LLVM Value Representation.
Lightweight error class with error context and mandatory checking.
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
StringRef - Represent a constant reference to a string, i.e.
Reader for the indexed binary instrprof format.
std::vector< ProfileSummaryEntry > SummaryEntryVector
static Expected< std::unique_ptr< IndexedInstrProfReader > > create(const Twine &Path, const Twine &RemappingPath="")
Factory method to create an indexed reader.
void Clear()
Clear value data entries and edge counters.
bool empty() const
empty - Check if the array is empty.
Error success()
Clear the current error and return a successful one.
Error getFunctionCounts(StringRef FuncName, uint64_t FuncHash, std::vector< uint64_t > &Counts)
Fill Counts with the profile data for the given function name.
static Error initializeReader(InstrProfReader &Reader)