1//===- InstrProfReader.cpp - Instrumented profiling reader ----------------===// 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 7//===----------------------------------------------------------------------===// 9// This file contains support for reading profiling data for clang's 10// instrumentation based PGO and coverage. 12//===----------------------------------------------------------------------===// 36#include <system_error> 42// Extracts the variant information from the top 32 bits in the version and 43// returns an enum specifying the variants present. 46if (Version & VARIANT_MASK_IR_PROF) {
47 ProfileKind |= InstrProfKind::IRInstrumentation;
49if (Version & VARIANT_MASK_CSIR_PROF) {
50 ProfileKind |= InstrProfKind::ContextSensitive;
52if (Version & VARIANT_MASK_INSTR_ENTRY) {
53 ProfileKind |= InstrProfKind::FunctionEntryInstrumentation;
55if (Version & VARIANT_MASK_INSTR_LOOP_ENTRIES) {
56 ProfileKind |= InstrProfKind::LoopEntriesInstrumentation;
58if (Version & VARIANT_MASK_BYTE_COVERAGE) {
59 ProfileKind |= InstrProfKind::SingleByteCoverage;
61if (Version & VARIANT_MASK_FUNCTION_ENTRY_ONLY) {
62 ProfileKind |= InstrProfKind::FunctionEntryOnly;
64if (Version & VARIANT_MASK_MEMPROF) {
65 ProfileKind |= InstrProfKind::MemProf;
67if (Version & VARIANT_MASK_TEMPORAL_PROF) {
68 ProfileKind |= InstrProfKind::TemporalProfile;
76 : FS.getBufferForFile(Filename);
77if (std::error_code EC = BufferOrErr.getError())
79return std::move(BufferOrErr.get());
86/// Read a list of binary ids from a profile that consist of 87/// a. uint64_t binary id length 88/// b. uint8_t binary id data 89/// c. uint8_t padding (if necessary) 90/// This function is shared between raw and indexed profiles. 91/// Raw profiles are in host-endian format, and indexed profiles are in 92/// little-endian format. So, this function takes an argument indicating the 93/// associated endian format to read the binary ids correctly. 97 std::vector<llvm::object::BuildID> &BinaryIds,
99using namespacesupport;
102constuint8_t *BinaryIdsStart = BinaryIdsBuffer.
data();
104if (BinaryIdsSize == 0)
107constuint8_t *BI = BinaryIdsStart;
108constuint8_t *BIEnd = BinaryIdsStart + BinaryIdsSize;
113size_t Remaining = BIEnd - BI;
114// There should be enough left to read the binary id length. 116return make_error<InstrProfError>(
117 instrprof_error::malformed,
118"not enough data to read binary id length");
122return make_error<InstrProfError>(instrprof_error::malformed,
123"binary id length is 0");
125 Remaining = BIEnd - BI;
126// There should be enough left to read the binary id data. 128return make_error<InstrProfError>(
129 instrprof_error::malformed,
"not enough data to read binary id data");
131// Add binary id to the binary ids list. 134// Increment by binary id data length, which aligned to the size of uint64. 137return make_error<InstrProfError>(
138 instrprof_error::malformed,
139"binary id section is greater than buffer size");
147OS <<
"Binary IDs: \n";
148for (
constauto &BI : BinaryIds) {
160 std::function<
void(
Error)> Warn) {
161// Set up the buffer to read. 163if (
Error E = BufferOrError.takeError())
166 BIDFetcher, BIDFetcherCorrelatorKind, Warn);
173 std::function<
void(
Error)> Warn) {
174if (Buffer->getBufferSize() == 0)
177 std::unique_ptr<InstrProfReader> Result;
183 BIDFetcher, BIDFetcherCorrelatorKind,
187 BIDFetcher, BIDFetcherCorrelatorKind,
194// Initialize the reader and return the result. 198return std::move(Result);
203constTwine &RemappingPath) {
204// Set up the buffer to read. 206if (
Error E = BufferOrError.takeError())
209// Set up the remapping buffer if requested. 210 std::unique_ptr<MemoryBuffer> RemappingBuffer;
211 std::string RemappingPathStr = RemappingPath.
str();
212if (!RemappingPathStr.empty()) {
214if (
Error E = RemappingBufferOrError.takeError())
216 RemappingBuffer = std::move(RemappingBufferOrError.get());
220 std::move(RemappingBuffer));
225 std::unique_ptr<MemoryBuffer> RemappingBuffer) {
229auto Result = std::make_unique<IndexedInstrProfReader>(
230 std::move(Buffer), std::move(RemappingBuffer));
232// Initialize the reader and return the result. 236return std::move(Result);
240// Verify that this really looks like plain ASCII text by checking a 241// 'reasonable' number of characters (up to profile magic size). 246 [](
char c) { return isPrint(c) || isSpace(c); });
249// Read the profile variant flag from the header: ":FE" means this is a FE 250// generated profile. ":IR" means this is an IR level profile. Other strings 251// with a leading ':' will be reported an error format. 257if (Str.equals_insensitive(
"ir"))
259elseif (Str.equals_insensitive(
"fe"))
261elseif (Str.equals_insensitive(
"csir")) {
264 }
elseif (Str.equals_insensitive(
"entry_first"))
266elseif (Str.equals_insensitive(
"not_entry_first"))
268elseif (Str.equals_insensitive(
"instrument_loop_entries"))
270elseif (Str.equals_insensitive(
"single_byte_coverage"))
272elseif (Str.equals_insensitive(
"temporal_prof_traces")) {
274if (
auto Err = readTemporalProfTraceData())
275returnerror(std::move(Err));
283/// Temporal profile trace data is stored in the header immediately after 284/// ":temporal_prof_traces". The first integer is the number of traces, the 285/// second integer is the stream size, then the following lines are the actual 286/// traces which consist of a weight and a comma separated list of function 288Error TextInstrProfReader::readTemporalProfTraceData() {
289if ((++Line).is_at_end())
296if ((++Line).is_at_end())
302for (
uint32_t i = 0; i < NumTraces; i++) {
303if ((++Line).is_at_end())
310if ((++Line).is_at_end())
314 Line->
split(FuncNames,
",",
/*MaxSplit=*/-1,
/*KeepEmpty=*/false);
315for (
auto &FuncName : FuncNames)
316Trace.FunctionNameRefs.push_back(
326#define CHECK_LINE_END(Line) \ 327 if (Line.is_at_end()) \ 328 return error(instrprof_error::truncated); 329#define READ_NUM(Str, Dst) \ 330 if ((Str).getAsInteger(10, (Dst))) \ 331 return error(instrprof_error::malformed); 332#define VP_READ_ADVANCE(Val) \ 333 CHECK_LINE_END(Line); \ 335 READ_NUM((*Line), (Val)); \ 343// No value profile data 346if (NumValueKinds == 0 || NumValueKinds > IPVK_Last + 1)
348"number of value kinds is invalid");
351for (
uint32_t VK = 0; VK < NumValueKinds; VK++) {
353if (ValueKind > IPVK_Last)
360Record.reserveSites(VK, NumValueSites);
361for (
uint32_t S = 0; S < NumValueSites; S++) {
364 std::vector<InstrProfValueData> CurrentValues;
367 std::pair<StringRef, StringRef> VD = Line->
rsplit(
':');
369if (ValueKind == IPVK_IndirectCallTarget) {
377 }
elseif (ValueKind == IPVK_VTableTarget) {
389 CurrentValues.push_back({
Value, TakenCount});
392assert(CurrentValues.size() == NumValueData);
393Record.addValueData(ValueKind, S, CurrentValues,
nullptr);
400#undef VP_READ_ADVANCE 404// Skip empty lines and comments. 407// If we hit EOF while looking for a name, we're done. 412// Read the function name. 415returnerror(std::move(E));
417// Read the function hash. 420if ((Line++)->getAsInteger(0,
Record.Hash))
422"function hash is not a valid integer");
424// Read the number of counters. 428if ((Line++)->getAsInteger(10, NumCounters))
430"number of counters is not a valid integer");
434// Read each counter and fill our internal storage with the values. 436Record.Counts.reserve(NumCounters);
441if ((Line++)->getAsInteger(10, Count))
443Record.Counts.push_back(Count);
446// Bitmap byte information is indicated with special character. 448Record.BitmapBytes.clear();
449// Read the number of bitmap bytes. 451if ((Line++)->drop_front(1).trim().getAsInteger(0, NumBitmapBytes))
453"number of bitmap bytes is not a valid integer");
454if (NumBitmapBytes != 0) {
455// Read each bitmap and fill our internal storage with the values. 456Record.BitmapBytes.reserve(NumBitmapBytes);
461if ((Line++)->getAsInteger(0, BitmapByte))
463"bitmap byte is not a valid integer");
464Record.BitmapBytes.push_back(BitmapByte);
469// Check if value profile data exists and read it if so. 471returnerror(std::move(E));
476template <
class IntPtrT>
481template <
class IntPtrT>
484 std::optional<uint64_t> Weight) {
485if (TemporalProfTimestamps.empty()) {
486assert(TemporalProfTraces.empty());
487return TemporalProfTraces;
489// Sort functions by their timestamps to build the trace. 490 std::sort(TemporalProfTimestamps.begin(), TemporalProfTimestamps.end());
493Trace.Weight = *Weight;
494for (
auto &[TimestampValue, NameRef] : TemporalProfTimestamps)
495Trace.FunctionNameRefs.push_back(NameRef);
496 TemporalProfTraces = {std::move(
Trace)};
497return TemporalProfTraces;
500template <
class IntPtrT>
506return RawInstrProf::getMagic<IntPtrT>() == Magic ||
510template <
class IntPtrT>
512if (!hasFormat(*DataBuffer))
517 DataBuffer->getBufferStart());
518 ShouldSwapBytes = Header->Magic != RawInstrProf::getMagic<IntPtrT>();
519return readHeader(*Header);
522template <
class IntPtrT>
524constchar *
End = DataBuffer->getBufferEnd();
525// Skip zero padding between profiles. 526while (CurrentPos !=
End && *CurrentPos == 0)
528// If there's nothing left, we're done. 531// If there isn't enough space for another header, this is probably just 532// garbage at the end of the file. 535"not enough space for another header");
536// The writer ensures each profile is padded to start at an aligned address. 537if (
reinterpret_cast<size_t>(CurrentPos) %
alignof(
uint64_t))
539"insufficient padding");
540// The magic should have the same byte order as in the previous header. 542if (Magic != swap(RawInstrProf::getMagic<IntPtrT>()))
545// There's another profile to read, so we need to process the header. 547return readHeader(*Header);
550template <
class IntPtrT>
553StringRef(VNamesStart, VNamesEnd - VNamesStart)))
554returnerror(std::move(E));
556constIntPtrT FPtr = swap(
I->FunctionPointer);
562if (VTableBegin !=
nullptr && VTableEnd !=
nullptr) {
564I != VTableEnd; ++
I) {
568// Map both begin and end address to the name hash, since the instrumented 569// address could be somewhere in the middle. 570// VPtr is of type uint32_t or uint64_t so 'VPtr + I->VTableSize' marks 571// the end of vtable address. 573swap(
I->VTableNameHash));
579template <
class IntPtrT>
585 (
"Profile uses raw profile format version = " +
588"\nPLEASE update this tool to version in the raw profile, or " 589"regenerate raw profile with expected version.")
593// Binary id start just after the header if exists. 596constuint8_t *BinaryIdEnd = BinaryIdStart + BinaryIdSize;
597constuint8_t *BufferEnd = (
constuint8_t *)DataBuffer->getBufferEnd();
598if (BinaryIdSize %
sizeof(
uint64_t) || BinaryIdEnd > BufferEnd)
601if (!BinaryIdsBuffer.empty()) {
603 BinaryIds, getDataEndianness()))
607 CountersDelta =
swap(Header.CountersDelta);
608 BitmapDelta =
swap(Header.BitmapDelta);
609 NamesDelta =
swap(Header.NamesDelta);
610auto NumData =
swap(Header.NumData);
611auto PaddingBytesBeforeCounters =
swap(Header.PaddingBytesBeforeCounters);
612auto CountersSize =
swap(Header.NumCounters) * getCounterTypeSize();
613auto PaddingBytesAfterCounters =
swap(Header.PaddingBytesAfterCounters);
614auto NumBitmapBytes =
swap(Header.NumBitmapBytes);
615auto PaddingBytesAfterBitmapBytes =
swap(Header.PaddingBytesAfterBitmapBytes);
616auto NamesSize =
swap(Header.NamesSize);
617auto VTableNameSize =
swap(Header.VNamesSize);
618auto NumVTables =
swap(Header.NumVTables);
619 ValueKindLast =
swap(Header.ValueKindLast);
622auto PaddingBytesAfterNames = getNumPaddingBytes(NamesSize);
623auto PaddingBytesAfterVTableNames = getNumPaddingBytes(VTableNameSize);
625auto VTableSectionSize =
627auto PaddingBytesAfterVTableProfData = getNumPaddingBytes(VTableSectionSize);
629// Profile data starts after profile header and binary ids if exist. 631ptrdiff_t CountersOffset = DataOffset + DataSize + PaddingBytesBeforeCounters;
633 CountersOffset + CountersSize + PaddingBytesAfterCounters;
635 BitmapOffset + NumBitmapBytes + PaddingBytesAfterBitmapBytes;
637 NamesOffset + NamesSize + PaddingBytesAfterNames;
638ptrdiff_t VTableNameOffset = VTableProfDataOffset + VTableSectionSize +
639 PaddingBytesAfterVTableProfData;
641 VTableNameOffset + VTableNameSize + PaddingBytesAfterVTableNames;
643auto *Start =
reinterpret_cast<constchar *
>(&Header);
644if (Start + ValueDataOffset > DataBuffer->getBufferEnd())
648 std::vector<object::BuildID> BinaryIDs;
649if (
Error E = readBinaryIds(BinaryIDs))
652 BIDFetcher, BinaryIDs)
653 .moveInto(BIDFetcherCorrelator)) {
656if (
auto Err = BIDFetcherCorrelator->correlateProfileData(0))
661// These sizes in the raw file are zero because we constructed them in the 663if (!(DataSize == 0 && NamesSize == 0 && CountersDelta == 0 &&
666Data = Correlator->getDataPointer();
670 }
elseif (BIDFetcherCorrelator) {
672 dyn_cast_or_null<InstrProfCorrelatorImpl<IntPtrT>>(
673 BIDFetcherCorrelator.get());
677 NamesEnd = NamesStart + BIDFetcherCorrelatorImpl->
getNamesSize();
681 DataEnd =
Data + NumData;
684 Start + VTableProfDataOffset);
685 VTableEnd = VTableBegin + NumVTables;
686 NamesStart = Start + NamesOffset;
687 NamesEnd = NamesStart + NamesSize;
688 VNamesStart = Start + VTableNameOffset;
689 VNamesEnd = VNamesStart + VTableNameSize;
692 CountersStart = Start + CountersOffset;
693 CountersEnd = CountersStart + CountersSize;
694 BitmapStart = Start + BitmapOffset;
695 BitmapEnd = BitmapStart + NumBitmapBytes;
696 ValueDataStart =
reinterpret_cast<constuint8_t *
>(Start + ValueDataOffset);
698 std::unique_ptr<InstrProfSymtab> NewSymtab = std::make_unique<InstrProfSymtab>();
699if (
Error E = createSymtab(*NewSymtab))
702 Symtab = std::move(NewSymtab);
706template <
class IntPtrT>
712template <
class IntPtrT>
718template <
class IntPtrT>
726if (CounterBaseOffset < 0)
729 (
"counter offset " +
Twine(CounterBaseOffset) +
" is negative").str());
731if (CounterBaseOffset >= CountersEnd - CountersStart)
733 (
"counter offset " +
Twine(CounterBaseOffset) +
734" is greater than the maximum counter offset " +
735Twine(CountersEnd - CountersStart - 1))
739 (CountersEnd - (CountersStart + CounterBaseOffset)) /
740 getCounterTypeSize();
741if (NumCounters > MaxNumCounters)
743 (
"number of counters " +
Twine(NumCounters) +
744" is greater than the maximum number of counters " +
745Twine(MaxNumCounters))
749Record.Counts.reserve(NumCounters);
752 CountersStart + CounterBaseOffset +
I * getCounterTypeSize();
753if (
I == 0 && hasTemporalProfile()) {
755if (TimestampValue != 0 &&
756 TimestampValue != std::numeric_limits<uint64_t>::max()) {
757 TemporalProfTimestamps.emplace_back(TimestampValue,
759 TemporalProfTraceStreamSize = 1;
761if (hasSingleByteCoverage()) {
762// In coverage mode, getCounterTypeSize() returns 1 byte but our 763// timestamp field has size uint64_t. Increment I so that the next 764// iteration of this for loop points to the byte after the timestamp 765// field, i.e., I += 8. 770if (hasSingleByteCoverage()) {
771// A value of zero signifies the block is covered. 772Record.Counts.push_back(*
Ptr == 0 ? 1 : 0);
775if (CounterValue > MaxCounterValue && Warn)
776 Warn(make_error<InstrProfError>(
779Record.Counts.push_back(CounterValue);
786template <
class IntPtrT>
790Record.BitmapBytes.clear();
791Record.BitmapBytes.reserve(NumBitmapBytes);
793// It's possible MCDC is either not enabled or only used for some functions 794// and not others. So if we record 0 bytes, just move on. 795if (NumBitmapBytes == 0)
798// BitmapDelta decreases as we advance to the next data record. 803 (
"bitmap offset " +
Twine(BitmapOffset) +
" is negative").str());
805if (BitmapOffset >= BitmapEnd - BitmapStart)
807 (
"bitmap offset " +
Twine(BitmapOffset) +
808" is greater than the maximum bitmap offset " +
809Twine(BitmapEnd - BitmapStart - 1))
813 (BitmapEnd - (BitmapStart + BitmapOffset)) /
sizeof(
uint8_t);
814if (NumBitmapBytes > MaxNumBitmapBytes)
816 (
"number of bitmap bytes " +
Twine(NumBitmapBytes) +
817" is greater than the maximum number of bitmap bytes " +
818Twine(MaxNumBitmapBytes))
822constchar *
Ptr = BitmapStart + BitmapOffset +
I;
829template <
class IntPtrT>
833 CurValueDataSize = 0;
834// Need to match the logic in value profile dumper code in compiler-rt: 837 NumValueKinds += (
Data->NumValueSites[
I] != 0);
843 ValueProfData::getValueProfData(
844 ValueDataStart, (
constunsignedchar *)DataBuffer->getBufferEnd(),
845 getDataEndianness());
850// Note that besides deserialization, this also performs the conversion for 851// indirect call targets. The function pointers from the raw profile are 852// remapped into function name hashes. 853 VDataPtrOrErr.
get()->deserializeTo(
Record, Symtab.get());
854 CurValueDataSize = VDataPtrOrErr.
get()->getSize();
858template <
class IntPtrT>
860// Keep reading profiles that consist of only headers and no profile data and 863// At this point, ValueDataStart field points to the next header. 864if (
Error E = readNextHeader(getNextHeaderPos()))
865returnerror(std::move(E));
867// Read name and set it in Record. 869returnerror(std::move(E));
871// Read FuncHash and set it in Record. 873returnerror(std::move(E));
875// Read raw counts and set Record. 877returnerror(std::move(E));
879// Read raw bitmap bytes and set Record. 881returnerror(std::move(E));
883// Read value data and set Record. 885returnerror(std::move(E));
892template <
class IntPtrT>
894 std::vector<llvm::object::BuildID> &BinaryIds) {
895 BinaryIds.insert(BinaryIds.begin(), this->BinaryIds.begin(),
896 this->BinaryIds.end());
900template <
class IntPtrT>
902if (!BinaryIds.empty())
912}
// end namespace llvm 923constunsignedchar *&
D,
constunsignedchar *
constEnd) {
925 ValueProfData::getValueProfData(
D,
End, ValueProfDataEndianness);
930 VDataPtrOrErr.
get()->deserializeTo(DataBuffer.back(),
nullptr);
931D += VDataPtrOrErr.
get()->TotalSize;
938using namespacesupport;
940// Check if the data is corrupt. If so, don't try to read it. 945 std::vector<uint64_t> CounterBuffer;
946 std::vector<uint8_t> BitmapByteBuffer;
948constunsignedchar *
End =
D +
N;
953uint64_t Hash = endian::readNext<uint64_t, llvm::endianness::little>(
D);
955// Initialize number of counters for GET_VERSION(FormatVersion) == 1. 957// If format version is different then read the number of counters. 961 CountsSize = endian::readNext<uint64_t, llvm::endianness::little>(
D);
963// Read counter values. 967 CounterBuffer.clear();
968 CounterBuffer.reserve(CountsSize);
969for (
uint64_t J = 0; J < CountsSize; ++J)
970 CounterBuffer.push_back(
971 endian::readNext<uint64_t, llvm::endianness::little>(
D));
973// Read bitmap bytes for GET_VERSION(FormatVersion) > 10. 978 BitmapBytes = endian::readNext<uint64_t, llvm::endianness::little>(
D);
979// Read bitmap byte values. 982 BitmapByteBuffer.clear();
983 BitmapByteBuffer.reserve(BitmapBytes);
984for (
uint64_t J = 0; J < BitmapBytes; ++J)
985 BitmapByteBuffer.push_back(
static_cast<uint8_t>(
986 endian::readNext<uint64_t, llvm::endianness::little>(
D)));
989 DataBuffer.emplace_back(K, Hash, std::move(CounterBuffer),
990 std::move(BitmapByteBuffer));
992// Read value profiling data. 1002template <
typename HashTableImpl>
1005auto Iter = HashTable->find(FuncName);
1006if (Iter == HashTable->end())
1012"profile data is empty");
1017template <
typename HashTableImpl>
1023Data = *RecordIterator;
1027"profile data is empty");
1032template <
typename HashTableImpl>
1034constunsignedchar *Buckets,
constunsignedchar *
const Payload,
1038 HashTable.reset(HashTableImpl::Create(
1039 Buckets, Payload,
Base,
1040typename HashTableImpl::InfoType(HashType,
Version)));
1041 RecordIterator = HashTable->data_begin();
1044template <
typename HashTableImpl>
1050/// A remapper that does not apply any remappings. 1056 : Underlying(Underlying) {}
1060return Underlying.getRecords(FuncName, Data);
1065/// A remapper that applies remappings based on a symbol remapping file. 1066template <
typename HashTableImpl>
1071 std::unique_ptr<MemoryBuffer> RemapBuffer,
1073 : RemapBuffer(
std::
move(RemapBuffer)), Underlying(Underlying) {
1076 /// Extract the original function name from a PGO function name. 1078// We can have multiple pieces separated by kGlobalIdentifierDelimiter ( 1079// semicolon now and colon in older profiles); there can be pieces both 1080// before and after the mangled name. Find the first part that starts with 1081// '_Z'; we'll assume that's the mangled name we want. 1085if (Parts.first.starts_with(
"_Z"))
1087if (Parts.second.empty())
1092 /// Given a mangled name extracted from a PGO function name, and a new 1093 /// form for that mangled name, reconstitute the name. 1104if (
Error E = Remappings.
read(*RemapBuffer))
1108if (
auto Key = Remappings.
insert(RealName)) {
1109// FIXME: We could theoretically map the same equivalence class to 1110// multiple names in the profile data. If that happens, we should 1111// return NamedInstrProfRecords from all of them. 1112 MappedNames.insert({Key, RealName});
1121if (
auto Key = Remappings.
lookup(RealName)) {
1122StringRef Remapped = MappedNames.lookup(Key);
1123if (!Remapped.
empty()) {
1125 RealName.
end() == FuncName.
end())
1126 FuncName = Remapped;
1128// Try rebuilding the name from the given remapping. 1131Error E = Underlying.getRecords(Reconstituted,
Data);
1135// If we failed because the name doesn't exist, fall back to asking 1136// about the original name. 1138 std::move(E), [](std::unique_ptr<InstrProfError> Err) {
1141 :
Error(std::move(Err));
1147return Underlying.getRecords(FuncName,
Data);
1151 /// The memory buffer containing the remapping configuration. Remappings 1152 /// holds pointers into this buffer. 1153 std::unique_ptr<MemoryBuffer> RemapBuffer;
1155 /// The mangling remapper. 1158 /// Mapping from mangled name keys to the name used for the key in the 1160 /// FIXME: Can we store a location within the on-disk hash table instead of 1164 /// The real profile data reader. 1169using namespacesupport;
1173uint64_t Magic = endian::read<uint64_t, llvm::endianness::little, aligned>(
1175// Verify that it's magical. 1181constunsignedchar *Cur,
bool UseCS) {
1182using namespaceIndexedInstrProf;
1183using namespacesupport;
1188uint64_t NFields = endian::byte_swap<uint64_t, llvm::endianness::little>(
1190uint64_t NEntries = endian::byte_swap<uint64_t, llvm::endianness::little>(
1194 std::unique_ptr<IndexedInstrProf::Summary> SummaryData =
1199for (
unsignedI = 0;
I < SummarySize /
sizeof(
uint64_t);
I++)
1200 Dst[
I] = endian::byte_swap<uint64_t, llvm::endianness::little>(Src[
I]);
1203for (
unsignedI = 0;
I < SummaryData->NumCutoffEntries;
I++) {
1208 std::unique_ptr<llvm::ProfileSummary> &Summary =
1209 UseCS ? this->CS_Summary : this->Summary;
1211// initialize InstrProfSummary using the SummaryData from disk. 1212 Summary = std::make_unique<ProfileSummary>(
1214 DetailedSummary, SummaryData->get(Summary::TotalBlockCount),
1215 SummaryData->get(Summary::MaxBlockCount),
1216 SummaryData->get(Summary::MaxInternalBlockCount),
1217 SummaryData->get(Summary::MaxFunctionCount),
1218 SummaryData->get(Summary::TotalNumBlocks),
1219 SummaryData->get(Summary::TotalNumFunctions));
1220return Cur + SummarySize;
1222// The older versions do not support a profile summary. This just computes 1223// an empty summary, which will not result in accurate hot/cold detection. 1224// We would need to call addRecord for all NamedInstrProfRecords to get the 1225// correct summary. However, this version is old (prior to early 2016) and 1226// has not been supporting an accurate summary for several years. 1228 Summary = Builder.getSummary();
1233Error IndexedMemProfReader::deserializeV2(
constunsignedchar *Start,
1234constunsignedchar *
Ptr) {
1235// The value returned from RecordTableGenerator.Emit. 1237 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1238// The offset in the stream right before invoking 1239// FrameTableGenerator.Emit. 1241 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1242// The value returned from FrameTableGenerator.Emit. 1244 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1246// The offset in the stream right before invoking 1247// CallStackTableGenerator.Emit. 1248uint64_t CallStackPayloadOffset = 0;
1249// The value returned from CallStackTableGenerator.Emit. 1252 CallStackPayloadOffset =
1253 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1254 CallStackTableOffset =
1255 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1261return SchemaOr.takeError();
1262 Schema = SchemaOr.get();
1264// Now initialize the table reader with a pointer into data buffer. 1266/*Buckets=*/Start + RecordTableOffset,
1270// Initialize the frame table reader with the payload and bucket offsets. 1272/*Buckets=*/Start + FrameTableOffset,
1273/*Payload=*/Start + FramePayloadOffset,
1278/*Buckets=*/Start + CallStackTableOffset,
1279/*Payload=*/Start + CallStackPayloadOffset,
1285Error IndexedMemProfReader::deserializeV3(
constunsignedchar *Start,
1286constunsignedchar *
Ptr) {
1287// The offset in the stream right before invoking 1288// CallStackTableGenerator.Emit. 1289constuint64_t CallStackPayloadOffset =
1290 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1291// The offset in the stream right before invoking RecordTableGenerator.Emit. 1293 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1294// The value returned from RecordTableGenerator.Emit. 1296 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1301return SchemaOr.takeError();
1302 Schema = SchemaOr.get();
1305 CallStackBase = Start + CallStackPayloadOffset;
1307// Compute the number of elements in the radix tree array. Since we use this 1308// to reserve enough bits in a BitVector, it's totally OK if we overestimate 1309// this number a little bit because of padding just before the next section. 1310 RadixTreeSize = (RecordPayloadOffset - CallStackPayloadOffset) /
1313// Now initialize the table reader with a pointer into data buffer. 1315/*Buckets=*/Start + RecordTableOffset,
1316/*Payload=*/Start + RecordPayloadOffset,
1324constunsignedchar *
Ptr = Start + MemProfOffset;
1326// Read the MemProf version number. 1328 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1331// Everything is good. We can proceed to deserialize the rest. 1334return make_error<InstrProfError>(
1336formatv(
"MemProf version {} not supported; " 1337"requires version between {} and {}, inclusive",
1344if (
Error E = deserializeV2(Start,
Ptr))
1348if (
Error E = deserializeV3(Start,
Ptr))
1357using namespacesupport;
1359constunsignedchar *Start =
1360 (
constunsignedchar *)DataBuffer->getBufferStart();
1361constunsignedchar *Cur = Start;
1362if ((
constunsignedchar *)DataBuffer->getBufferEnd() - Cur < 24)
1367return HeaderOr.takeError();
1370 Cur += Header->size();
1374if (Header->Version & VARIANT_MASK_CSIR_PROF)
1377// Read the hash type and start offset. 1383// The hash table with profile counts comes next. 1384auto IndexPtr = std::make_unique<InstrProfReaderIndex<OnDiskHashTableImplV3>>(
1385 Start + Header->HashOffset, Cur, Start, HashType, Header->Version);
1387// The MemProfOffset field in the header is only valid when the format 1388// version is higher than 8 (when it was introduced). 1389if (Header->getIndexedProfileVersion() >= 8 &&
1390 Header->Version & VARIANT_MASK_MEMPROF) {
1395// BinaryIdOffset field in the header is only valid when the format version 1396// is higher than 9 (when it was introduced). 1397if (Header->getIndexedProfileVersion() >= 9) {
1398constunsignedchar *
Ptr = Start + Header->BinaryIdOffset;
1399// Read binary ids size. 1401 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1402if (BinaryIdsSize %
sizeof(
uint64_t))
1404// Set the binary ids start. 1406if (
Ptr > (
constunsignedchar *)DataBuffer->getBufferEnd())
1408"corrupted binary ids");
1411if (Header->getIndexedProfileVersion() >= 12) {
1412constunsignedchar *
Ptr = Start + Header->VTableNamesOffset;
1415 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1417// Writer first writes the length of compressed string, and then the actual 1419constchar *VTableNamePtr = (
constchar *)
Ptr;
1420if (VTableNamePtr > (
constchar *)DataBuffer->getBufferEnd())
1423 VTableName =
StringRef(VTableNamePtr, CompressedVTableNamesLen);
1426if (Header->getIndexedProfileVersion() >= 10 &&
1427 Header->Version & VARIANT_MASK_TEMPORAL_PROF) {
1428constunsignedchar *
Ptr = Start + Header->TemporalProfTracesOffset;
1429constauto *PtrEnd = (
constunsignedchar *)DataBuffer->getBufferEnd();
1430// Expect at least two 64 bit fields: NumTraces, and TraceStreamSize 1434 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1436 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1437for (
unsigned i = 0; i < NumTraces; i++) {
1438// Expect at least two 64 bit fields: Weight and NumFunctions 1443 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1445 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1446// Expect at least NumFunctions 64 bit fields 1449for (
unsigned j = 0; j < NumFunctions; j++) {
1451 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1452Trace.FunctionNameRefs.push_back(NameRef);
1458// Load the remapping table now if requested. 1459if (RemappingBuffer) {
1461 std::make_unique<InstrProfReaderItaniumRemapper<OnDiskHashTableImplV3>>(
1462 std::move(RemappingBuffer), *IndexPtr);
1463if (
Error E = Remapper->populateRemappings())
1466 Remapper = std::make_unique<InstrProfReaderNullRemapper>(*IndexPtr);
1468 Index = std::move(IndexPtr);
1477auto NewSymtab = std::make_unique<InstrProfSymtab>();
1479if (
Error E = NewSymtab->initVTableNamesFromCompressedStrings(VTableName)) {
1484// finalizeSymtab is called inside populateSymtab. 1485if (
Error E = Index->populateSymtab(*NewSymtab)) {
1490Symtab = std::move(NewSymtab);
1499auto Err = Remapper->getRecords(FuncName,
Data);
1501// If we don't find FuncName, try DeprecatedFuncName to handle profiles 1502// built by older compilers. 1506return make_error<InstrProfError>(IE);
1507if (
auto Err = Remapper->getRecords(DeprecatedFuncName,
Data))
1512return std::move(Err2);
1514// Found it. Look for counters with the right hash. 1516// A flag to indicate if the records are from the same type 1517// of profile (i.e cs vs nocs). 1518bool CSBitMatch =
false;
1521for (
uint64_t CountValue : Counts) {
1524// Handle overflow -- if that happens, return max. 1525if (std::numeric_limits<uint64_t>::max() - CountValue <= ValueSum)
1526return std::numeric_limits<uint64_t>::max();
1527 ValueSum += CountValue;
1533// Check for a match and fill the vector if there is one. 1534if (
I.Hash == FuncHash)
1539if (MismatchedFuncSum ==
nullptr)
1541 FuncSum = std::max(FuncSum, getFuncSum(
I.Counts));
1545if (MismatchedFuncSum !=
nullptr)
1546 *MismatchedFuncSum = FuncSum;
1560 MemProfCallStackTable, FrameIdConv);
1564// Check that all call stack ids were successfully converted to call stacks. 1566return make_error<InstrProfError>(
1568"memprof call stack not found for call stack id " +
1572// Check that all frame ids were successfully converted to frames. 1575"memprof frame not found for frame id " +
1584constunsignedchar *FrameBase,
1585constunsignedchar *CallStackBase) {
1594// TODO: Add memprof specific errors. 1595if (MemProfRecordTable ==
nullptr)
1597"no memprof data available in profile");
1598auto Iter = MemProfRecordTable->find(FuncNameHash);
1599if (Iter == MemProfRecordTable->end())
1600return make_error<InstrProfError>(
1602"memprof record not found for function hash " +
Twine(FuncNameHash));
1607assert(MemProfFrameTable &&
"MemProfFrameTable must be available");
1608assert(MemProfCallStackTable &&
"MemProfCallStackTable must be available");
1610 *MemProfCallStackTable);
1612assert(!MemProfFrameTable &&
"MemProfFrameTable must not be available");
1613assert(!MemProfCallStackTable &&
1614"MemProfCallStackTable must not be available");
1615assert(FrameBase &&
"FrameBase must be available");
1616assert(CallStackBase &&
"CallStackBase must be available");
1620return make_error<InstrProfError>(
1622formatv(
"MemProf version {} not supported; " 1623"requires version between {} and {}, inclusive",
1630assert(MemProfRecordTable);
1637// The set of linear call stack IDs that we need to traverse from. We expect 1638// the set to be dense, so we use a BitVector. 1641// Collect the set of linear call stack IDs. Since we expect a lot of 1642// duplicates, we first collect them in the form of a bit vector before 1645 MemProfRecordTable->data()) {
1647 IndexedRecord.AllocSites)
1651// Collect caller-callee pairs for each linear call stack ID in Worklist. 1652for (
unsigned CS : Worklist.
set_bits())
1658// Sort each call list by the source location. 1659for (
auto &[CallerGUID, CallList] : Pairs) {
1661 CallList.erase(
llvm::unique(CallList), CallList.end());
1670 MemProfRecordTable->getNumEntries());
1671for (
uint64_t Key : MemProfRecordTable->keys()) {
1680return AllMemProfData;
1685 std::vector<uint64_t> &Counts) {
1688returnerror(std::move(E));
1690 Counts =
Record.get().Counts;
1699returnerror(std::move(E));
1701constauto &BitmapBytes =
Record.get().BitmapBytes;
1702size_tI = 0, E = BitmapBytes.size();
1703 Bitmap.
resize(E * CHAR_BIT);
1706usingXTy =
decltype(
X);
1708size_tN = std::min(E -
I,
sizeof(W));
1709 std::memset(W, 0,
sizeof(W));
1710 std::memcpy(W, &BitmapBytes[
I],
N);
1726returnerror(std::move(E));
1729if (RecordIndex >=
Data.size()) {
1730 Index->advanceToNextKey();
1737 std::vector<llvm::object::BuildID> &BinaryIds) {
1743 std::vector<llvm::object::BuildID> BinaryIds;
1752for (
constauto &Func : *
this) {
1755if (FuncIsCS != IsCS)
1758 Func.accumulateCounts(Sum);
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Provides ErrorOr<T> smart pointer.
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS)
static Error initializeReader(InstrProfReader &Reader)
#define READ_NUM(Str, Dst)
#define CHECK_LINE_END(Line)
static Error readBinaryIdsInternal(const MemoryBuffer &DataBuffer, ArrayRef< uint8_t > BinaryIdsBuffer, std::vector< llvm::object::BuildID > &BinaryIds, const llvm::endianness Endian)
Read a list of binary ids from a profile that consist of a.
#define VP_READ_ADVANCE(Val)
static InstrProfKind getProfileKindFromVersion(uint64_t Version)
static Expected< memprof::MemProfRecord > getMemProfRecordV2(const memprof::IndexedMemProfRecord &IndexedRecord, MemProfFrameHashTable &MemProfFrameTable, MemProfCallStackHashTable &MemProfCallStackTable)
static Expected< memprof::MemProfRecord > getMemProfRecordV3(const memprof::IndexedMemProfRecord &IndexedRecord, const unsigned char *FrameBase, const unsigned char *CallStackBase)
static void printBinaryIdsInternal(raw_ostream &OS, ArrayRef< llvm::object::BuildID > BinaryIds)
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some functions that are useful when dealing with strings.
Defines the virtual file system interface vfs::FileSystem.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
iterator_range< const_set_bits_iterator > set_bits() const
static BitVector & apply(F &&f, BitVector &Out, BitVector const &Arg, ArgTys const &...Args)
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
Reader for the indexed binary instrprof format.
Error readNextRecord(NamedInstrProfRecord &Record) override
Read a single record.
static Expected< std::unique_ptr< IndexedInstrProfReader > > create(const Twine &Path, vfs::FileSystem &FS, const Twine &RemappingPath="")
Factory method to create an indexed reader.
Error readHeader() override
Read the file header.
Error printBinaryIds(raw_ostream &OS) override
Print binary ids.
Error getFunctionBitmap(StringRef FuncName, uint64_t FuncHash, BitVector &Bitmap)
Fill Bitmap with the profile data for the given function name.
InstrProfSymtab & getSymtab() override
Return the PGO symtab.
static bool hasFormat(const MemoryBuffer &DataBuffer)
Return true if the given buffer is in an indexed instrprof format.
Expected< InstrProfRecord > getInstrProfRecord(StringRef FuncName, uint64_t FuncHash, StringRef DeprecatedFuncName="", uint64_t *MismatchedFuncSum=nullptr)
Return the NamedInstrProfRecord associated with FuncName and FuncHash.
Error getFunctionCounts(StringRef FuncName, uint64_t FuncHash, std::vector< uint64_t > &Counts)
Fill Counts with the profile data for the given function name.
Error readBinaryIds(std::vector< llvm::object::BuildID > &BinaryIds) override
Read a list of binary ids.
Error deserialize(const unsigned char *Start, uint64_t MemProfOffset)
memprof::AllMemProfData getAllMemProfData() const
Expected< memprof::MemProfRecord > getMemProfRecord(const uint64_t FuncNameHash) const
DenseMap< uint64_t, SmallVector< memprof::CallEdgeTy, 0 > > getMemProfCallerCalleePairs() const
InstrProfCorrelatorImpl - A child of InstrProfCorrelator with a template pointer type so that the Pro...
const RawInstrProf::ProfileData< IntPtrT > * getDataPointer() const
Return a pointer to the underlying ProfileData vector that this class constructs.
size_t getDataSize() const
Return the number of ProfileData elements.
InstrProfCorrelator - A base class used to create raw instrumentation data to their functions.
const char * getNamesPointer() const
Return a pointer to the names string that this class constructs.
ProfCorrelatorKind
Indicate if we should use the debug info or profile metadata sections to correlate.
std::optional< size_t > getDataSize() const
Return the number of ProfileData elements.
static llvm::Expected< std::unique_ptr< InstrProfCorrelator > > get(StringRef Filename, ProfCorrelatorKind FileKind, const object::BuildIDFetcher *BIDFetcher=nullptr, const ArrayRef< llvm::object::BuildID > BIs={})
size_t getNamesSize() const
Return the number of bytes in the names string.
static std::pair< instrprof_error, std::string > take(Error E)
Consume an Error and return the raw enum value contained within it, and the optional error message.
data_type ReadData(StringRef K, const unsigned char *D, offset_type N)
bool readValueProfilingData(const unsigned char *&D, const unsigned char *const End)
hash_value_type ComputeHash(StringRef K)
ArrayRef< NamedInstrProfRecord > data_type
InstrProfKind getProfileKind() const override
Error getRecords(ArrayRef< NamedInstrProfRecord > &Data) override
InstrProfReaderIndex(const unsigned char *Buckets, const unsigned char *const Payload, const unsigned char *const Base, IndexedInstrProf::HashT HashType, uint64_t Version)
A remapper that applies remappings based on a symbol remapping file.
static StringRef extractName(StringRef Name)
Extract the original function name from a PGO function name.
InstrProfReaderItaniumRemapper(std::unique_ptr< MemoryBuffer > RemapBuffer, InstrProfReaderIndex< HashTableImpl > &Underlying)
Error populateRemappings() override
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 getRecords(StringRef FuncName, ArrayRef< NamedInstrProfRecord > &Data) override
Name matcher supporting fuzzy matching of symbol names to names in profiles.
Base class and interface for reading profiling data of any known instrprof format.
std::unique_ptr< InstrProfSymtab > Symtab
Error success()
Clear the current error and return a successful one.
SmallVector< TemporalProfTraceTy > TemporalProfTraces
A list of temporal profile traces.
uint64_t TemporalProfTraceStreamSize
The total number of temporal profile traces seen.
virtual bool isIRLevelProfile() const =0
virtual Error readHeader()=0
Read the header. Required before reading first record.
void accumulateCounts(CountSumOrPercent &Sum, bool IsCS)
Compute the sum of counts and return in Sum.
static Expected< std::unique_ptr< InstrProfReader > > create(const Twine &Path, vfs::FileSystem &FS, const InstrProfCorrelator *Correlator=nullptr, const object::BuildIDFetcher *BIDFetcher=nullptr, const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind=InstrProfCorrelator::ProfCorrelatorKind::NONE, std::function< void(Error)> Warn=nullptr)
Factory method to create an appropriately typed reader for the given instrprof file.
A symbol table used for function [IR]PGO name look-up with keys (such as pointers,...
static bool isExternalSymbol(const StringRef &Symbol)
True if Symbol is the value used to represent external symbols.
void mapAddress(uint64_t Addr, uint64_t MD5Val)
Map a function address to its name's MD5 hash.
Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
void mapVTableAddress(uint64_t StartAddr, uint64_t EndAddr, uint64_t MD5Val)
Map the address range (i.e., [start_address, end_address)) of a variable to its names' MD5 hash.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
size_t getBufferSize() const
const char * getBufferEnd() const
static ErrorOr< std::unique_ptr< MemoryBuffer > > getSTDIN()
Read all of stdin into a file buffer, and return it.
const char * getBufferStart() const
Provides lookup and iteration over an on disk hash table.
static OnDiskIterableChainedHashTable * Create(const unsigned char *Buckets, const unsigned char *const Payload, const unsigned char *const Base, const Info &InfoObj=Info())
Create the hash table.
static const ArrayRef< uint32_t > DefaultCutoffs
A vector of useful cutoff values for detailed summary.
Reader for the raw instrprof binary format from runtime.
Error readHeader() override
Read the header. Required before reading first record.
Error readNextRecord(NamedInstrProfRecord &Record) override
Read a single record.
Error printBinaryIds(raw_ostream &OS) override
Print binary ids.
static bool hasFormat(const MemoryBuffer &DataBuffer)
InstrProfKind getProfileKind() const override
Returns a BitsetEnum describing the attributes of the raw instr profile.
Error readBinaryIds(std::vector< llvm::object::BuildID > &BinaryIds) override
Read a list of binary ids.
SmallVector< TemporalProfTraceTy > & getTemporalProfTraces(std::optional< uint64_t > Weight={}) override
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
iterator insert(iterator I, T &&Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
std::pair< StringRef, StringRef > rsplit(StringRef Separator) const
Split into two substrings around the last occurrence of a separator string.
Reader for symbol remapping files.
Key insert(StringRef FunctionName)
Construct a key for the given symbol, or return an existing one if an equivalent name has already bee...
Key lookup(StringRef FunctionName)
Map the given symbol name into the key for the corresponding equivalence class.
Error read(MemoryBuffer &B)
Read remappings from the given buffer, which must live as long as the remapper.
Reader for the simple text based instrprof format.
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if the given buffer is in text instrprof format.
Error readNextRecord(NamedInstrProfRecord &Record) override
Read a single record.
Error readHeader() override
Read the header.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
std::string str() const
Return the twine contents as a std::string.
LLVM Value Representation.
bool is_at_end() const
Return true if we're an "end" iterator or have reached EOF.
BuildIDFetcher searches local cache directories for debug info.
This class implements an extremely fast bulk output stream that can only output to a stream.
The virtual file system interface.
std::unique_ptr< Summary > allocSummary(uint32_t TotalSize)
uint64_t ComputeHash(StringRef K)
constexpr uint64_t MaximumSupportedVersion
constexpr uint64_t MinimumSupportedVersion
Expected< MemProfSchema > readMemProfSchema(const unsigned char *&Buffer)
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
This is an optimization pass for GlobalISel generic memory operations.
RawInstrProfReader< uint32_t > RawInstrProfReader32
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS)
constexpr T byteswap(T V) noexcept
Reverses the bytes in the given integer value V.
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
auto unique(Range &&R, Predicate P)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
constexpr T alignToPowerOf2(U Value, V Align)
Will overflow only if result is not representable in T.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
std::vector< ProfileSummaryEntry > SummaryEntryVector
@ raw_profile_version_mismatch
@ counter_value_too_large
@ unexpected_correlation_info
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
constexpr char GlobalIdentifierDelimiter
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
RawInstrProfReader< uint64_t > RawInstrProfReader64
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
void consumeError(Error Err)
Consume a Error without doing anything.
InstrProfKind
An enum describing the attributes of an instrumented profile.
@ LoopEntriesInstrumentation
@ FunctionEntryInstrumentation
@ FrontendInstrumentation
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static Expected< Header > readFromBuffer(const unsigned char *Buffer)
uint64_t Cutoff
The required percentile of total execution count.
uint64_t NumBlocks
Number of blocks >= the minumum execution count.
uint64_t MinBlockCount
The minimum execution count for this percentile.
static uint32_t getSize(uint32_t NumSumFields, uint32_t NumCutoffEntries)
uint64_t NumSummaryFields
uint64_t NumCutoffEntries
Profiling information for a single function.
static bool hasCSFlagInHash(uint64_t FuncHash)
An ordered list of functions identified by their NameRef found in INSTR_PROF_DATA.
std::vector< GUIDMemProfRecordPair > HeapProfileRecords
std::optional< CallStackId > LastUnmappedId
DenseMap< uint64_t, SmallVector< CallEdgeTy, 0 > > CallerCalleePairs
std::optional< FrameId > LastUnmappedId
MemProfRecord toMemProfRecord(llvm::function_ref< std::vector< Frame >(const CallStackId)> Callback) const