35#include <system_error>
45 if (Version & VARIANT_MASK_IR_PROF) {
46 ProfileKind |= InstrProfKind::IRInstrumentation;
48 if (Version & VARIANT_MASK_CSIR_PROF) {
49 ProfileKind |= InstrProfKind::ContextSensitive;
51 if (Version & VARIANT_MASK_INSTR_ENTRY) {
52 ProfileKind |= InstrProfKind::FunctionEntryInstrumentation;
54 if (Version & VARIANT_MASK_BYTE_COVERAGE) {
55 ProfileKind |= InstrProfKind::SingleByteCoverage;
57 if (Version & VARIANT_MASK_FUNCTION_ENTRY_ONLY) {
58 ProfileKind |= InstrProfKind::FunctionEntryOnly;
60 if (Version & VARIANT_MASK_MEMPROF) {
61 ProfileKind |= InstrProfKind::MemProf;
63 if (Version & VARIANT_MASK_TEMPORAL_PROF) {
64 ProfileKind |= InstrProfKind::TemporalProfile;
72 : FS.getBufferForFile(Filename);
73 if (std::error_code EC = BufferOrErr.getError())
75 return std::move(BufferOrErr.get());
93 const uint8_t *BinaryIdsStart,
94 std::vector<llvm::object::BuildID> &BinaryIds,
96 using namespace support;
98 if (BinaryIdsSize == 0)
101 const uint8_t *BI = BinaryIdsStart;
102 const uint8_t *BIEnd = BinaryIdsStart + BinaryIdsSize;
104 reinterpret_cast<const uint8_t *
>(DataBuffer.
getBufferEnd());
107 size_t Remaining = BIEnd - BI;
110 return make_error<InstrProfError>(
111 instrprof_error::malformed,
112 "not enough data to read binary id length");
116 BILen = endian::readNext<uint64_t, little, unaligned>(BI);
118 BILen = endian::readNext<uint64_t, big, unaligned>(BI);
121 return make_error<InstrProfError>(instrprof_error::malformed,
122 "binary id length is 0");
124 Remaining = BIEnd - BI;
127 return make_error<InstrProfError>(
128 instrprof_error::malformed,
"not enough data to read binary id data");
136 return make_error<InstrProfError>(
137 instrprof_error::malformed,
138 "binary id section is greater than buffer size");
147 const uint8_t *BinaryIdsStart,
149 if (BinaryIdsSize == 0)
152 std::vector<llvm::object::BuildID> BinaryIds;
157 OS <<
"Binary IDs: \n";
158 for (
auto BI : BinaryIds) {
172 if (
Error E = BufferOrError.takeError())
180 if (Buffer->getBufferSize() == 0)
183 std::unique_ptr<InstrProfReader> Result;
200 return std::move(Result);
205 const Twine &RemappingPath) {
208 if (
Error E = BufferOrError.takeError())
212 std::unique_ptr<MemoryBuffer> RemappingBuffer;
213 std::string RemappingPathStr = RemappingPath.
str();
214 if (!RemappingPathStr.empty()) {
216 if (
Error E = RemappingBufferOrError.takeError())
218 RemappingBuffer = std::move(RemappingBufferOrError.get());
222 std::move(RemappingBuffer));
227 std::unique_ptr<MemoryBuffer> RemappingBuffer) {
231 auto Result = std::make_unique<IndexedInstrProfReader>(
232 std::move(Buffer), std::move(RemappingBuffer));
238 return std::move(Result);
248 [](
char c) { return isPrint(c) || isSpace(c); });
259 if (Str.equals_insensitive(
"ir"))
261 else if (Str.equals_insensitive(
"fe"))
263 else if (Str.equals_insensitive(
"csir")) {
266 }
else if (Str.equals_insensitive(
"entry_first"))
268 else if (Str.equals_insensitive(
"not_entry_first"))
270 else if (Str.equals_insensitive(
"temporal_prof_traces")) {
272 if (
auto Err = readTemporalProfTraceData())
273 return error(std::move(Err));
286Error TextInstrProfReader::readTemporalProfTraceData() {
287 if ((++Line).is_at_end())
294 if ((++Line).is_at_end())
300 for (
uint32_t i = 0; i < NumTraces; i++) {
301 if ((++Line).is_at_end())
308 if ((++Line).is_at_end())
312 Line->
split(FuncNames,
",", -1,
false);
313 for (
auto &FuncName : FuncNames)
314 Trace.FunctionNameRefs.push_back(
324#define CHECK_LINE_END(Line) \
325 if (Line.is_at_end()) \
326 return error(instrprof_error::truncated);
327#define READ_NUM(Str, Dst) \
328 if ((Str).getAsInteger(10, (Dst))) \
329 return error(instrprof_error::malformed);
330#define VP_READ_ADVANCE(Val) \
331 CHECK_LINE_END(Line); \
333 READ_NUM((*Line), (Val)); \
344 if (NumValueKinds == 0 || NumValueKinds > IPVK_Last + 1)
346 "number of value kinds is invalid");
349 for (
uint32_t VK = 0; VK < NumValueKinds; VK++) {
351 if (ValueKind > IPVK_Last)
358 Record.reserveSites(VK, NumValueSites);
359 for (
uint32_t S = 0; S < NumValueSites; S++) {
362 std::vector<InstrProfValueData> CurrentValues;
365 std::pair<StringRef, StringRef> VD = Line->
rsplit(
':');
367 if (ValueKind == IPVK_IndirectCallTarget) {
379 CurrentValues.push_back({
Value, TakenCount});
382 Record.addValueData(ValueKind, S, CurrentValues.data(), NumValueData,
390#undef VP_READ_ADVANCE
405 return error(std::move(
E));
410 if ((Line++)->getAsInteger(0,
Record.Hash))
412 "function hash is not a valid integer");
418 if ((Line++)->getAsInteger(10, NumCounters))
420 "number of counters is not a valid integer");
421 if (NumCounters == 0)
426 Record.Counts.reserve(NumCounters);
431 if ((Line++)->getAsInteger(10, Count))
433 Record.Counts.push_back(Count);
438 return error(std::move(
E));
443template <
class IntPtrT>
448template <
class IntPtrT>
451 std::optional<uint64_t> Weight) {
452 if (TemporalProfTimestamps.empty()) {
453 assert(TemporalProfTraces.empty());
454 return TemporalProfTraces;
457 std::sort(TemporalProfTimestamps.begin(), TemporalProfTimestamps.end());
460 Trace.Weight = *Weight;
461 for (
auto &[TimestampValue, NameRef] : TemporalProfTimestamps)
462 Trace.FunctionNameRefs.push_back(NameRef);
463 TemporalProfTraces = {std::move(
Trace)};
464 return TemporalProfTraces;
467template <
class IntPtrT>
473 return RawInstrProf::getMagic<IntPtrT>() == Magic ||
477template <
class IntPtrT>
479 if (!hasFormat(*DataBuffer))
484 DataBuffer->getBufferStart());
485 ShouldSwapBytes = Header->Magic != RawInstrProf::getMagic<IntPtrT>();
486 return readHeader(*Header);
489template <
class IntPtrT>
491 const char *
End = DataBuffer->getBufferEnd();
493 while (CurrentPos !=
End && *CurrentPos == 0)
496 if (CurrentPos ==
End)
502 "not enough space for another header");
504 if (
reinterpret_cast<size_t>(CurrentPos) %
alignof(
uint64_t))
506 "insufficient padding");
509 if (Magic != swap(RawInstrProf::getMagic<IntPtrT>()))
514 return readHeader(*Header);
517template <
class IntPtrT>
520 return error(std::move(
E));
522 const IntPtrT FPtr = swap(
I->FunctionPointer);
530template <
class IntPtrT>
536 (
"Profile uses raw profile format version = " +
537 Twine(GET_VERSION(Version)) +
539 "\nPLEASE update this tool to version in the raw profile, or "
540 "regenerate raw profile with expected version.")
542 if (useDebugInfoCorrelate() && !Correlator)
544 if (!useDebugInfoCorrelate() && Correlator)
547 BinaryIdsSize =
swap(Header.BinaryIdsSize);
548 if (BinaryIdsSize %
sizeof(
uint64_t))
551 CountersDelta =
swap(Header.CountersDelta);
552 NamesDelta =
swap(Header.NamesDelta);
553 auto NumData =
swap(Header.DataSize);
554 auto PaddingBytesBeforeCounters =
swap(Header.PaddingBytesBeforeCounters);
555 auto CountersSize =
swap(Header.CountersSize) * getCounterTypeSize();
556 auto PaddingBytesAfterCounters =
swap(Header.PaddingBytesAfterCounters);
557 auto NamesSize =
swap(Header.NamesSize);
558 ValueKindLast =
swap(Header.ValueKindLast);
561 auto PaddingSize = getNumPaddingBytes(NamesSize);
565 ptrdiff_t CountersOffset = DataOffset + DataSize + PaddingBytesBeforeCounters;
567 CountersOffset + CountersSize + PaddingBytesAfterCounters;
568 ptrdiff_t ValueDataOffset = NamesOffset + NamesSize + PaddingSize;
570 auto *Start =
reinterpret_cast<const char *
>(&Header);
571 if (Start + ValueDataOffset > DataBuffer->getBufferEnd())
577 assert(DataSize == 0 && NamesSize == 0);
578 assert(CountersDelta == 0 && NamesDelta == 0);
579 Data = Correlator->getDataPointer();
580 DataEnd =
Data + Correlator->getDataSize();
581 NamesStart = Correlator->getNamesPointer();
582 NamesEnd = NamesStart + Correlator->getNamesSize();
586 DataEnd =
Data + NumData;
587 NamesStart = Start + NamesOffset;
588 NamesEnd = NamesStart + NamesSize;
594 CountersStart = Start + CountersOffset;
595 CountersEnd = CountersStart + CountersSize;
596 ValueDataStart =
reinterpret_cast<const uint8_t *
>(Start + ValueDataOffset);
598 const uint8_t *BufferEnd = (
const uint8_t *)DataBuffer->getBufferEnd();
599 if (BinaryIdsStart + BinaryIdsSize > BufferEnd)
602 std::unique_ptr<InstrProfSymtab> NewSymtab = std::make_unique<InstrProfSymtab>();
603 if (
Error E = createSymtab(*NewSymtab))
606 Symtab = std::move(NewSymtab);
610template <
class IntPtrT>
616template <
class IntPtrT>
622template <
class IntPtrT>
626 if (NumCounters == 0)
630 if (CounterBaseOffset < 0)
633 (
"counter offset " +
Twine(CounterBaseOffset) +
" is negative").str());
635 if (CounterBaseOffset >= CountersEnd - CountersStart)
637 (
"counter offset " +
Twine(CounterBaseOffset) +
638 " is greater than the maximum counter offset " +
639 Twine(CountersEnd - CountersStart - 1))
643 (CountersEnd - (CountersStart + CounterBaseOffset)) /
644 getCounterTypeSize();
645 if (NumCounters > MaxNumCounters)
647 (
"number of counters " +
Twine(NumCounters) +
648 " is greater than the maximum number of counters " +
649 Twine(MaxNumCounters))
653 Record.Counts.reserve(NumCounters);
656 CountersStart + CounterBaseOffset +
I * getCounterTypeSize();
657 if (
I == 0 && hasTemporalProfile()) {
659 if (TimestampValue != 0 &&
660 TimestampValue != std::numeric_limits<uint64_t>::max()) {
661 TemporalProfTimestamps.emplace_back(TimestampValue,
663 TemporalProfTraceStreamSize = 1;
665 if (hasSingleByteCoverage()) {
674 if (hasSingleByteCoverage()) {
676 Record.Counts.push_back(*
Ptr == 0 ? 1 : 0);
678 const auto *CounterValue =
reinterpret_cast<const uint64_t *
>(
Ptr);
686template <
class IntPtrT>
690 CurValueDataSize = 0;
694 NumValueKinds += (
Data->NumValueSites[
I] != 0);
700 ValueProfData::getValueProfData(
701 ValueDataStart, (
const unsigned char *)DataBuffer->getBufferEnd(),
702 getDataEndianness());
710 VDataPtrOrErr.
get()->deserializeTo(
Record, Symtab.get());
711 CurValueDataSize = VDataPtrOrErr.
get()->getSize();
715template <
class IntPtrT>
721 if (
Error E = readNextHeader(getNextHeaderPos()))
722 return error(std::move(
E));
726 return error(std::move(
E));
730 return error(std::move(
E));
734 return error(std::move(
E));
738 return error(std::move(
E));
745template <
class IntPtrT>
747 std::vector<llvm::object::BuildID> &BinaryIds) {
749 BinaryIds, getDataEndianness());
752template <
class IntPtrT>
755 getDataEndianness());
774 const unsigned char *&
D,
const unsigned char *
const End) {
776 ValueProfData::getValueProfData(
D,
End, ValueProfDataEndianness);
781 VDataPtrOrErr.
get()->deserializeTo(DataBuffer.back(),
nullptr);
782 D += VDataPtrOrErr.
get()->TotalSize;
789 using namespace support;
796 std::vector<uint64_t> CounterBuffer;
798 const unsigned char *
End =
D +
N;
803 uint64_t Hash = endian::readNext<uint64_t, little, unaligned>(
D);
811 CountsSize = endian::readNext<uint64_t, little, unaligned>(
D);
817 CounterBuffer.clear();
818 CounterBuffer.reserve(CountsSize);
819 for (
uint64_t J = 0; J < CountsSize; ++J)
820 CounterBuffer.push_back(endian::readNext<uint64_t, little, unaligned>(
D));
822 DataBuffer.emplace_back(K, Hash, std::move(CounterBuffer));
834template <
typename HashTableImpl>
837 auto Iter = HashTable->find(FuncName);
838 if (Iter == HashTable->end())
844 "profile data is empty");
849template <
typename HashTableImpl>
855 Data = *RecordIterator;
859 "profile data is empty");
864template <
typename HashTableImpl>
866 const unsigned char *Buckets,
const unsigned char *
const Payload,
869 FormatVersion = Version;
870 HashTable.reset(HashTableImpl::Create(
871 Buckets, Payload,
Base,
872 typename HashTableImpl::InfoType(HashType, Version)));
873 RecordIterator = HashTable->data_begin();
876template <
typename HashTableImpl>
888 : Underlying(Underlying) {}
892 return Underlying.getRecords(FuncName,
Data);
898template <
typename HashTableImpl>
903 std::unique_ptr<MemoryBuffer> RemapBuffer,
905 : RemapBuffer(
std::
move(RemapBuffer)), Underlying(Underlying) {
915 Parts = Parts.second.split(
':');
916 if (Parts.first.startswith(
"_Z"))
918 if (Parts.second.empty())
939 if (
auto Key = Remappings.
insert(RealName)) {
943 MappedNames.insert({Key, RealName});
952 if (
auto Key = Remappings.
lookup(RealName)) {
953 StringRef Remapped = MappedNames.lookup(Key);
954 if (!Remapped.
empty()) {
956 RealName.
end() == FuncName.
end())
962 Error E = Underlying.getRecords(Reconstituted,
Data);
969 std::move(
E), [](std::unique_ptr<InstrProfError> Err) {
972 :
Error(std::move(Err));
978 return Underlying.getRecords(FuncName,
Data);
984 std::unique_ptr<MemoryBuffer> RemapBuffer;
1000 using namespace support;
1005 endian::read<uint64_t, little, aligned>(DataBuffer.
getBufferStart());
1010const unsigned char *
1012 const unsigned char *Cur,
bool UseCS) {
1013 using namespace IndexedInstrProf;
1014 using namespace support;
1025 std::unique_ptr<IndexedInstrProf::Summary> SummaryData =
1030 for (
unsigned I = 0;
I < SummarySize /
sizeof(
uint64_t);
I++)
1031 Dst[
I] = endian::byte_swap<uint64_t, little>(Src[
I]);
1034 for (
unsigned I = 0;
I < SummaryData->NumCutoffEntries;
I++) {
1039 std::unique_ptr<llvm::ProfileSummary> &Summary =
1040 UseCS ? this->CS_Summary : this->Summary;
1043 Summary = std::make_unique<ProfileSummary>(
1045 DetailedSummary, SummaryData->get(Summary::TotalBlockCount),
1046 SummaryData->get(Summary::MaxBlockCount),
1047 SummaryData->get(Summary::MaxInternalBlockCount),
1048 SummaryData->get(Summary::MaxFunctionCount),
1049 SummaryData->get(Summary::TotalNumBlocks),
1050 SummaryData->get(Summary::TotalNumFunctions));
1051 return Cur + SummarySize;
1059 Summary =
Builder.getSummary();
1065 using namespace support;
1067 const unsigned char *Start =
1068 (
const unsigned char *)DataBuffer->getBufferStart();
1069 const unsigned char *Cur = Start;
1070 if ((
const unsigned char *)DataBuffer->getBufferEnd() - Cur < 24)
1075 return HeaderOr.takeError();
1078 Cur += Header->size();
1082 if (Header->formatVersion() & VARIANT_MASK_CSIR_PROF)
1088 endian::byte_swap<uint64_t, little>(Header->HashType));
1092 uint64_t HashOffset = endian::byte_swap<uint64_t, little>(Header->HashOffset);
1095 auto IndexPtr = std::make_unique<InstrProfReaderIndex<OnDiskHashTableImplV3>>(
1096 Start + HashOffset, Cur, Start, HashType, Header->formatVersion());
1100 if (GET_VERSION(Header->formatVersion()) >= 8 &&
1101 Header->formatVersion() & VARIANT_MASK_MEMPROF) {
1103 endian::byte_swap<uint64_t, little>(Header->MemProfOffset);
1105 const unsigned char *
Ptr = Start + MemProfOffset;
1108 support::endian::readNext<uint64_t, little, unaligned>(
Ptr);
1111 const uint64_t FramePayloadOffset =
1112 support::endian::readNext<uint64_t, little, unaligned>(
Ptr);
1115 support::endian::readNext<uint64_t, little, unaligned>(
Ptr);
1120 return SchemaOr.takeError();
1121 Schema = SchemaOr.get();
1125 Start + RecordTableOffset,
1131 Start + FrameTableOffset,
1132 Start + FramePayloadOffset,
1138 if (GET_VERSION(Header->formatVersion()) >= 9) {
1140 endian::byte_swap<uint64_t, little>(Header->BinaryIdOffset);
1141 const unsigned char *
Ptr = Start + BinaryIdOffset;
1143 BinaryIdsSize = support::endian::readNext<uint64_t, little, unaligned>(
Ptr);
1144 if (BinaryIdsSize %
sizeof(
uint64_t))
1147 BinaryIdsStart =
Ptr;
1148 if (BinaryIdsStart > (
const unsigned char *)DataBuffer->getBufferEnd())
1150 "corrupted binary ids");
1153 if (GET_VERSION(Header->formatVersion()) >= 10 &&
1154 Header->formatVersion() & VARIANT_MASK_TEMPORAL_PROF) {
1155 uint64_t TemporalProfTracesOffset =
1156 endian::byte_swap<uint64_t, little>(Header->TemporalProfTracesOffset);
1157 const unsigned char *
Ptr = Start + TemporalProfTracesOffset;
1158 const auto *PtrEnd = (
const unsigned char *)DataBuffer->getBufferEnd();
1163 support::endian::readNext<uint64_t, little, unaligned>(
Ptr);
1165 support::endian::readNext<uint64_t, little, unaligned>(
Ptr);
1166 for (
unsigned i = 0; i < NumTraces; i++) {
1172 support::endian::readNext<uint64_t, little, unaligned>(
Ptr);
1174 support::endian::readNext<uint64_t, little, unaligned>(
Ptr);
1176 if (
Ptr + NumFunctions *
sizeof(
uint64_t) > PtrEnd)
1178 for (
unsigned j = 0; j < NumFunctions; j++) {
1180 support::endian::readNext<uint64_t, little, unaligned>(
Ptr);
1181 Trace.FunctionNameRefs.push_back(NameRef);
1188 if (RemappingBuffer) {
1190 std::make_unique<InstrProfReaderItaniumRemapper<OnDiskHashTableImplV3>>(
1191 std::move(RemappingBuffer), *IndexPtr);
1192 if (
Error E = Remapper->populateRemappings())
1195 Remapper = std::make_unique<InstrProfReaderNullRemapper>(*IndexPtr);
1197 Index = std::move(IndexPtr);
1206 std::unique_ptr<InstrProfSymtab> NewSymtab = std::make_unique<InstrProfSymtab>();
1207 if (
Error E =
Index->populateSymtab(*NewSymtab)) {
1212 Symtab = std::move(NewSymtab);
1220 Error Err = Remapper->getRecords(FuncName,
Data);
1222 return std::move(Err);
1227 bool CSBitMatch =
false;
1228 auto getFuncSum = [](
const std::vector<uint64_t> &Counts) {
1230 for (
uint64_t CountValue : Counts) {
1234 if (std::numeric_limits<uint64_t>::max() - CountValue <= ValueSum)
1235 return std::numeric_limits<uint64_t>::max();
1236 ValueSum += CountValue;
1243 if (
I.Hash == FuncHash)
1244 return std::move(
I);
1248 if (MismatchedFuncSum ==
nullptr)
1250 FuncSum = std::max(FuncSum, getFuncSum(
I.Counts));
1254 if (MismatchedFuncSum !=
nullptr)
1255 *MismatchedFuncSum = FuncSum;
1264 if (MemProfRecordTable ==
nullptr)
1266 "no memprof data available in profile");
1267 auto Iter = MemProfRecordTable->find(FuncNameHash);
1268 if (Iter == MemProfRecordTable->end())
1269 return make_error<InstrProfError>(
1271 "memprof record not found for function hash " +
Twine(FuncNameHash));
1276 bool HasFrameMappingError =
false;
1278 auto FrIter = MemProfFrameTable->find(Id);
1279 if (FrIter == MemProfFrameTable->end()) {
1280 LastUnmappedFrameId = Id;
1281 HasFrameMappingError =
true;
1290 if (HasFrameMappingError) {
1292 "memprof frame not found for frame id " +
1293 Twine(LastUnmappedFrameId));
1300 std::vector<uint64_t> &Counts) {
1303 return error(std::move(
E));
1305 Counts =
Record.get().Counts;
1314 return error(std::move(
E));
1317 if (RecordIndex >=
Data.size()) {
1318 Index->advanceToNextKey();
1325 std::vector<llvm::object::BuildID> &BinaryIds) {
1337 for (
const auto &Func : *
this) {
1340 if (FuncIsCS != IsCS)
1343 Func.accumulateCounts(Sum);
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.
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS)
static Error printBinaryIdsInternal(raw_ostream &OS, const MemoryBuffer &DataBuffer, uint64_t BinaryIdsSize, const uint8_t *BinaryIdsStart, llvm::support::endianness Endian)
static Error initializeReader(InstrProfReader &Reader)
#define READ_NUM(Str, Dst)
#define CHECK_LINE_END(Line)
#define VP_READ_ADVANCE(Val)
static InstrProfKind getProfileKindFromVersion(uint64_t Version)
static Error readBinaryIdsInternal(const MemoryBuffer &DataBuffer, const uint64_t BinaryIdsSize, const uint8_t *BinaryIdsStart, std::vector< llvm::object::BuildID > &BinaryIds, const llvm::support::endianness Endian)
Read a list of binary ids from a profile that consist of a.
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Defines the virtual file system interface vfs::FileSystem.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
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.
Expected< memprof::MemProfRecord > getMemProfRecord(uint64_t FuncNameHash)
Return the memprof record for the function identified by llvm::md5(Name).
Error readHeader() override
Read the file header.
Error printBinaryIds(raw_ostream &OS) override
Print binary ids.
Expected< InstrProfRecord > getInstrProfRecord(StringRef FuncName, uint64_t FuncHash, uint64_t *MismatchedFuncSum=nullptr)
Return the NamedInstrProfRecord associated with FuncName and FuncHash.
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.
Error readBinaryIds(std::vector< llvm::object::BuildID > &BinaryIds) override
Read a list of binary ids.
InstrProfCorrelator - A base class used to create raw instrumentation data to their functions.
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.
static Expected< std::unique_ptr< InstrProfReader > > create(const Twine &Path, vfs::FileSystem &FS, const InstrProfCorrelator *Correlator=nullptr)
Factory method to create an appropriately typed reader for the given instrprof file.
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.
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
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.
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 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).
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
bool startswith(StringRef Prefix) const
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.
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)
Expected< MemProfSchema > readMemProfSchema(const unsigned char *&Buffer)
unsigned char getSwappedBytes(unsigned char C)
This is an optimization pass for GlobalISel generic memory operations.
RawInstrProfReader< uint32_t > RawInstrProfReader32
uint64_t alignToPowerOf2(uint64_t Value, uint64_t Align)
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
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
@ missing_debug_info_for_correlation
@ unexpected_debug_info_for_correlation
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...
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.
@ FunctionEntryInstrumentation
@ FrontendInstrumentation
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.