37#include <system_error>
47 if (Version & VARIANT_MASK_IR_PROF) {
48 ProfileKind |= InstrProfKind::IRInstrumentation;
50 if (Version & VARIANT_MASK_CSIR_PROF) {
51 ProfileKind |= InstrProfKind::ContextSensitive;
53 if (Version & VARIANT_MASK_INSTR_ENTRY) {
54 ProfileKind |= InstrProfKind::FunctionEntryInstrumentation;
56 if (Version & VARIANT_MASK_INSTR_LOOP_ENTRIES) {
57 ProfileKind |= InstrProfKind::LoopEntriesInstrumentation;
59 if (Version & VARIANT_MASK_BYTE_COVERAGE) {
60 ProfileKind |= InstrProfKind::SingleByteCoverage;
62 if (Version & VARIANT_MASK_FUNCTION_ENTRY_ONLY) {
63 ProfileKind |= InstrProfKind::FunctionEntryOnly;
65 if (Version & VARIANT_MASK_MEMPROF) {
66 ProfileKind |= InstrProfKind::MemProf;
68 if (Version & VARIANT_MASK_TEMPORAL_PROF) {
69 ProfileKind |= InstrProfKind::TemporalProfile;
77 : FS.getBufferForFile(Filename);
78 if (std::error_code EC = BufferOrErr.getError())
80 return std::move(BufferOrErr.get());
98 std::vector<llvm::object::BuildID> &BinaryIds,
100 using namespace support;
103 const uint8_t *BinaryIdsStart = BinaryIdsBuffer.
data();
105 if (BinaryIdsSize == 0)
108 const uint8_t *BI = BinaryIdsStart;
109 const uint8_t *BIEnd = BinaryIdsStart + BinaryIdsSize;
114 size_t Remaining = BIEnd - BI;
117 return make_error<InstrProfError>(
118 instrprof_error::malformed,
119 "not enough data to read binary id length");
123 return make_error<InstrProfError>(instrprof_error::malformed,
124 "binary id length is 0");
126 Remaining = BIEnd - BI;
129 return make_error<InstrProfError>(
130 instrprof_error::malformed,
"not enough data to read binary id data");
138 return make_error<InstrProfError>(
139 instrprof_error::malformed,
140 "binary id section is greater than buffer size");
148 OS <<
"Binary IDs: \n";
149 for (
const auto &BI : BinaryIds) {
161 std::function<
void(
Error)> Warn) {
164 if (
Error E = BufferOrError.takeError())
167 BIDFetcher, BIDFetcherCorrelatorKind, Warn);
174 std::function<
void(
Error)> Warn) {
175 if (Buffer->getBufferSize() == 0)
178 std::unique_ptr<InstrProfReader> Result;
184 BIDFetcher, BIDFetcherCorrelatorKind,
188 BIDFetcher, BIDFetcherCorrelatorKind,
199 return std::move(Result);
204 const Twine &RemappingPath) {
207 if (
Error E = BufferOrError.takeError())
211 std::unique_ptr<MemoryBuffer> RemappingBuffer;
212 std::string RemappingPathStr = RemappingPath.
str();
213 if (!RemappingPathStr.empty()) {
215 if (
Error E = RemappingBufferOrError.takeError())
217 RemappingBuffer = std::move(RemappingBufferOrError.get());
221 std::move(RemappingBuffer));
226 std::unique_ptr<MemoryBuffer> RemappingBuffer) {
230 auto Result = std::make_unique<IndexedInstrProfReader>(
231 std::move(Buffer), std::move(RemappingBuffer));
237 return std::move(Result);
247 [](
char c) { return isPrint(c) || isSpace(c); });
258 if (Str.equals_insensitive(
"ir"))
260 else if (Str.equals_insensitive(
"fe"))
262 else if (Str.equals_insensitive(
"csir")) {
265 }
else if (Str.equals_insensitive(
"entry_first"))
267 else if (Str.equals_insensitive(
"not_entry_first"))
269 else if (Str.equals_insensitive(
"instrument_loop_entries"))
271 else if (Str.equals_insensitive(
"single_byte_coverage"))
273 else if (Str.equals_insensitive(
"temporal_prof_traces")) {
275 if (
auto Err = readTemporalProfTraceData())
276 return error(std::move(Err));
289Error TextInstrProfReader::readTemporalProfTraceData() {
290 if ((++Line).is_at_end())
297 if ((++Line).is_at_end())
303 for (
uint32_t i = 0; i < NumTraces; i++) {
304 if ((++Line).is_at_end())
311 if ((++Line).is_at_end())
315 Line->
split(FuncNames,
",", -1,
false);
316 for (
auto &FuncName : FuncNames)
317 Trace.FunctionNameRefs.push_back(
327#define CHECK_LINE_END(Line) \
328 if (Line.is_at_end()) \
329 return error(instrprof_error::truncated);
330#define READ_NUM(Str, Dst) \
331 if ((Str).getAsInteger(10, (Dst))) \
332 return error(instrprof_error::malformed);
333#define VP_READ_ADVANCE(Val) \
334 CHECK_LINE_END(Line); \
336 READ_NUM((*Line), (Val)); \
347 if (NumValueKinds == 0 || NumValueKinds > IPVK_Last + 1)
349 "number of value kinds is invalid");
352 for (
uint32_t VK = 0; VK < NumValueKinds; VK++) {
354 if (ValueKind > IPVK_Last)
361 Record.reserveSites(VK, NumValueSites);
362 for (
uint32_t S = 0; S < NumValueSites; S++) {
365 std::vector<InstrProfValueData> CurrentValues;
368 std::pair<StringRef, StringRef> VD = Line->
rsplit(
':');
370 if (ValueKind == IPVK_IndirectCallTarget) {
378 }
else if (ValueKind == IPVK_VTableTarget) {
390 CurrentValues.push_back({
Value, TakenCount});
393 assert(CurrentValues.size() == NumValueData);
394 Record.addValueData(ValueKind, S, CurrentValues,
nullptr);
401#undef VP_READ_ADVANCE
416 return error(std::move(E));
421 if ((Line++)->getAsInteger(0,
Record.Hash))
423 "function hash is not a valid integer");
429 if ((Line++)->getAsInteger(10, NumCounters))
431 "number of counters is not a valid integer");
432 if (NumCounters == 0)
437 Record.Counts.reserve(NumCounters);
442 if ((Line++)->getAsInteger(10, Count))
444 Record.Counts.push_back(Count);
449 Record.BitmapBytes.clear();
452 if ((Line++)->drop_front(1).trim().getAsInteger(0, NumBitmapBytes))
454 "number of bitmap bytes is not a valid integer");
455 if (NumBitmapBytes != 0) {
457 Record.BitmapBytes.reserve(NumBitmapBytes);
458 for (
uint8_t I = 0;
I < NumBitmapBytes; ++
I) {
462 if ((Line++)->getAsInteger(0, BitmapByte))
464 "bitmap byte is not a valid integer");
465 Record.BitmapBytes.push_back(BitmapByte);
472 return error(std::move(E));
477template <
class IntPtrT>
482template <
class IntPtrT>
485 std::optional<uint64_t> Weight) {
486 if (TemporalProfTimestamps.empty()) {
487 assert(TemporalProfTraces.empty());
488 return TemporalProfTraces;
491 std::sort(TemporalProfTimestamps.begin(), TemporalProfTimestamps.end());
494 Trace.Weight = *Weight;
495 for (
auto &[TimestampValue, NameRef] : TemporalProfTimestamps)
496 Trace.FunctionNameRefs.push_back(NameRef);
497 TemporalProfTraces = {std::move(
Trace)};
498 return TemporalProfTraces;
501template <
class IntPtrT>
507 return RawInstrProf::getMagic<IntPtrT>() == Magic ||
511template <
class IntPtrT>
513 if (!hasFormat(*DataBuffer))
518 DataBuffer->getBufferStart());
519 ShouldSwapBytes = Header->Magic != RawInstrProf::getMagic<IntPtrT>();
520 return readHeader(*Header);
523template <
class IntPtrT>
525 const char *
End = DataBuffer->getBufferEnd();
527 while (CurrentPos !=
End && *CurrentPos == 0)
530 if (CurrentPos ==
End)
536 "not enough space for another header");
538 if (
reinterpret_cast<size_t>(CurrentPos) %
alignof(
uint64_t))
540 "insufficient padding");
543 if (Magic != swap(RawInstrProf::getMagic<IntPtrT>()))
548 return readHeader(*Header);
551template <
class IntPtrT>
554 StringRef(VNamesStart, VNamesEnd - VNamesStart)))
555 return error(std::move(E));
557 const IntPtrT FPtr = swap(
I->FunctionPointer);
563 if (VTableBegin !=
nullptr && VTableEnd !=
nullptr) {
565 I != VTableEnd; ++
I) {
574 swap(
I->VTableNameHash));
580template <
class IntPtrT>
586 (
"Profile uses raw profile format version = " +
589 "\nPLEASE update this tool to version in the raw profile, or "
590 "regenerate raw profile with expected version.")
597 const uint8_t *BinaryIdEnd = BinaryIdStart + BinaryIdSize;
598 const uint8_t *BufferEnd = (
const uint8_t *)DataBuffer->getBufferEnd();
599 if (BinaryIdSize %
sizeof(
uint64_t) || BinaryIdEnd > BufferEnd)
602 if (!BinaryIdsBuffer.empty()) {
604 BinaryIds, getDataEndianness()))
608 CountersDelta =
swap(Header.CountersDelta);
609 BitmapDelta =
swap(Header.BitmapDelta);
610 NamesDelta =
swap(Header.NamesDelta);
611 auto NumData =
swap(Header.NumData);
612 auto PaddingBytesBeforeCounters =
swap(Header.PaddingBytesBeforeCounters);
613 auto CountersSize =
swap(Header.NumCounters) * getCounterTypeSize();
614 auto PaddingBytesAfterCounters =
swap(Header.PaddingBytesAfterCounters);
615 auto NumBitmapBytes =
swap(Header.NumBitmapBytes);
616 auto PaddingBytesAfterBitmapBytes =
swap(Header.PaddingBytesAfterBitmapBytes);
617 auto NamesSize =
swap(Header.NamesSize);
618 auto VTableNameSize =
swap(Header.VNamesSize);
619 auto NumVTables =
swap(Header.NumVTables);
620 ValueKindLast =
swap(Header.ValueKindLast);
623 auto PaddingBytesAfterNames = getNumPaddingBytes(NamesSize);
624 auto PaddingBytesAfterVTableNames = getNumPaddingBytes(VTableNameSize);
626 auto VTableSectionSize =
628 auto PaddingBytesAfterVTableProfData = getNumPaddingBytes(VTableSectionSize);
632 ptrdiff_t CountersOffset = DataOffset + DataSize + PaddingBytesBeforeCounters;
634 CountersOffset + CountersSize + PaddingBytesAfterCounters;
636 BitmapOffset + NumBitmapBytes + PaddingBytesAfterBitmapBytes;
638 NamesOffset + NamesSize + PaddingBytesAfterNames;
639 ptrdiff_t VTableNameOffset = VTableProfDataOffset + VTableSectionSize +
640 PaddingBytesAfterVTableProfData;
642 VTableNameOffset + VTableNameSize + PaddingBytesAfterVTableNames;
644 auto *Start =
reinterpret_cast<const char *
>(&Header);
645 if (Start + ValueDataOffset > DataBuffer->getBufferEnd())
649 std::vector<object::BuildID> BinaryIDs;
650 if (
Error E = readBinaryIds(BinaryIDs))
653 BIDFetcher, BinaryIDs)
654 .moveInto(BIDFetcherCorrelator)) {
657 if (
auto Err = BIDFetcherCorrelator->correlateProfileData(0))
664 if (!(DataSize == 0 && NamesSize == 0 && CountersDelta == 0 &&
667 Data = Correlator->getDataPointer();
671 }
else if (BIDFetcherCorrelator) {
673 dyn_cast_or_null<InstrProfCorrelatorImpl<IntPtrT>>(
674 BIDFetcherCorrelator.get());
678 NamesEnd = NamesStart + BIDFetcherCorrelatorImpl->
getNamesSize();
682 DataEnd =
Data + NumData;
685 Start + VTableProfDataOffset);
686 VTableEnd = VTableBegin + NumVTables;
687 NamesStart = Start + NamesOffset;
688 NamesEnd = NamesStart + NamesSize;
689 VNamesStart = Start + VTableNameOffset;
690 VNamesEnd = VNamesStart + VTableNameSize;
693 CountersStart = Start + CountersOffset;
694 CountersEnd = CountersStart + CountersSize;
695 BitmapStart = Start + BitmapOffset;
696 BitmapEnd = BitmapStart + NumBitmapBytes;
697 ValueDataStart =
reinterpret_cast<const uint8_t *
>(Start + ValueDataOffset);
699 std::unique_ptr<InstrProfSymtab> NewSymtab = std::make_unique<InstrProfSymtab>();
700 if (
Error E = createSymtab(*NewSymtab))
703 Symtab = std::move(NewSymtab);
707template <
class IntPtrT>
713template <
class IntPtrT>
719template <
class IntPtrT>
723 if (NumCounters == 0)
727 if (CounterBaseOffset < 0)
730 (
"counter offset " +
Twine(CounterBaseOffset) +
" is negative").str());
732 if (CounterBaseOffset >= CountersEnd - CountersStart)
734 (
"counter offset " +
Twine(CounterBaseOffset) +
735 " is greater than the maximum counter offset " +
736 Twine(CountersEnd - CountersStart - 1))
740 (CountersEnd - (CountersStart + CounterBaseOffset)) /
741 getCounterTypeSize();
742 if (NumCounters > MaxNumCounters)
744 (
"number of counters " +
Twine(NumCounters) +
745 " is greater than the maximum number of counters " +
746 Twine(MaxNumCounters))
750 Record.Counts.reserve(NumCounters);
753 CountersStart + CounterBaseOffset +
I * getCounterTypeSize();
754 if (
I == 0 && hasTemporalProfile()) {
756 if (TimestampValue != 0 &&
757 TimestampValue != std::numeric_limits<uint64_t>::max()) {
758 TemporalProfTimestamps.emplace_back(TimestampValue,
760 TemporalProfTraceStreamSize = 1;
762 if (hasSingleByteCoverage()) {
771 if (hasSingleByteCoverage()) {
773 Record.Counts.push_back(*
Ptr == 0 ? 1 : 0);
776 if (CounterValue > MaxCounterValue && Warn)
777 Warn(make_error<InstrProfError>(
780 Record.Counts.push_back(CounterValue);
787template <
class IntPtrT>
791 Record.BitmapBytes.clear();
792 Record.BitmapBytes.reserve(NumBitmapBytes);
796 if (NumBitmapBytes == 0)
801 if (BitmapOffset < 0)
804 (
"bitmap offset " +
Twine(BitmapOffset) +
" is negative").str());
806 if (BitmapOffset >= BitmapEnd - BitmapStart)
808 (
"bitmap offset " +
Twine(BitmapOffset) +
809 " is greater than the maximum bitmap offset " +
810 Twine(BitmapEnd - BitmapStart - 1))
814 (BitmapEnd - (BitmapStart + BitmapOffset)) /
sizeof(
uint8_t);
815 if (NumBitmapBytes > MaxNumBitmapBytes)
817 (
"number of bitmap bytes " +
Twine(NumBitmapBytes) +
818 " is greater than the maximum number of bitmap bytes " +
819 Twine(MaxNumBitmapBytes))
823 const char *
Ptr = BitmapStart + BitmapOffset +
I;
830template <
class IntPtrT>
834 CurValueDataSize = 0;
838 NumValueKinds += (
Data->NumValueSites[
I] != 0);
844 ValueProfData::getValueProfData(
845 ValueDataStart, (
const unsigned char *)DataBuffer->getBufferEnd(),
846 getDataEndianness());
854 VDataPtrOrErr.
get()->deserializeTo(
Record, Symtab.get());
855 CurValueDataSize = VDataPtrOrErr.
get()->getSize();
859template <
class IntPtrT>
865 if (
Error E = readNextHeader(getNextHeaderPos()))
866 return error(std::move(E));
870 return error(std::move(E));
874 return error(std::move(E));
878 return error(std::move(E));
882 return error(std::move(E));
886 return error(std::move(E));
893template <
class IntPtrT>
895 std::vector<llvm::object::BuildID> &BinaryIds) {
896 BinaryIds.insert(BinaryIds.begin(), this->BinaryIds.begin(),
897 this->BinaryIds.end());
901template <
class IntPtrT>
903 if (!BinaryIds.empty())
924 const unsigned char *&
D,
const unsigned char *
const End) {
926 ValueProfData::getValueProfData(
D,
End, ValueProfDataEndianness);
931 VDataPtrOrErr.
get()->deserializeTo(DataBuffer.back(),
nullptr);
932 D += VDataPtrOrErr.
get()->TotalSize;
939 using namespace support;
946 std::vector<uint64_t> CounterBuffer;
947 std::vector<uint8_t> BitmapByteBuffer;
949 const unsigned char *
End =
D +
N;
954 uint64_t Hash = endian::readNext<uint64_t, llvm::endianness::little>(
D);
962 CountsSize = endian::readNext<uint64_t, llvm::endianness::little>(
D);
968 CounterBuffer.clear();
969 CounterBuffer.reserve(CountsSize);
970 for (
uint64_t J = 0; J < CountsSize; ++J)
971 CounterBuffer.push_back(
972 endian::readNext<uint64_t, llvm::endianness::little>(
D));
979 BitmapBytes = endian::readNext<uint64_t, llvm::endianness::little>(
D);
983 BitmapByteBuffer.clear();
984 BitmapByteBuffer.reserve(BitmapBytes);
985 for (
uint64_t J = 0; J < BitmapBytes; ++J)
986 BitmapByteBuffer.push_back(
static_cast<uint8_t>(
987 endian::readNext<uint64_t, llvm::endianness::little>(
D)));
990 DataBuffer.emplace_back(K, Hash, std::move(CounterBuffer),
991 std::move(BitmapByteBuffer));
1003template <
typename HashTableImpl>
1006 auto Iter = HashTable->find(FuncName);
1007 if (Iter == HashTable->end())
1013 "profile data is empty");
1018template <
typename HashTableImpl>
1024 Data = *RecordIterator;
1028 "profile data is empty");
1033template <
typename HashTableImpl>
1035 const unsigned char *Buckets,
const unsigned char *
const Payload,
1039 HashTable.reset(HashTableImpl::Create(
1040 Buckets, Payload,
Base,
1041 typename HashTableImpl::InfoType(HashType,
Version)));
1042 RecordIterator = HashTable->data_begin();
1045template <
typename HashTableImpl>
1057 : Underlying(Underlying) {}
1061 return Underlying.getRecords(FuncName, Data);
1067template <
typename HashTableImpl>
1072 std::unique_ptr<MemoryBuffer> RemapBuffer,
1074 : RemapBuffer(
std::
move(RemapBuffer)), Underlying(Underlying) {
1083 std::pair<StringRef, StringRef> Parts = {
StringRef(),
Name};
1086 if (Parts.first.starts_with(
"_Z"))
1088 if (Parts.second.empty())
1105 if (
Error E = Remappings.
read(*RemapBuffer))
1109 if (
auto Key = Remappings.
insert(RealName)) {
1113 MappedNames.insert({Key, RealName});
1122 if (
auto Key = Remappings.
lookup(RealName)) {
1123 StringRef Remapped = MappedNames.lookup(Key);
1124 if (!Remapped.
empty()) {
1126 RealName.
end() == FuncName.
end())
1127 FuncName = Remapped;
1132 Error E = Underlying.getRecords(Reconstituted,
Data);
1139 std::move(E), [](std::unique_ptr<InstrProfError> Err) {
1142 :
Error(std::move(Err));
1148 return Underlying.getRecords(FuncName,
Data);
1154 std::unique_ptr<MemoryBuffer> RemapBuffer;
1170 using namespace support;
1174 uint64_t Magic = endian::read<uint64_t, llvm::endianness::little, aligned>(
1180const unsigned char *
1182 const unsigned char *Cur,
bool UseCS) {
1183 using namespace IndexedInstrProf;
1184 using namespace support;
1189 uint64_t NFields = endian::byte_swap<uint64_t, llvm::endianness::little>(
1191 uint64_t NEntries = endian::byte_swap<uint64_t, llvm::endianness::little>(
1195 std::unique_ptr<IndexedInstrProf::Summary> SummaryData =
1200 for (
unsigned I = 0;
I < SummarySize /
sizeof(
uint64_t);
I++)
1201 Dst[
I] = endian::byte_swap<uint64_t, llvm::endianness::little>(Src[
I]);
1204 for (
unsigned I = 0;
I < SummaryData->NumCutoffEntries;
I++) {
1209 std::unique_ptr<llvm::ProfileSummary> &Summary =
1210 UseCS ? this->CS_Summary : this->Summary;
1213 Summary = std::make_unique<ProfileSummary>(
1215 DetailedSummary, SummaryData->get(Summary::TotalBlockCount),
1216 SummaryData->get(Summary::MaxBlockCount),
1217 SummaryData->get(Summary::MaxInternalBlockCount),
1218 SummaryData->get(Summary::MaxFunctionCount),
1219 SummaryData->get(Summary::TotalNumBlocks),
1220 SummaryData->get(Summary::TotalNumFunctions));
1221 return Cur + SummarySize;
1229 Summary = Builder.getSummary();
1235 using namespace support;
1237 const unsigned char *Start =
1238 (
const unsigned char *)DataBuffer->getBufferStart();
1239 const unsigned char *Cur = Start;
1240 if ((
const unsigned char *)DataBuffer->getBufferEnd() - Cur < 24)
1245 return HeaderOr.takeError();
1248 Cur += Header->size();
1252 if (Header->Version & VARIANT_MASK_CSIR_PROF)
1262 auto IndexPtr = std::make_unique<InstrProfReaderIndex<OnDiskHashTableImplV3>>(
1263 Start + Header->HashOffset, Cur, Start, HashType, Header->Version);
1267 if (Header->getIndexedProfileVersion() >= 8 &&
1268 Header->Version & VARIANT_MASK_MEMPROF) {
1275 if (Header->getIndexedProfileVersion() >= 9) {
1276 const unsigned char *
Ptr = Start + Header->BinaryIdOffset;
1279 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1280 if (BinaryIdsSize %
sizeof(
uint64_t))
1284 if (
Ptr > (
const unsigned char *)DataBuffer->getBufferEnd())
1286 "corrupted binary ids");
1289 if (Header->getIndexedProfileVersion() >= 12) {
1290 const unsigned char *
Ptr = Start + Header->VTableNamesOffset;
1292 uint64_t CompressedVTableNamesLen =
1293 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1297 const char *VTableNamePtr = (
const char *)
Ptr;
1298 if (VTableNamePtr > DataBuffer->getBufferEnd())
1301 VTableName =
StringRef(VTableNamePtr, CompressedVTableNamesLen);
1304 if (Header->getIndexedProfileVersion() >= 10 &&
1305 Header->Version & VARIANT_MASK_TEMPORAL_PROF) {
1306 const unsigned char *
Ptr = Start + Header->TemporalProfTracesOffset;
1307 const auto *PtrEnd = (
const unsigned char *)DataBuffer->getBufferEnd();
1312 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1314 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1315 for (
unsigned i = 0; i < NumTraces; i++) {
1321 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1323 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1325 if (
Ptr + NumFunctions *
sizeof(
uint64_t) > PtrEnd)
1327 for (
unsigned j = 0; j < NumFunctions; j++) {
1329 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
1330 Trace.FunctionNameRefs.push_back(NameRef);
1337 if (RemappingBuffer) {
1339 std::make_unique<InstrProfReaderItaniumRemapper<OnDiskHashTableImplV3>>(
1340 std::move(RemappingBuffer), *IndexPtr);
1341 if (
Error E = Remapper->populateRemappings())
1344 Remapper = std::make_unique<InstrProfReaderNullRemapper>(*IndexPtr);
1346 Index = std::move(IndexPtr);
1355 auto NewSymtab = std::make_unique<InstrProfSymtab>();
1357 if (
Error E = NewSymtab->initVTableNamesFromCompressedStrings(VTableName)) {
1363 if (
Error E = Index->populateSymtab(*NewSymtab)) {
1368 Symtab = std::move(NewSymtab);
1377 auto Err = Remapper->getRecords(FuncName,
Data);
1384 return make_error<InstrProfError>(IE);
1385 if (
auto Err = Remapper->getRecords(DeprecatedFuncName,
Data))
1390 return std::move(Err2);
1396 bool CSBitMatch =
false;
1399 for (
uint64_t CountValue : Counts) {
1403 if (std::numeric_limits<uint64_t>::max() - CountValue <= ValueSum)
1404 return std::numeric_limits<uint64_t>::max();
1405 ValueSum += CountValue;
1412 if (
I.Hash == FuncHash)
1413 return std::move(
I);
1417 if (MismatchedFuncSum ==
nullptr)
1419 FuncSum = std::max(FuncSum, getFuncSum(
I.Counts));
1423 if (MismatchedFuncSum !=
nullptr)
1424 *MismatchedFuncSum = FuncSum;
1438 MemProfCallStackTable, FrameIdConv);
1444 return make_error<InstrProfError>(
1446 "memprof call stack not found for call stack id " +
1453 "memprof frame not found for frame id " +
1463 if (MemProfRecordTable ==
nullptr)
1465 "no memprof data available in profile");
1466 auto Iter = MemProfRecordTable->find(FuncNameHash);
1467 if (Iter == MemProfRecordTable->end())
1468 return make_error<InstrProfError>(
1470 "memprof record not found for function hash " +
Twine(FuncNameHash));
1475 assert(MemProfFrameTable &&
"MemProfFrameTable must be available");
1476 assert(MemProfCallStackTable &&
"MemProfCallStackTable must be available");
1478 *MemProfCallStackTable);
1482 assert(!MemProfFrameTable &&
"MemProfFrameTable must not be available");
1483 assert(!MemProfCallStackTable &&
1484 "MemProfCallStackTable must not be available");
1485 assert(FrameBase &&
"FrameBase must be available");
1486 assert(CallStackBase &&
"CallStackBase must be available");
1495 return make_error<InstrProfError>(
1497 formatv(
"MemProf version {} not supported; "
1498 "requires version between {} and {}, inclusive",
1505 assert(MemProfRecordTable);
1520 MemProfRecordTable->data()) {
1522 IndexedRecord.AllocSites)
1527 for (
unsigned CS : Worklist.
set_bits())
1534 for (
auto &[CallerGUID, CallList] : Pairs) {
1536 CallList.erase(
llvm::unique(CallList), CallList.end());
1545 MemProfRecordTable->getNumEntries());
1546 for (
uint64_t Key : MemProfRecordTable->keys()) {
1556 if (DataAccessProfileData !=
nullptr) {
1557 for (
const auto &[SymHandleRef, RecordRef] :
1558 DataAccessProfileData->getRecords())
1561 RecordRef.Locations));
1562 for (
StringRef ColdSymbol : DataAccessProfileData->getKnownColdSymbols())
1565 for (
uint64_t Hash : DataAccessProfileData->getKnownColdHashes())
1569 return AllMemProfData;
1574 std::vector<uint64_t> &Counts) {
1577 return error(std::move(E));
1579 Counts =
Record.get().Counts;
1588 return error(std::move(E));
1590 const auto &BitmapBytes =
Record.get().BitmapBytes;
1591 size_t I = 0, E = BitmapBytes.size();
1592 Bitmap.
resize(E * CHAR_BIT);
1595 using XTy =
decltype(
X);
1597 size_t N = std::min(E -
I,
sizeof(W));
1598 std::memset(W, 0,
sizeof(W));
1599 std::memcpy(W, &BitmapBytes[
I],
N);
1615 return error(std::move(E));
1618 if (RecordIndex >=
Data.size()) {
1619 Index->advanceToNextKey();
1626 std::vector<llvm::object::BuildID> &BinaryIds) {
1632 std::vector<llvm::object::BuildID> BinaryIds;
1641 for (
const auto &Func : *
this) {
1644 if (FuncIsCS != IsCS)
1647 Func.accumulateCounts(Sum);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 void printBinaryIdsInternal(raw_ostream &OS, ArrayRef< llvm::object::BuildID > BinaryIds)
static StringRef getName(Value *V)
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.
Error getFunctionCounts(StringRef FuncName, uint64_t FuncHash, std::vector< uint64_t > &Counts)
Fill Counts with the profile data for the given function name.
Expected< NamedInstrProfRecord > getInstrProfRecord(StringRef FuncName, uint64_t FuncHash, StringRef DeprecatedFuncName="", uint64_t *MismatchedFuncSum=nullptr)
Return the NamedInstrProfRecord associated with FuncName and FuncHash.
Error readBinaryIds(std::vector< llvm::object::BuildID > &BinaryIds) override
Read a list of binary ids.
LLVM_ABI Error deserialize(const unsigned char *Start, uint64_t MemProfOffset)
LLVM_ABI memprof::AllMemProfData getAllMemProfData() const
LLVM_ABI Expected< memprof::MemProfRecord > getMemProfRecord(const uint64_t FuncNameHash) const
LLVM_ABI 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.
LLVM_ABI std::optional< size_t > getDataSize() const
Return the number of ProfileData elements.
static LLVM_ABI 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.
LLVM_ABI data_type ReadData(StringRef K, const unsigned char *D, offset_type N)
LLVM_ABI bool readValueProfilingData(const unsigned char *&D, const unsigned char *const End)
LLVM_ABI 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.
LLVM_ABI void accumulateCounts(CountSumOrPercent &Sum, bool IsCS)
Compute the sum of counts and return in Sum.
static LLVM_ABI 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.
LLVM_ABI 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 LLVM_ABI 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.
LLVM_ABI 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...
LLVM_ABI 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
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.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
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
LLVM_ABI 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.
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.
YamlDataAccessProfData YamlifiedDataAccessProfiles
std::vector< GUIDMemProfRecordPair > HeapProfileRecords
std::optional< CallStackId > LastUnmappedId
The data access profiles for a symbol.
std::optional< FrameId > LastUnmappedId
LLVM_ABI MemProfRecord toMemProfRecord(llvm::function_ref< std::vector< Frame >(const CallStackId)> Callback) const
std::vector< memprof::DataAccessProfRecord > Records
std::vector< uint64_t > KnownColdStrHashes
std::vector< std::string > KnownColdSymbols