45#include <system_error>
49using namespace sampleprof;
51#define DEBUG_TYPE "samplepgo-reader"
58 cl::desc(
"Profile uses flow sensitive discriminators"));
71 std::vector<NameFunctionSamples> V;
73 for (
const auto &
I : V)
80 for (
const auto &
I : BodySamples) {
90 if (!CallTargets.empty()) {
92 for (
const auto &J : CallTargets) {
105 for (
const auto &
I : CallsiteSamples)
106 for (
const auto &FS :
I.second) {
126 if (!BodySamples.empty())
130 if (!CallsiteSamples.empty())
132 [&] { DumpCallsiteSamples(CallsiteSamples); });
138 std::vector<NameFunctionSamples> V;
142 for (
const auto &
F : V)
161 size_t n2 = Input.
rfind(
':');
162 size_t n1 = Input.
rfind(
':', n2 - 1);
163 FName = Input.
substr(0, n1);
224 if (Input[
Depth] ==
'!') {
225 LineTy = LineType::Metadata;
229 size_t n1 = Input.
find(
':');
231 size_t n2 = Loc.
find(
'.');
245 LineTy = LineType::BodyProfile;
246 size_t n3 = Rest.
find(
' ');
296 if (n4 == Rest.
size())
302 LineTy = LineType::CallSiteProfile;
304 CalleeName = Rest.
substr(0, n3);
322 uint32_t TopLevelProbeProfileCount = 0;
332 if (pos == LineIt->
npos || (*LineIt)[pos] ==
'#')
346 if ((*LineIt)[0] !=
' ') {
347 uint64_t NumSamples, NumHeadSamples;
349 if (!
ParseHead(*LineIt, FName, NumSamples, NumHeadSamples)) {
351 "Expected 'mangled_name:NUM:NUM', found " + *LineIt);
374 Discriminator, FName, TargetCountMap, FunctionHash,
377 "Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " +
381 if (LineTy != LineType::Metadata &&
Depth == DepthMetadata) {
384 "Found non-metadata after metadata: " + *LineIt);
395 case LineType::CallSiteProfile: {
397 LineLocation(LineOffset, Discriminator))[std::string(FName)];
404 case LineType::BodyProfile: {
409 for (
const auto &name_count : TargetCountMap) {
411 LineOffset, Discriminator, name_count.first,
418 case LineType::Metadata: {
423 ++TopLevelProbeProfileCount;
428 DepthMetadata =
Depth;
436 "Cannot have both context-sensitive and regular profile");
438 assert((TopLevelProbeProfileCount == 0 ||
439 TopLevelProbeProfileCount ==
Profiles.size()) &&
440 "Cannot have both probe-based profiles and regular profiles");
458 if ((*LineIt)[0] !=
' ') {
459 uint64_t NumSamples, NumHeadSamples;
461 result =
ParseHead(*LineIt, FName, NumSamples, NumHeadSamples);
469 unsigned NumBytesRead = 0;
473 if (Val > std::numeric_limits<T>::max())
475 else if (
Data + NumBytesRead >
End)
485 Data += NumBytesRead;
486 return static_cast<T>(Val);
492 if (
Data + Str.size() + 1 >
End) {
498 Data += Str.size() + 1;
512 using namespace support;
513 T Val = endian::readNext<T, little, unaligned>(
Data);
520 auto Idx = readNumber<uint32_t>();
521 if (std::error_code EC =
Idx.getError())
523 if (*
Idx >= Table.size())
530 if (std::error_code EC =
Idx.getError())
538 if (std::error_code EC = FName.getError())
549 if (std::error_code EC =
Idx.getError())
556 const uint8_t *SavedData =
Data;
558 auto FID = readUnencodedNumber<uint64_t>();
559 if (std::error_code EC = FID.getError())
573 if (std::error_code EC =
Idx.getError())
581 auto NumSamples = readNumber<uint64_t>();
582 if (std::error_code EC = NumSamples.getError())
587 auto NumRecords = readNumber<uint32_t>();
588 if (std::error_code EC = NumRecords.getError())
592 auto LineOffset = readNumber<uint64_t>();
593 if (std::error_code EC = LineOffset.getError())
597 return std::error_code();
600 auto Discriminator = readNumber<uint64_t>();
601 if (std::error_code EC = Discriminator.getError())
604 auto NumSamples = readNumber<uint64_t>();
605 if (std::error_code EC = NumSamples.getError())
608 auto NumCalls = readNumber<uint32_t>();
609 if (std::error_code EC = NumCalls.getError())
615 for (
uint32_t J = 0; J < *NumCalls; ++J) {
617 if (std::error_code EC = CalledFunction.getError())
620 auto CalledFunctionSamples = readNumber<uint64_t>();
621 if (std::error_code EC = CalledFunctionSamples.getError())
625 *CalledFunction, *CalledFunctionSamples);
628 FProfile.
addBodySamples(*LineOffset, DiscriminatorVal, *NumSamples);
632 auto NumCallsites = readNumber<uint32_t>();
633 if (std::error_code EC = NumCallsites.getError())
636 for (
uint32_t J = 0; J < *NumCallsites; ++J) {
637 auto LineOffset = readNumber<uint64_t>();
638 if (std::error_code EC = LineOffset.getError())
641 auto Discriminator = readNumber<uint64_t>();
642 if (std::error_code EC = Discriminator.getError())
646 if (std::error_code EC = FName.getError())
653 LineLocation(*LineOffset, DiscriminatorVal))[std::string(*FName)];
655 if (std::error_code EC =
readProfile(CalleeProfile))
665 auto NumHeadSamples = readNumber<uint64_t>();
666 if (std::error_code EC = NumHeadSamples.getError())
670 if (std::error_code EC = FContext.
getError())
678 if (FContext->hasContext())
699 auto ContextIdx = readNumber<uint32_t>();
700 if (std::error_code EC = ContextIdx.getError())
711 if (std::error_code EC = FContext.getError())
716 if (std::error_code EC = FName.getError())
726 switch (Entry.Type) {
731 Summary->setPartialProfile(
true);
744 "If FixedLengthMD5 is true, UseMD5 has to be true");
802 auto Size = readNumber<uint64_t>();
803 if (std::error_code EC =
Size.getError())
810 std::make_unique<std::vector<std::pair<SampleContext, uint64_t>>>();
816 if (std::error_code EC = FContext.getError())
819 auto Offset = readNumber<uint64_t>();
820 if (std::error_code EC =
Offset.getError())
841 const uint8_t *Start =
Data;
842 if (!LoadFuncsToBeUsed) {
871 "func offset table should always be sorted in CS profile");
874 const auto &FContext = NameOffset.first;
875 auto FName = FContext.
getName();
879 if ((
useMD5() && FuncGuidsToUse.
count(std::stoull(FName.data()))) ||
882 if (!CommonContext || !CommonContext->
IsPrefixOf(FContext))
883 CommonContext = &FContext;
886 if (CommonContext == &FContext ||
887 (CommonContext && CommonContext->
IsPrefixOf(FContext))) {
890 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
891 assert(FuncProfileAddr <
End &&
"out of LBRProfile section");
903 const uint8_t *FuncProfileAddr = Start + iter->second;
904 assert(FuncProfileAddr <
End &&
"out of LBRProfile section");
911 auto FuncName = FContext.
getName();
915 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
916 assert(FuncProfileAddr <
End &&
"out of LBRProfile section");
925 "Cannot have both context-sensitive and regular profile");
927 "Section flag should be consistent with actual profile");
933 ProfSymList = std::make_unique<ProfileSymbolList>();
942std::error_code SampleProfileReaderExtBinaryBase::decompressSection(
943 const uint8_t *SecStart,
const uint64_t SecSize,
944 const uint8_t *&DecompressBuf,
uint64_t &DecompressBufSize) {
946 End = SecStart + SecSize;
947 auto DecompressSize = readNumber<uint64_t>();
948 if (std::error_code EC = DecompressSize.getError())
950 DecompressBufSize = *DecompressSize;
952 auto CompressSize = readNumber<uint64_t>();
953 if (std::error_code EC = CompressSize.getError())
960 size_t UCSize = DecompressBufSize;
965 DecompressBuf =
reinterpret_cast<const uint8_t *
>(
Buffer);
970 const uint8_t *BufStart =
971 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
982 const uint8_t *SecStart = BufStart + Entry.Offset;
991 const uint8_t *DecompressBuf;
993 if (std::error_code EC = decompressSection(
994 SecStart, SecSize, DecompressBuf, DecompressBufSize))
996 SecStart = DecompressBuf;
997 SecSize = DecompressBufSize;
1000 if (std::error_code EC =
readOneSection(SecStart, SecSize, Entry))
1002 if (
Data != SecStart + SecSize)
1007 Data = BufStart + Entry.Offset;
1008 End = BufStart +
Buffer->getBufferSize();
1021 std::vector<uint64_t> OffsetsToUse;
1022 if (!LoadFuncsToBeUsed) {
1024 for (
auto FuncEntry : FuncOffsetTable) {
1025 OffsetsToUse.push_back(FuncEntry.second);
1029 for (
auto Name : FuncsToUse) {
1031 auto iter = FuncOffsetTable.find(
StringRef(GUID));
1032 if (iter == FuncOffsetTable.end())
1034 OffsetsToUse.push_back(iter->second);
1038 for (
auto Offset : OffsetsToUse) {
1039 const uint8_t *SavedData =
Data;
1041 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart()) +
1049std::error_code SampleProfileReaderRawBinary::verifySPMagic(
uint64_t Magic) {
1055std::error_code SampleProfileReaderExtBinary::verifySPMagic(
uint64_t Magic) {
1062SampleProfileReaderCompactBinary::verifySPMagic(
uint64_t Magic) {
1069 auto Size = readNumber<uint32_t>();
1070 if (std::error_code EC =
Size.getError())
1075 if (std::error_code EC =
Name.getError())
1084 auto Size = readNumber<uint64_t>();
1085 if (std::error_code EC =
Size.getError())
1087 MD5StringBuf = std::make_unique<std::vector<std::string>>();
1102 auto FID = readNumber<uint64_t>();
1103 if (std::error_code EC = FID.getError())
1124 auto Size = readNumber<uint32_t>();
1125 if (std::error_code EC =
Size.getError())
1128 std::vector<SampleContextFrameVector> *PNameVec =
1129 new std::vector<SampleContextFrameVector>();
1130 PNameVec->reserve(*
Size);
1133 auto ContextSize = readNumber<uint32_t>();
1134 if (std::error_code EC = ContextSize.getError())
1136 for (
uint32_t J = 0; J < *ContextSize; ++J) {
1138 if (std::error_code EC = FName.getError())
1140 auto LineOffset = readNumber<uint64_t>();
1141 if (std::error_code EC = LineOffset.getError())
1145 return std::error_code();
1147 auto Discriminator = readNumber<uint64_t>();
1148 if (std::error_code EC = Discriminator.getError())
1151 PNameVec->back().emplace_back(
1152 FName.get(),
LineLocation(LineOffset.get(), Discriminator.get()));
1167 auto Checksum = readNumber<uint64_t>();
1168 if (std::error_code EC = Checksum.getError())
1174 if (ProfileHasAttribute) {
1176 if (std::error_code EC =
Attributes.getError())
1184 auto NumCallsites = readNumber<uint32_t>();
1185 if (std::error_code EC = NumCallsites.getError())
1188 for (
uint32_t J = 0; J < *NumCallsites; ++J) {
1189 auto LineOffset = readNumber<uint64_t>();
1190 if (std::error_code EC = LineOffset.getError())
1193 auto Discriminator = readNumber<uint64_t>();
1194 if (std::error_code EC = Discriminator.getError())
1198 if (std::error_code EC = FContext.getError())
1206 *Discriminator))[std::string(FContext.get().getName())]);
1208 if (std::error_code EC =
1222 if (std::error_code EC = FContext.getError())
1225 auto It =
Profiles.find(*FContext);
1227 FProfile = &It->second;
1237std::error_code SampleProfileReaderCompactBinary::readNameTable() {
1238 auto Size = readNumber<uint64_t>();
1239 if (std::error_code EC =
Size.getError())
1241 NameTable.reserve(*
Size);
1243 auto FID = readNumber<uint64_t>();
1244 if (std::error_code EC = FID.getError())
1246 NameTable.push_back(std::to_string(*FID));
1254 auto Type = readUnencodedNumber<uint64_t>();
1255 if (std::error_code EC =
Type.getError())
1257 Entry.Type =
static_cast<SecType>(*Type);
1259 auto Flags = readUnencodedNumber<uint64_t>();
1260 if (std::error_code EC =
Flags.getError())
1262 Entry.Flags = *
Flags;
1264 auto Offset = readUnencodedNumber<uint64_t>();
1265 if (std::error_code EC =
Offset.getError())
1269 auto Size = readUnencodedNumber<uint64_t>();
1270 if (std::error_code EC =
Size.getError())
1274 Entry.LayoutIndex =
Idx;
1280 auto EntryNum = readUnencodedNumber<uint64_t>();
1281 if (std::error_code EC = EntryNum.getError())
1284 for (
uint64_t i = 0; i < (*EntryNum); i++)
1292 const uint8_t *BufStart =
1293 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1295 End = BufStart +
Buffer->getBufferSize();
1309 if (Entry.Type ==
Type)
1323 FileSize = std::max(Entry.Offset + Entry.Size, FileSize);
1331 Flags.append(
"{compressed,");
1336 Flags.append(
"flat,");
1338 switch (Entry.Type) {
1341 Flags.append(
"fixlenmd5,");
1343 Flags.append(
"md5,");
1345 Flags.append(
"uniq,");
1349 Flags.append(
"partial,");
1351 Flags.append(
"context,");
1353 Flags.append(
"preInlined,");
1355 Flags.append(
"fs-discriminator,");
1359 Flags.append(
"ordered,");
1363 Flags.append(
"probe,");
1365 Flags.append(
"attr,");
1370 char &last =
Flags.back();
1381 OS <<
getSecName(Entry.Type) <<
" - Offset: " << Entry.Offset
1382 <<
", Size: " << Entry.Size <<
", Flags: " <<
getSecFlagsStr(Entry)
1385 TotalSecsSize += Entry.Size;
1389 "Size of 'header + sections' doesn't match the total size of profile");
1391 OS <<
"Header Size: " << HeaderSize <<
"\n";
1392 OS <<
"Total Sections Size: " << TotalSecsSize <<
"\n";
1399 auto Magic = readNumber<uint64_t>();
1400 if (std::error_code EC = Magic.getError())
1402 else if (std::error_code EC = verifySPMagic(*Magic))
1406 auto Version = readNumber<uint64_t>();
1407 if (std::error_code EC = Version.getError())
1416 Data =
reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1430std::error_code SampleProfileReaderCompactBinary::readHeader() {
1432 if (std::error_code EC = readFuncOffsetTable())
1437std::error_code SampleProfileReaderCompactBinary::readFuncOffsetTable() {
1438 auto TableOffset = readUnencodedNumber<uint64_t>();
1439 if (std::error_code EC = TableOffset.getError())
1442 const uint8_t *SavedData =
Data;
1443 const uint8_t *TableStart =
1444 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart()) +
1448 auto Size = readNumber<uint64_t>();
1449 if (std::error_code EC =
Size.getError())
1452 FuncOffsetTable.reserve(*
Size);
1454 auto FName(readStringFromTable());
1455 if (std::error_code EC = FName.getError())
1458 auto Offset = readNumber<uint64_t>();
1459 if (std::error_code EC =
Offset.getError())
1462 FuncOffsetTable[*FName] = *
Offset;
1478std::error_code SampleProfileReaderBinary::readSummaryEntry(
1479 std::vector<ProfileSummaryEntry> &Entries) {
1480 auto Cutoff = readNumber<uint64_t>();
1481 if (std::error_code EC = Cutoff.getError())
1484 auto MinBlockCount = readNumber<uint64_t>();
1485 if (std::error_code EC = MinBlockCount.getError())
1488 auto NumBlocks = readNumber<uint64_t>();
1489 if (std::error_code EC = NumBlocks.getError())
1492 Entries.emplace_back(*Cutoff, *MinBlockCount, *NumBlocks);
1497 auto TotalCount = readNumber<uint64_t>();
1498 if (std::error_code EC = TotalCount.getError())
1501 auto MaxBlockCount = readNumber<uint64_t>();
1502 if (std::error_code EC = MaxBlockCount.getError())
1505 auto MaxFunctionCount = readNumber<uint64_t>();
1506 if (std::error_code EC = MaxFunctionCount.getError())
1509 auto NumBlocks = readNumber<uint64_t>();
1510 if (std::error_code EC = NumBlocks.getError())
1513 auto NumFunctions = readNumber<uint64_t>();
1514 if (std::error_code EC = NumFunctions.getError())
1517 auto NumSummaryEntries = readNumber<uint64_t>();
1518 if (std::error_code EC = NumSummaryEntries.getError())
1521 std::vector<ProfileSummaryEntry> Entries;
1522 for (
unsigned i = 0; i < *NumSummaryEntries; i++) {
1523 std::error_code EC = readSummaryEntry(Entries);
1527 Summary = std::make_unique<ProfileSummary>(
1529 *MaxFunctionCount, *NumBlocks, *NumFunctions);
1535 const uint8_t *
Data =
1536 reinterpret_cast<const uint8_t *
>(
Buffer.getBufferStart());
1542 const uint8_t *
Data =
1543 reinterpret_cast<const uint8_t *
>(
Buffer.getBufferStart());
1549 const uint8_t *
Data =
1550 reinterpret_cast<const uint8_t *
>(
Buffer.getBufferStart());
1566 return static_cast<T>(Val);
1567 }
else if (
sizeof(
T) <=
sizeof(
uint64_t)) {
1570 return static_cast<T>(Val);
1632 Names.push_back(std::string(Str));
1658 if (InlineStack.
size() == 0)
1677 if (InlineStack.
size() == 0) {
1725 for (
auto *CallerProfile : NewStack)
1726 CallerProfile->addTotalSamples(Count);
1735 for (
uint32_t J = 0; J < NumTargets; J++) {
1754 TargetName, TargetCount);
1795 StringRef Magic(
reinterpret_cast<const char *
>(
Buffer.getBufferStart()));
1796 return Magic ==
"adcg*704";
1805 "Profile data remapping cannot be applied to profile data "
1806 "in compact format (original mangled names are not available).",
1813 assert(Remappings &&
"should be initialized while creating remapper");
1816 Sample.second.findAllNames(NamesInSample);
1817 for (
auto &
Name : NamesInSample)
1818 if (
auto Key = Remappings->insert(
Name))
1819 NameMap.insert({Key,
Name});
1822 RemappingApplied =
true;
1825std::optional<StringRef>
1827 if (
auto Key = Remappings->lookup(Fname))
1828 return NameMap.lookup(Key);
1829 return std::nullopt;
1838 : FS.getBufferForFile(Filename);
1839 if (std::error_code EC = BufferOrErr.getError())
1841 auto Buffer = std::move(BufferOrErr.get());
1843 return std::move(Buffer);
1860 const std::string RemapFilename) {
1862 if (std::error_code EC = BufferOrError.getError())
1864 return create(BufferOrError.get(),
C, FS,
P, RemapFilename);
1883 if (std::error_code EC = BufferOrError.getError())
1885 return create(BufferOrError.get(), Reader,
C);
1902 auto Remappings = std::make_unique<SymbolRemappingReader>();
1903 if (
Error E = Remappings->read(*
B)) {
1913 return std::make_unique<SampleProfileReaderItaniumRemapper>(
1914 std::move(
B), std::move(Remappings), Reader);
1931 const std::string RemapFilename) {
1932 std::unique_ptr<SampleProfileReader> Reader;
1946 if (!RemapFilename.empty()) {
1948 RemapFilename, FS, *Reader,
C);
1949 if (std::error_code EC = ReaderOrErr.getError()) {
1950 std::string Msg =
"Could not create remapper: " + EC.message();
1954 Reader->Remapper = std::move(ReaderOrErr.get());
1957 if (std::error_code EC = Reader->readHeader()) {
1961 Reader->setDiscriminatorMaskedBitFrom(
P);
1963 return std::move(Reader);
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
Provides ErrorOr<T> smart pointer.
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS)
This file supports working with JSON data.
Module.h This file contains the declarations for the Module class.
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool ParseHead(const StringRef &Input, StringRef &FName, uint64_t &NumSamples, uint64_t &NumHeadSamples)
Parse Input as function head.
static void dumpFunctionProfileJson(const FunctionSamples &S, json::OStream &JOS, bool TopLevel=false)
static bool isOffsetLegal(unsigned L)
Returns true if line offset L is legal (only has 16 bits).
static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth, uint64_t &NumSamples, uint32_t &LineOffset, uint32_t &Discriminator, StringRef &CalleeName, DenseMap< StringRef, uint64_t > &TargetCountMap, uint64_t &FunctionHash, uint32_t &Attributes)
Parse Input as line sample.
static cl::opt< bool > ProfileIsFSDisciminator("profile-isfs", cl::Hidden, cl::init(false), cl::desc("Profile uses flow sensitive discriminators"))
static std::string getSecFlagsStr(const SecHdrTableEntry &Entry)
static bool parseMetadata(const StringRef &Input, uint64_t &FunctionHash, uint32_t &Attributes)
Parse Input that contains metadata.
Defines the virtual file system interface vfs::FileSystem.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
Implements a dense probed hash-table based set.
Diagnostic information for the sample profiler.
Represents either an error or a value T.
std::error_code getError() const
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
bool readInt(uint32_t &Val)
bool readInt64(uint64_t &Val)
bool readGCOVVersion(GCOV::GCOVVersion &version)
readGCOVVersion - Read GCOV version.
bool readString(StringRef &str)
bool readGCDAFormat()
readGCDAFormat - Check GCDA signature is valid at the beginning of buffer.
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
This is an important class for using LLVM in a threaded context.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getSTDIN()
Read all of stdin into a file buffer, and return it.
static const ArrayRef< uint32_t > DefaultCutoffs
A vector of useful cutoff values for detailed summary.
void push_back(const 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.
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.
size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
bool startswith(StringRef Prefix) const
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
static constexpr size_t npos
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
int64_t getLineNum() const
StringRef getMessage() const
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
void object(Block Contents)
Emit an object whose elements are emitted in the provided Block.
void attribute(llvm::StringRef Key, const Value &Contents)
Emit an attribute whose value is self-contained (number, vector<int> etc).
void attributeArray(llvm::StringRef Key, Block Contents)
Emit an attribute whose value is an array with elements from the Block.
A forward iterator which reads text lines from a buffer.
int64_t line_number() const
Return the current line number. May return any number at EOF.
bool is_at_eof() const
Return true if we've reached EOF or are an "end" iterator.
This class implements an extremely fast bulk output stream that can only output to a stream.
Representation of the samples collected for a function.
static bool ProfileIsPreInlined
void setName(StringRef FunctionName)
Set the name of the function.
sampleprof_error addTotalSamples(uint64_t Num, uint64_t Weight=1)
uint64_t getHeadSamples() const
For top-level functions, return the total number of branch samples that have the function as the bran...
sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight=1)
FunctionSamplesMap & functionSamplesAt(const LineLocation &Loc)
Return the function samples at the given callsite location.
static bool ProfileIsProbeBased
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
sampleprof_error addBodySamples(uint32_t LineOffset, uint32_t Discriminator, uint64_t Num, uint64_t Weight=1)
void setFunctionHash(uint64_t Hash)
static bool ProfileIsFS
If this profile uses flow sensitive discriminators.
sampleprof_error addCalledTargetSamples(uint32_t LineOffset, uint32_t Discriminator, StringRef FName, uint64_t Num, uint64_t Weight=1)
SampleContext & getContext() const
static bool HasUniqSuffix
Whether the profile contains any ".__uniq." suffix in a name.
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
const CallsiteSampleMap & getCallsiteSamples() const
Return all the callsite samples collected in the body of the function.
void setContext(const SampleContext &FContext)
StringRef getName() const
Return the function name.
const BodySampleMap & getBodySamples() const
Return all the samples collected in the body of the function.
StringRef getName() const
void setAllAttributes(uint32_t A)
bool IsPrefixOf(const SampleContext &That) const
std::string toString() const
std::error_code readProfile(FunctionSamples &FProfile)
Read the contents of the given profile instance.
virtual std::error_code readNameTable()
Read the whole name table.
const uint8_t * Data
Points to the current location in the buffer.
ErrorOr< StringRef > readString()
Read a string from the profile.
std::vector< StringRef > NameTable
Function name table.
ErrorOr< T > readNumber()
Read a numeric value of type T from the profile.
std::error_code readHeader() override
Read and validate the file header.
virtual ErrorOr< StringRef > readStringFromTable()
Read a string indirectly via the name table.
bool at_eof() const
Return true if we've reached the end of file.
std::error_code readImpl() override
Read sample profiles from the associated file.
ErrorOr< uint32_t > readStringIndex(T &Table)
Read the string index and check whether it overflows the table.
virtual ErrorOr< SampleContext > readSampleContextFromTable()
const uint8_t * End
Points to the end of the buffer.
ErrorOr< T > readUnencodedNumber()
Read a numeric value of type T from the profile.
std::error_code readFuncProfile(const uint8_t *Start)
Read the next function profile instance.
std::error_code readSummary()
Read profile summary.
std::error_code readMagicIdent()
Read the contents of Magic number and Version number.
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
std::error_code readImpl() override
Read samples only for functions to use.
bool collectFuncsFromModule() override
Collect functions with definitions in Module M.
std::error_code readFuncOffsetTable()
std::vector< SecHdrTableEntry > SecHdrTable
ErrorOr< StringRef > readStringFromTable() override
Read a string indirectly via the name table.
std::error_code readFuncMetadata(bool ProfileHasAttribute)
std::error_code readNameTableSec(bool IsMD5)
bool collectFuncsFromModule() override
Collect functions with definitions in Module M.
uint64_t getSectionSize(SecType Type)
Get the total size of all Type sections.
std::error_code readCSNameTableSec()
virtual std::error_code readCustomSection(const SecHdrTableEntry &Entry)=0
std::unique_ptr< const std::vector< SampleContextFrameVector > > CSNameTable
CSNameTable is used to save full context vectors.
bool FixedLengthMD5
Use fixed length MD5 instead of ULEB128 encoding so NameTable doesn't need to be read in up front and...
DenseSet< StringRef > FuncsToUse
The set containing the functions to use when compiling a module.
ErrorOr< SampleContextFrames > readContextFromTable()
std::unique_ptr< ProfileSymbolList > ProfSymList
std::error_code readSecHdrTable()
std::error_code readFuncProfiles()
std::unique_ptr< std::vector< std::string > > MD5StringBuf
If MD5 is used in NameTable section, the section saves uint64_t data.
std::error_code readImpl() override
Read sample profiles in extensible format from the associated file.
bool useMD5() override
Return whether names in the profile are all MD5 numbers.
const uint8_t * MD5NameMemStart
The starting address of NameTable containing fixed length MD5.
virtual std::error_code readOneSection(const uint8_t *Start, uint64_t Size, const SecHdrTableEntry &Entry)
bool dumpSectionInfo(raw_ostream &OS=dbgs()) override
std::error_code readMD5NameTable()
std::error_code readSecHdrTableEntry(uint32_t Idx)
bool SkipFlatProf
If SkipFlatProf is true, skip the sections with SecFlagFlat flag.
std::error_code readHeader() override
Read and validate the file header.
uint64_t getFileSize()
Get the total size of header and all sections.
DenseMap< SampleContext, uint64_t > FuncOffsetTable
The table mapping from function context to the offset of its FunctionSample towards file start.
std::unique_ptr< std::vector< std::pair< SampleContext, uint64_t > > > OrderedFuncOffsets
Function offset mapping ordered by contexts.
std::error_code readProfileSymbolList()
ErrorOr< SampleContext > readSampleContextFromTable() override
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
ErrorOr< T > readNumber()
GCOVBuffer GcovBuffer
GCOV buffer containing the profile.
std::vector< std::string > Names
Function names in this profile.
std::error_code readImpl() override
Read sample profiles from the associated file.
std::error_code readNameTable()
std::error_code readHeader() override
Read and validate the file header.
ErrorOr< StringRef > readString()
static const uint32_t GCOVTagAFDOFunction
std::error_code readOneFunctionProfile(const InlineCallStack &InlineStack, bool Update, uint32_t Offset)
std::error_code readFunctionProfiles()
static const uint32_t GCOVTagAFDOFileNames
GCOV tags used to separate sections in the profile file.
std::error_code skipNextWord()
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
std::error_code readSectionTag(uint32_t Expected)
Read the section tag and check that it's the same as Expected.
static ErrorOr< std::unique_ptr< SampleProfileReaderItaniumRemapper > > create(const std::string Filename, vfs::FileSystem &FS, SampleProfileReader &Reader, LLVMContext &C)
Create a remapper from the given remapping file.
void applyRemapping(LLVMContext &Ctx)
Apply remappings to the profile read by Reader.
std::optional< StringRef > lookUpNameInProfile(StringRef FunctionName)
Return the equivalent name in the profile for FunctionName if it exists.
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
std::error_code readImpl() override
Read sample profiles from the associated file.
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Sample-based profile reader.
bool ProfileIsPreInlined
Whether function profile contains ShouldBeInlined contexts.
void dumpFunctionProfile(SampleContext FContext, raw_ostream &OS=dbgs())
Print the profile for FContext on stream OS.
SampleProfileMap & getProfiles()
Return all the profiles.
uint32_t CSProfileCount
Number of context-sensitive profiles.
void dump(raw_ostream &OS=dbgs())
Print all the profiles on stream OS.
const Module * M
The current module being compiled if SampleProfileReader is used by compiler.
std::unique_ptr< MemoryBuffer > Buffer
Memory buffer holding the profile file.
std::unique_ptr< SampleProfileReaderItaniumRemapper > Remapper
virtual bool useMD5()
Return whether names in the profile are all MD5 numbers.
MemoryBuffer * getBuffer() const
bool ProfileIsCS
Whether function profiles are context-sensitive flat profiles.
std::unique_ptr< ProfileSummary > Summary
Profile summary information.
void computeSummary()
Compute summary for this profile.
uint32_t getDiscriminatorMask() const
Get the bitmask the discriminators: For FS profiles, return the bit mask for this pass.
bool ProfileIsFS
Whether the function profiles use FS discriminators.
void dumpJson(raw_ostream &OS=dbgs())
Print all the profiles on stream OS in the JSON format.
static ErrorOr< std::unique_ptr< SampleProfileReader > > create(const std::string Filename, LLVMContext &C, vfs::FileSystem &FS, FSDiscriminatorPass P=FSDiscriminatorPass::Base, const std::string RemapFilename="")
Create a sample profile reader appropriate to the file format.
SampleProfileMap Profiles
Map every function to its associated profile.
bool ProfileIsProbeBased
Whether samples are collected based on pseudo probes.
void reportError(int64_t LineNumber, const Twine &Msg) const
Report a parse error message.
Representation of a single sample record.
uint64_t getSamples() const
const SortedCallTargetSet getSortedCallTargets() const
The virtual file system interface.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)
void sortFuncProfiles(const SampleProfileMap &ProfileMap, std::vector< NameFunctionSamples > &SortedProfiles)
static uint64_t SPMagic(SampleProfileFormat Format=SPF_Binary)
static bool hasSecFlag(const SecHdrTableEntry &Entry, SecFlagType Flag)
std::map< LineLocation, FunctionSamplesMap > CallsiteSampleMap
@ HIST_TYPE_INDIR_CALL_TOPN
std::map< LineLocation, SampleRecord > BodySampleMap
@ SecFlagIsPreInlined
SecFlagIsPreInlined means this profile contains ShouldBeInlined contexts thus this is CS preinliner c...
@ SecFlagPartial
SecFlagPartial means the profile is for common/shared code.
@ SecFlagFSDiscriminator
SecFlagFSDiscriminator means this profile uses flow-sensitive discriminators.
@ SecFlagFullContext
SecFlagContext means this is context-sensitive flat profile for CSSPGO.
SmallVector< SampleContextFrame, 1 > SampleContextFrameVector
static std::string getSecName(SecType Type)
static uint64_t SPVersion()
This is an optimization pass for GlobalISel generic memory operations.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
sampleprof_error MergeResult(sampleprof_error &Accumulator, sampleprof_error Result)
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...
uint64_t MD5Hash(StringRef Str)
Helper to compute and return lower 64 bits of the given string's MD5 hash.
Represents the relative location of an instruction.