37#include <system_error>
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,
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;
119 "not enough data to read binary id length");
124 "binary id length is 0");
126 Remaining = BIEnd - BI;
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); });
256 while (Line->starts_with(
":")) {
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())
294 if (Line->getAsInteger(0, NumTraces))
297 if ((++Line).is_at_end())
303 for (
uint32_t i = 0; i < NumTraces; i++) {
304 if ((++Line).is_at_end())
308 if (Line->getAsInteger(0,
Trace.Weight))
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)); \
339 if (Line.is_at_end())
342 uint32_t NumValueKinds;
343 if (Line->getAsInteger(10, NumValueKinds)) {
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)
365 std::vector<InstrProfValueData> CurrentValues;
366 for (uint32_t V = 0;
V < NumValueData;
V++) {
368 std::pair<StringRef, StringRef> VD = Line->rsplit(
':');
369 uint64_t TakenCount,
Value;
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
406 while (!Line.is_at_end() && (Line->empty() || Line->starts_with(
"#")))
409 if (Line.is_at_end()) {
416 return error(std::move(E));
419 if (Line.is_at_end())
421 if ((Line++)->getAsInteger(0,
Record.Hash))
423 "function hash is not a valid integer");
427 if (Line.is_at_end())
431 "number of counters is not a valid integer");
439 if (Line.is_at_end())
442 if ((Line++)->getAsInteger(10,
Count))
448 if (Line->starts_with(
"$")) {
449 Record.BitmapBytes.clear();
452 if ((Line++)->drop_front(1).trim().getAsInteger(0,
NumBitmapBytes))
454 "number of bitmap bytes is not a valid integer");
459 if (Line.is_at_end())
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()) {
491 std::sort(TemporalProfTimestamps.begin(), TemporalProfTimestamps.end());
494 Trace.Weight = *Weight;
495 for (
auto &[TimestampValue, NameRef] : TemporalProfTimestamps)
496 Trace.FunctionNameRefs.push_back(NameRef);
501template <
class IntPtrT>
503 if (DataBuffer.getBufferSize() <
sizeof(
uint64_t))
506 *
reinterpret_cast<const uint64_t *
>(DataBuffer.getBufferStart());
511template <
class IntPtrT>
518 DataBuffer->getBufferStart());
523template <
class IntPtrT>
524Error RawInstrProfReader<IntPtrT>::readNextHeader(
const char *CurrentPos) {
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");
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) {
566 const IntPtrT VPtr =
swap(
I->VTablePointer);
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.")
593 uint64_t BinaryIdSize =
swap(Header.BinaryIdsSize);
595 const uint8_t *BinaryIdStart =
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()))
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);
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;
633 ptrdiff_t BitmapOffset =
634 CountersOffset + CountersSize + PaddingBytesAfterCounters;
635 ptrdiff_t NamesOffset =
637 ptrdiff_t VTableProfDataOffset =
638 NamesOffset + NamesSize + PaddingBytesAfterNames;
639 ptrdiff_t VTableNameOffset = VTableProfDataOffset + VTableSectionSize +
640 PaddingBytesAfterVTableProfData;
641 ptrdiff_t ValueDataOffset =
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))
667 Data = Correlator->getDataPointer();
671 }
else if (BIDFetcherCorrelator) {
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;
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>
720Error RawInstrProfReader<IntPtrT>::readRawCounts(
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))
739 uint64_t MaxNumCounters =
740 (CountersEnd - (CountersStart + CounterBaseOffset)) /
741 getCounterTypeSize();
745 " is greater than the maximum number of counters " +
746 Twine(MaxNumCounters))
753 CountersStart + CounterBaseOffset +
I * getCounterTypeSize();
754 if (
I == 0 && hasTemporalProfile()) {
755 uint64_t TimestampValue =
swap(*
reinterpret_cast<const uint64_t *
>(
Ptr));
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);
775 uint64_t CounterValue =
swap(*
reinterpret_cast<const uint64_t *
>(
Ptr));
776 if (CounterValue > MaxCounterValue && Warn)
780 Record.Counts.push_back(CounterValue);
787template <
class IntPtrT>
791 Record.BitmapBytes.clear();
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))
813 uint64_t MaxNumBitmapBytes =
814 (BitmapEnd - (BitmapStart + BitmapOffset)) /
sizeof(uint8_t);
818 " is greater than the maximum number of bitmap bytes " +
819 Twine(MaxNumBitmapBytes))
823 const char *
Ptr = BitmapStart + BitmapOffset +
I;
830template <
class IntPtrT>
831Error RawInstrProfReader<IntPtrT>::readValueProfilingData(
834 CurValueDataSize = 0;
836 uint32_t NumValueKinds = 0;
837 for (uint32_t
I = 0;
I < IPVK_Last + 1;
I++)
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;
946 std::vector<uint64_t> CounterBuffer;
947 std::vector<uint8_t> BitmapByteBuffer;
949 const unsigned char *End =
D +
N;
965 if (
D + CountsSize *
sizeof(
uint64_t) > End)
968 CounterBuffer.clear();
969 CounterBuffer.reserve(CountsSize);
970 for (
uint64_t J = 0; J < CountsSize; ++J)
971 CounterBuffer.push_back(
981 if (
D + BitmapBytes *
sizeof(
uint8_t) > End)
983 BitmapByteBuffer.clear();
984 BitmapByteBuffer.reserve(BitmapBytes);
985 for (
uint64_t J = 0; J < BitmapBytes; ++J)
986 BitmapByteBuffer.push_back(
static_cast<uint8_t>(
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))
1107 for (
StringRef Name : Underlying.HashTable->keys()) {
1109 if (
auto Key = Remappings.insert(RealName)) {
1113 MappedNames.insert({
Key, RealName});
1122 if (
auto Key = Remappings.lookup(RealName)) {
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;
1172 if (DataBuffer.getBufferSize() < 8)
1175 DataBuffer.getBufferStart());
1180const unsigned char *
1182 const unsigned char *Cur,
bool UseCS) {
1195 std::unique_ptr<IndexedInstrProf::Summary> SummaryData =
1200 for (
unsigned I = 0;
I < SummarySize /
sizeof(
uint64_t);
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();
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();
1262 auto IndexPtr = std::make_unique<InstrProfReaderIndex<OnDiskHashTableImplV3>>(
1263 Start + Header->HashOffset, Cur, Start, HashType, Header->Version);
1267 if (Header->getIndexedProfileVersion() >= 8 &&
1269 if (
Error E = MemProfReader.deserialize(Start, Header->MemProfOffset))
1275 if (Header->getIndexedProfileVersion() >= 9) {
1276 const unsigned char *
Ptr = Start + Header->BinaryIdOffset;
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 =
1297 const char *VTableNamePtr = (
const char *)
Ptr;
1298 if (VTableNamePtr > DataBuffer->getBufferEnd())
1301 VTableName =
StringRef(VTableNamePtr, CompressedVTableNamesLen);
1304 if (Header->getIndexedProfileVersion() >= 10 &&
1306 const unsigned char *
Ptr = Start + Header->TemporalProfTracesOffset;
1307 const auto *PtrEnd = (
const unsigned char *)DataBuffer->getBufferEnd();
1315 for (
unsigned i = 0; i < NumTraces; i++) {
1325 if (
Ptr + NumFunctions *
sizeof(
uint64_t) > PtrEnd)
1327 for (
unsigned j = 0; j < NumFunctions; j++) {
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);
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;
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);
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())
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");
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())
1531 std::move(Extractor.CallerCalleePairs);
1534 for (
auto &[CallerGUID, CallList] : Pairs) {
1536 CallList.erase(
llvm::unique(CallList), CallList.end());
1545 MemProfRecordTable->getNumEntries());
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")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
Provides ErrorOr<T> smart pointer.
InstrProfLookupTrait::offset_type offset_type
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)
InstrProfLookupTrait::data_type data_type
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)
#define VARIANT_MASK_CSIR_PROF
#define VARIANT_MASK_MEMPROF
#define VARIANT_MASK_TEMPORAL_PROF
#define VARIANT_MASK_IR_PROF
#define VARIANT_MASK_BYTE_COVERAGE
#define VARIANT_MASK_INSTR_ENTRY
#define VARIANT_MASK_FUNCTION_ENTRY_ONLY
#define VARIANT_MASK_INSTR_LOOP_ENTRIES
static StringRef getName(Value *V)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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 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)
bool atEnd() const override
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
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.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
Reader for symbol remapping files.
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.
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
SmallVector< uint8_t, 10 > BuildID
A build ID in binary form.
value_type byte_swap(value_type value, endianness endian)
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
value_type readNext(const CharT *&memory, endianness endian)
Read a value of a particular endianness from a buffer, and increment the buffer past that value.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr CountersDelta
FunctionAddr VTableAddr Value
FunctionAddr NumBitmapBytes
RawInstrProfReader< uint64_t > RawInstrProfReader64
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.
FunctionAddr VTableAddr uintptr_t uintptr_t DataSize
auto unique(Range &&R, Predicate P)
auto dyn_cast_or_null(const Y &Val)
FunctionAddr VTableAddr uintptr_t BitmapDelta
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
FunctionAddr VTableAddr uintptr_t uintptr_t Version
void sort(IteratorTy Start, IteratorTy End)
OnDiskIterableChainedHashTable< memprof::CallStackLookupTrait > MemProfCallStackHashTable
constexpr T alignToPowerOf2(U Value, V Align)
Will overflow only if result is not representable in T.
FunctionAddr NumValueSites[IPVK_Last+1]
OnDiskIterableChainedHashTable< memprof::FrameLookupTrait > MemProfFrameHashTable
FunctionAddr VTableAddr Count
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
@ 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.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
std::vector< ProfileSummaryEntry > SummaryEntryVector
void consumeError(Error Err)
Consume a Error without doing anything.
InstrProfKind
An enum describing the attributes of an instrumented profile.
@ LoopEntriesInstrumentation
@ FunctionEntryInstrumentation
@ FrontendInstrumentation
RawInstrProfReader< uint32_t > RawInstrProfReader32
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.
LLVM_ABI void addValueData(uint32_t ValueKind, uint32_t Site, ArrayRef< InstrProfValueData > VData, InstrProfSymtab *SymTab)
Add ValueData for ValueKind at value Site.
void reserveSites(uint32_t ValueKind, uint32_t NumValueSites)
Reserve space for NumValueSites sites.
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