48#include <system_error>
54#define DEBUG_TYPE "samplepgo-reader"
61 cl::desc(
"Profile uses flow sensitive discriminators"));
66 cl::desc(
"Lazy load the name table from the profile."));
74 OS <<
"Function: " << FS.getContext().toString() <<
": " << FS;
79 std::vector<NameFunctionSamples> V;
81 for (
const auto &
I : V)
88 for (
const auto &
I : BodySamples) {
93 if (
Loc.Discriminator)
95 JOS.
attribute(
"samples", Sample.getSamples());
97 auto CallTargets = Sample.getSortedCallTargets();
98 if (!CallTargets.empty()) {
100 for (
const auto &J : CallTargets) {
102 JOS.
attribute(
"function", J.first.str());
113 for (
const auto &
I : CallsiteSamples)
114 for (
const auto &FS :
I.second) {
119 if (
Loc.Discriminator)
134 if (!BodySamples.empty())
138 if (!CallsiteSamples.empty())
140 [&] { DumpCallsiteSamples(CallsiteSamples); });
146 std::vector<NameFunctionSamples> V;
150 for (
const auto &
F : V)
169 size_t n2 =
Input.rfind(
':');
170 size_t n1 =
Input.rfind(
':', n2 - 1);
171 FName =
Input.substr(0, n1);
172 if (
Input.substr(n1 + 1, n2 - n1 - 1).getAsInteger(10, NumSamples))
174 if (
Input.substr(n2 + 1).getAsInteger(10, NumHeadSamples))
191 if (
Input.starts_with(
"!CFGChecksum:")) {
196 if (
Input.starts_with(
"!Attributes:")) {
216 size_t ColonIndex =
Input.find(
':', Index);
221 size_t CountStartIndex = ColonIndex + 1;
223 size_t NextIndex =
Input.find_first_of(
' ', CountStartIndex);
225 if (
Input.substr(CountStartIndex, NextIndex - CountStartIndex)
226 .getAsInteger(10,
Count))
234 :
Input.find_first_not_of(
' ', NextIndex);
275 size_t n1 =
Input.find(
':');
277 size_t n2 =
Loc.find(
'.');
283 if (
Loc.substr(0, n2).getAsInteger(10, LineOffset))
285 if (
Loc.substr(n2 + 1).getAsInteger(10, Discriminator))
292 size_t n3 = Rest.
find(
' ');
342 if (n4 == Rest.
size())
354 CalleeName = Rest.
substr(0, n3);
372 uint32_t TopLevelProbeProfileCount = 0;
378 std::vector<SampleContext *> FlatSamples;
384 if (pos == LineIt->
npos || (*LineIt)[pos] ==
'#')
398 if ((*LineIt)[0] !=
' ') {
399 uint64_t NumSamples, NumHeadSamples;
401 if (!
ParseHead(*LineIt, FName, NumSamples, NumHeadSamples)) {
403 "Expected 'mangled_name:NUM:NUM', found " + *LineIt);
422 uint64_t FunctionHash = 0;
429 FunctionHash, Attributes, IsFlat)) {
433 "Cannot parse metadata: " + *LineIt);
437 "Expected 'vtables [mangled_vtable:NUM]+', found " +
442 "Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " +
450 "Found non-metadata after metadata: " + *LineIt);
473 Result, InlineStack.
back()->addCallsiteVTableTypeProfAt(
480 for (
const auto &name_count : TargetCountMap) {
482 LineOffset, Discriminator,
496 ++TopLevelProbeProfileCount;
501 DepthMetadata =
Depth;
504 FlatSamples.push_back(&FProfile.
getContext());
508 "!Flat may only be used at top level function.",
DS_Warning));
523 "Cannot have both context-sensitive and regular profile");
525 assert((TopLevelProbeProfileCount == 0 ||
526 TopLevelProbeProfileCount ==
Profiles.size()) &&
527 "Cannot have both probe-based profiles and regular profiles");
545 if ((*LineIt)[0] !=
' ') {
546 uint64_t NumSamples, NumHeadSamples;
548 result =
ParseHead(*LineIt, FName, NumSamples, NumHeadSamples);
558 std::error_code EC = ProfError;
567 unsigned NumBytesRead = 0;
572 switch (DecodeError) {
581 if (Val > std::numeric_limits<T>::max())
584 Data += NumBytesRead;
585 return static_cast<T>(Val);
592 const auto *Terminator =
static_cast<const uint8_t *
>(
593 std::memchr(
Data, 0,
static_cast<size_t>(
End -
Data)));
598 Data = Terminator + 1;
615 if (std::error_code EC = Idx.getError())
617 if (*Idx >=
Table.size())
627 if (std::error_code EC = Idx.getError())
637 if (std::error_code EC = ContextIdx.getError())
642 *RetIdx = *ContextIdx;
652 if (std::error_code EC = FContext.getError())
657 if (std::error_code EC = FName.getError())
669 Hash = Context.getHashCode();
672 return std::make_pair(Context, Hash);
678 if (std::error_code EC = NumVTableTypes.getError())
683 M.reserve(
M.size() + *NumVTableTypes);
687 if (std::error_code EC = VTableType.getError())
691 if (std::error_code EC = VTableSamples.getError())
694 auto [It, Inserted] =
M.try_emplace(*VTableType, *VTableSamples);
703 Buffer->getBufferIdentifier(), 0,
704 "Duplicate vtable type " + VTableType->str() +
705 " at the same location. Additional counters will be ignored.",
722 "Cannot read vtable profiles if ReadVTableProf is false");
726 if (std::error_code EC = NumCallsites.getError())
732 if (std::error_code EC = LineOffset.getError())
739 if (std::error_code EC = Discriminator.getError())
757 if (std::error_code EC = NumHeadSamples.getError())
762 if (std::error_code EC = NumSamples.getError())
768 if (std::error_code EC = NumRecords.getError())
774 if (std::error_code EC = LineOffset.getError())
782 if (std::error_code EC = Discriminator.getError())
786 if (std::error_code EC = NumSamples.getError())
790 if (std::error_code EC = NumCalls.getError())
796 for (
uint32_t J = 0; J < *NumCalls; ++J) {
798 if (std::error_code EC = CalledFunction.getError())
802 if (std::error_code EC = CalledFunctionSamples.getError())
806 *CalledFunction, *CalledFunctionSamples);
809 FProfile.
addBodySamples(*LineOffset, DiscriminatorVal, *NumSamples);
820 if (std::error_code EC = ProfNum.getError())
825 <<
"\n Profile blocks: " << *ProfNum <<
"\n";
832 for (uint64_t
I = 0;
I < *ProfNum; ++
I) {
834 if (std::error_code EC =
Type.getError())
838 if (!SeenTypes.
insert(*Type).second) {
843 if (std::error_code EC =
Size.getError())
848 <<
"), Payload size: " << *
Size <<
"\n";
849 const uint64_t RemainingSize =
End -
Data;
851 if (*
Size > RemainingSize) {
853 " declares payload size " +
Twine(*
Size) +
854 ", but only " +
Twine(RemainingSize) +
879 if (
Data != PayloadEnd) {
882 " did not consume its complete payload; unread bytes: " +
904 if (std::error_code EC = NumCallsites.getError())
907 for (
uint32_t J = 0; J < *NumCallsites; ++J) {
909 if (std::error_code EC = LineOffset.getError())
913 if (std::error_code EC = Discriminator.getError())
917 if (std::error_code EC = FName.getError())
926 if (std::error_code EC =
readProfile(CalleeProfile,
true))
943 if (std::error_code EC = NumHeadSamples.
getError())
947 if (std::error_code EC = FContextHash.getError())
950 auto &[FContext, Hash] = *FContextHash;
958 if (FContext.hasContext())
961 if (std::error_code EC =
readProfile(FProfile,
false))
986 switch (Entry.Type) {
991 Summary->setPartialProfile(
true);
1002 bool FixedLengthMD5 =
1011 if (std::error_code EC =
1040 bool IsNested = !IsFlat;
1044 "func offset table should always be sorted or in Eytzinger BFS "
1045 "order in CS profile");
1116 ProfilesToReadMetadata.
insert(&
I->second);
1148 size_t SpanSize =
NameTable->getEytzingerSpan(IsNested).size();
1169 if (std::error_code EC =
Size.getError())
1173 if (UseFuncOffsetList)
1178 for (uint64_t
I = 0;
I < *
Size; ++
I) {
1180 if (std::error_code EC = FContextHash.getError())
1183 auto &[FContext, Hash] = *FContextHash;
1185 if (std::error_code EC =
Offset.getError())
1188 if (UseFuncOffsetList)
1215 if (RelOffset == UINT32_MAX)
1217 const uint8_t *FuncProfileAddr = Start + RelOffset;
1241 const auto &FContext = NameOffset.first;
1253 if (!CommonContext || !CommonContext->
isPrefixOf(FContext))
1254 CommonContext = &FContext;
1257 if (CommonContext == &FContext ||
1258 (CommonContext && CommonContext->
isPrefixOf(FContext))) {
1261 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
1281 StringRef FuncNameStr = FuncName.stringRef();
1292 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
1321 if (!LoadFuncsToBeUsed) {
1334 "Cannot have both context-sensitive and regular profile");
1336 "Section flag should be consistent with actual profile");
1349 if (
Size %
sizeof(uint64_t) != 0)
1352 size_t NumEntries =
Size /
sizeof(uint64_t);
1354 ProfSymList = std::make_unique<ProfileSymbolList>();
1364 ProfSymList = std::make_unique<ProfileSymbolList>();
1373std::error_code SampleProfileReaderExtBinaryBase::decompressSection(
1374 const uint8_t *SecStart,
const uint64_t SecSize,
1375 const uint8_t *&DecompressBuf, uint64_t &DecompressBufSize) {
1377 End = SecStart + SecSize;
1379 if (std::error_code EC = DecompressSize.getError())
1381 DecompressBufSize = *DecompressSize;
1384 if (std::error_code EC = CompressSize.getError())
1391 size_t UCSize = DecompressBufSize;
1402 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1413 const uint8_t *SecStart = BufStart + Entry.Offset;
1414 uint64_t SecSize = Entry.Size;
1423 uint64_t DecompressBufSize;
1424 if (std::error_code EC = decompressSection(
1425 SecStart, SecSize, DecompressBuf, DecompressBufSize))
1427 SecStart = DecompressBuf;
1428 SecSize = DecompressBufSize;
1431 if (std::error_code EC =
readOneSection(SecStart, SecSize, Entry))
1433 if (
Data != SecStart + SecSize)
1438 Data = BufStart + Entry.Offset;
1439 End = BufStart +
Buffer->getBufferSize();
1446std::error_code SampleProfileReaderRawBinary::verifySPMagic(uint64_t Magic) {
1452std::error_code SampleProfileReaderExtBinary::verifySPMagic(uint64_t Magic) {
1460 if (std::error_code EC =
Size.getError())
1469 std::vector<FunctionId> TableVec;
1470 TableVec.reserve(*
Size);
1481 for (
size_t I = 0;
I < *
Size; ++
I) {
1483 if (std::error_code EC = Name.getError())
1489 TableVec.emplace_back(FID);
1497 std::make_unique<MD5SampleProfileNameTable>(std::move(TableVec));
1500 std::make_unique<StringSampleProfileNameTable>(std::move(TableVec));
1505 bool IsMD5,
bool FixedLengthMD5,
bool IsEytzinger) {
1517 bool IsMD5,
bool FixedLengthMD5) {
1518 assert(IsMD5 &&
"Eytzinger name tables require MD5 representation");
1524 for (uint64_t &
Count : Counts) {
1526 if (std::error_code EC = ValOrErr.getError())
1530 auto [NumNested, NumFlat, NumInlinees] = Counts;
1533 if (NumNested > std::numeric_limits<uint32_t>::max() ||
1534 NumFlat > std::numeric_limits<uint32_t>::max() ||
1535 NumInlinees > std::numeric_limits<uint32_t>::max())
1538 uint64_t TotalEntries = NumNested + NumFlat + NumInlinees;
1539 if (
static_cast<size_t>(
End -
Data) < TotalEntries *
sizeof(uint64_t))
1542 NameTable = std::make_unique<EytzingerSampleProfileNameTable>(
1548 Data =
Data + TotalEntries *
sizeof(uint64_t);
1554 bool FixedLengthMD5) {
1555 if (FixedLengthMD5) {
1557 errs() <<
"If FixedLengthMD5 is true, UseMD5 has to be true";
1559 if (std::error_code EC =
Size.getError())
1563 "Fixed length MD5 name table does not contain specified number of "
1571 std::vector<FunctionId> TableVec;
1572 TableVec.reserve(*
Size);
1573 for (
size_t I = 0;
I < *
Size; ++
I) {
1580 std::make_unique<MD5SampleProfileNameTable>(std::move(TableVec));
1584 Data =
Data + (*Size) *
sizeof(uint64_t);
1589 assert(!FixedLengthMD5 &&
"FixedLengthMD5 should be unreachable here");
1591 if (std::error_code EC =
Size.getError())
1594 std::vector<FunctionId> TableVec;
1595 TableVec.reserve(*
Size);
1598 for (
size_t I = 0;
I < *
Size; ++
I) {
1600 if (std::error_code EC = FID.getError())
1609 std::make_unique<MD5SampleProfileNameTable>(std::move(TableVec));
1622 if (std::error_code EC =
Size.getError())
1635 for (
size_t I = 0;
I < *
Size; ++
I) {
1638 if (std::error_code EC = ContextSize.getError())
1640 for (
uint32_t J = 0; J < *ContextSize; ++J) {
1642 if (std::error_code EC = FName.getError())
1645 if (std::error_code EC = LineOffset.getError())
1652 if (std::error_code EC = Discriminator.getError())
1656 FName.get(),
LineLocation(LineOffset.get(), Discriminator.get()));
1668 if (std::error_code EC = Checksum.getError())
1676 if (std::error_code EC = Attributes.getError())
1685 if (std::error_code EC = NumCallsites.getError())
1688 for (
uint32_t J = 0; J < *NumCallsites; ++J) {
1690 if (std::error_code EC = LineOffset.getError())
1694 if (std::error_code EC = Discriminator.getError())
1698 if (std::error_code EC = FContextHash.getError())
1701 auto &[FContext, Hash] = *FContextHash;
1706 *LineOffset, *Discriminator))[FContext.getFunction()]);
1727 Data = R->second.first;
1728 End = R->second.second;
1739 if (std::error_code EC = FContextHash.getError())
1741 auto &[FContext, Hash] = *FContextHash;
1745 FProfile = &It->second;
1762 if (std::error_code EC =
Type.getError())
1764 Entry.Type =
static_cast<SecType>(*Type);
1773 if (std::error_code EC = Flags.getError())
1775 Entry.Flags = *Flags;
1778 if (std::error_code EC =
Offset.getError())
1783 if (std::error_code EC =
Size.getError())
1787 Entry.LayoutIndex = Idx;
1794 if (std::error_code EC = EntryNum.getError())
1797 for (uint64_t i = 0; i < (*EntryNum); i++)
1806 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1808 End = BufStart +
Buffer->getBufferSize();
1822 if (Entry.Type ==
Type)
1834 uint64_t FileSize = 0;
1836 FileSize = std::max(Entry.Offset + Entry.Size, FileSize);
1844 Flags.append(
"{compressed,");
1849 Flags.append(
"flat,");
1851 switch (Entry.Type) {
1854 Flags.append(
"eytzinger,");
1856 Flags.append(
"fixlenmd5,");
1858 Flags.append(
"md5,");
1860 Flags.append(
"uniq,");
1864 Flags.append(
"partial,");
1866 Flags.append(
"context,");
1868 Flags.append(
"preInlined,");
1870 Flags.append(
"fs-discriminator,");
1875 Flags.append(
"ordered,");
1877 Flags.append(
"eytzinger,");
1881 Flags.append(
"probe,");
1883 Flags.append(
"attr,");
1887 Flags.append(
"md5,");
1892 char &last = Flags.back();
1901 uint64_t TotalSecsSize = 0;
1903 OS <<
getSecName(Entry.Type) <<
" - Offset: " << Entry.Offset
1904 <<
", Size: " << Entry.Size <<
", Flags: " <<
getSecFlagsStr(Entry)
1907 TotalSecsSize += Entry.Size;
1911 "Size of 'header + sections' doesn't match the total size of profile");
1913 OS <<
"Header Size: " << HeaderSize <<
"\n";
1914 OS <<
"Total Sections Size: " << TotalSecsSize <<
"\n";
1922 if (std::error_code EC = Magic.getError())
1924 else if (std::error_code EC = verifySPMagic(*Magic))
1929 if (std::error_code EC =
Version.getError())
1953std::error_code SampleProfileReaderBinary::readSummaryEntry(
1954 std::vector<ProfileSummaryEntry> &Entries) {
1956 if (std::error_code EC = Cutoff.getError())
1960 if (std::error_code EC = MinBlockCount.getError())
1964 if (std::error_code EC = NumBlocks.getError())
1967 Entries.emplace_back(*Cutoff, *MinBlockCount, *NumBlocks);
1973 if (std::error_code EC = TotalCount.getError())
1977 if (std::error_code EC = MaxBlockCount.getError())
1981 if (std::error_code EC = MaxFunctionCount.getError())
1985 if (std::error_code EC = NumBlocks.getError())
1989 if (std::error_code EC = NumFunctions.getError())
1993 if (std::error_code EC = NumSummaryEntries.getError())
1996 std::vector<ProfileSummaryEntry> Entries;
1997 for (
unsigned i = 0; i < *NumSummaryEntries; i++) {
1998 std::error_code EC = readSummaryEntry(Entries);
2002 Summary = std::make_unique<ProfileSummary>(
2004 *MaxFunctionCount, *NumBlocks, *NumFunctions);
2038 if (
GcovBuffer.readInt(Val) && Val <= std::numeric_limits<T>::max())
2039 return static_cast<T>(Val);
2040 }
else if (
sizeof(
T) <=
sizeof(uint64_t)) {
2042 if (
GcovBuffer.readInt64(Val) && Val <= std::numeric_limits<T>::max())
2043 return static_cast<T>(Val);
2105 Names.push_back(std::string(Str));
2130 uint64_t HeadCount = 0;
2131 if (InlineStack.
size() == 0)
2150 if (InlineStack.
size() == 0) {
2199 for (
auto *CallerProfile : NewStack)
2200 CallerProfile->addTotalSamples(
Count);
2209 for (
uint32_t J = 0; J < NumTargets; J++) {
2222 uint64_t TargetCount;
2272 (Contents.
size() == 8 || Contents[8] ==
'\0');
2278 if (Reader.useMD5()) {
2280 Reader.getBuffer()->getBufferIdentifier(),
2281 "Profile data remapping cannot be applied to profile data "
2282 "using MD5 names (original mangled names are not available).",
2289 assert(Remappings &&
"should be initialized while creating remapper");
2290 for (
auto &Sample : Reader.getProfiles()) {
2292 Sample.second.findAllNames(NamesInSample);
2293 for (
auto &Name : NamesInSample) {
2295 if (
auto Key = Remappings->insert(NameStr))
2296 NameMap.insert({
Key, NameStr});
2300 RemappingApplied =
true;
2303std::optional<StringRef>
2305 if (
auto Key = Remappings->lookup(Fname)) {
2307 if (!Result.empty())
2310 return std::nullopt;
2320 if (std::error_code EC = BufferOrErr.getError())
2322 auto Buffer = std::move(BufferOrErr.get());
2324 return std::move(Buffer);
2338ErrorOr<std::unique_ptr<SampleProfileReader>>
2343 if (std::error_code EC = BufferOrError.getError())
2345 return create(BufferOrError.get(),
C, FS,
P, RemapFilename);
2364 if (std::error_code EC = BufferOrError.getError())
2366 return create(BufferOrError.get(), Reader,
C);
2383 auto Remappings = std::make_unique<SymbolRemappingReader>();
2384 if (
Error E = Remappings->read(*
B)) {
2388 ParseError.getLineNum(),
2389 ParseError.getMessage()));
2394 return std::make_unique<SampleProfileReaderItaniumRemapper>(
2395 std::move(
B), std::move(Remappings), Reader);
2413 std::unique_ptr<SampleProfileReader> Reader;
2425 if (!RemapFilename.
empty()) {
2427 RemapFilename, FS, *Reader,
C);
2428 if (std::error_code EC = ReaderOrErr.getError()) {
2429 std::string
Msg =
"Could not create remapper: " + EC.message();
2433 Reader->Remapper = std::move(ReaderOrErr.get());
2436 if (std::error_code EC = Reader->readHeader()) {
2440 Reader->setDiscriminatorMaskedBitFrom(
P);
2442 return std::move(Reader);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
Provides ErrorOr<T> smart pointer.
Module.h This file contains the declarations for the Module class.
This file supports working with JSON data.
static constexpr StringLiteral Filename
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, DenseMap< StringRef, uint64_t > &TypeCountMap, uint64_t &FunctionHash, uint32_t &Attributes, bool &IsFlat)
Parse Input as line sample.
static cl::opt< bool > LazyLoadNameTable("sample-profile-lazy-load-name-table", cl::init(true), cl::Hidden, cl::desc("Lazy load the name table from the profile."))
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 std::error_code diagnoseReaderError(const SampleProfileReader &Reader, sampleprof_error ProfError)
Emit a reader diagnostic for ProfError and return its error code.
static bool hasBinaryFormat(const MemoryBuffer &Buffer, uint64_t ExpectedMagic)
Return whether Buffer starts with ExpectedMagic without reading beyond it.
static bool parseTypeCountMap(StringRef Input, DenseMap< StringRef, uint64_t > &TypeCountMap)
static bool parseMetadata(const StringRef &Input, uint64_t &FunctionHash, uint32_t &Attributes)
Parse Input that contains metadata.
This file provides utility classes that use RAII to save and restore values.
This file defines the SmallSet class.
Defines the virtual file system interface vfs::FileSystem.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
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.
Non-owning view of a buffer formatted as a complete binary search tree in Eytzinger (breadth-first) o...
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
This is an important class for using LLVM in a threaded context.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
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.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
static constexpr size_t npos
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
constexpr size_t size() const
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.
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 find(char C, size_t From=0) const
Search for the first character C in the string.
LLVM_ABI 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.
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).
LLVM_ABI void arrayBegin()
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.
This class represents a function that is read from a sample profile.
StringRef stringRef() const
Convert to StringRef.
uint64_t getHashCode() const
Get hash code of this object.
std::string str() const
Convert to a string, usually for output purpose.
Representation of the samples collected for a function.
static LLVM_ABI std::atomic< bool > ProfileIsFS
If this profile uses flow sensitive discriminators.
static LLVM_ABI std::atomic< bool > ProfileIsPreInlined
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...
void setFunction(FunctionId NewFunctionID)
Set the name of the function.
const CallsiteSampleMap & getCallsiteSamples() const LLVM_LIFETIME_BOUND
Return all the callsite samples collected in the body of the function.
FunctionId getFunction() const
Return the function name.
SampleContext & getContext() const LLVM_LIFETIME_BOUND
FunctionSamplesMap & functionSamplesAt(const LineLocation &Loc) LLVM_LIFETIME_BOUND
Return the function samples at the given callsite location.
sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight=1)
void reserveBodySamples(size_t NumEntries)
TypeCountMap & getTypeSamplesAt(const LineLocation &Loc) LLVM_LIFETIME_BOUND
Returns the vtable access samples for the C++ types for Loc.
sampleprof_error addCalledTargetSamples(uint32_t LineOffset, uint32_t Discriminator, FunctionId Func, uint64_t Num, uint64_t Weight=1)
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)
static LLVM_ABI std::atomic< bool > HasUniqSuffix
Whether the profile contains any ".__uniq." suffix in a name.
void setFunctionHash(uint64_t Hash)
static LLVM_ABI std::atomic< bool > ProfileIsProbeBased
const BodySampleMap & getBodySamples() const LLVM_LIFETIME_BOUND
Return all the samples collected in the body of the function.
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
void setContext(const SampleContext &FContext)
static LLVM_ABI std::atomic< bool > ProfileIsCS
void reserveCallsiteTypeCounts(size_t NumEntries)
void setAllAttributes(uint32_t A)
FunctionId getFunction() const
std::string toString() const
bool isPrefixOf(const SampleContext &That) const
This class provides operator overloads to the map container using MD5 as the key type,...
iterator find(const SampleContext &Ctx)
std::error_code readNameTable()
Read the whole name table.
const uint8_t * Data
Points to the current location in the buffer.
std::error_code readCompositeProfile(FunctionSamples &FProfile, bool IsNested)
std::error_code readLBRProfile(FunctionSamples &FProfile, bool IsNested)
Read specific profile types.
ErrorOr< StringRef > readString()
Read a string from the profile.
std::unique_ptr< SampleProfileNameTable > NameTable
Function name table.
ErrorOr< T > readNumber()
Read a numeric value of type T from the profile.
ErrorOr< SampleContextFrames > readContextFromTable(size_t *RetIdx=nullptr)
Read a context indirectly via the CSNameTable.
ErrorOr< std::pair< SampleContext, uint64_t > > readSampleContextFromTable()
Read a context indirectly via the CSNameTable if the profile has context, otherwise same as readStrin...
std::error_code readHeader() override
Read and validate the file header.
const uint64_t * MD5SampleContextStart
The starting address of the table of MD5 values of sample contexts.
std::vector< SampleContextFrameVector > CSNameTable
CSNameTable is used to save full context vectors.
std::error_code readImpl() override
Read sample profiles from the associated file.
ErrorOr< FunctionId > readStringFromTable(size_t *RetIdx=nullptr)
Read a string indirectly via the name table. Optionally return the index.
std::vector< uint64_t > MD5SampleContextTable
Table to cache MD5 values of sample contexts corresponding to readSampleContextFromTable(),...
std::error_code readCallsiteVTableProf(FunctionSamples &FProfile)
Read all virtual functions' vtable access counts for FProfile.
ErrorOr< size_t > readStringIndex(T &Table)
Read the string index and check whether it overflows the table.
const uint8_t * End
Points to the end of the buffer.
std::error_code readProfile(FunctionSamples &FProfile, bool IsNested)
Read the contents of the given profile instance.
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 readVTableTypeCountMap(TypeCountMap &M)
Read bytes from the input buffer pointed by Data and decode them into M.
std::error_code readSummary()
Read profile summary.
std::error_code readMagicIdent()
Read the contents of Magic number and Version number.
std::vector< SecHdrTableEntry > SecHdrTable
std::error_code readNameTableSecEytzinger(bool IsMD5, bool FixedLengthMD5)
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()
std::error_code readEytzingerFuncOffsetTable(bool IsNested)
virtual std::error_code readCustomSection(const SecHdrTableEntry &Entry)=0
std::vector< std::pair< SampleContext, uint64_t > > FuncOffsetList
The list version of FuncOffsetTable.
std::error_code readFuncMetadata()
DenseSet< StringRef > FuncsToUse
The set containing the functions to use when compiling a module.
std::unique_ptr< ProfileSymbolList > ProfSymList
std::optional< SampleProfileFuncOffsetTable > FuncOffsetTable
The table mapping from a function context's MD5 to the offset of its FunctionSample towards file star...
std::error_code readNameTableSec(bool IsMD5, bool FixedLengthMD5, bool IsEytzinger=false)
std::error_code readSecHdrTable()
std::error_code readFuncProfiles()
bool useFuncOffsetList() const
Determine which container readFuncOffsetTable() should populate, the list FuncOffsetList or the map F...
std::error_code readSecHdrTableEntry(uint64_t Idx)
std::error_code readImpl() override
Read sample profiles in extensible format from the associated file.
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 readFuncOffsetTable(bool IsEytzinger, bool IsNested)
std::error_code readNameTableSecLegacy(bool IsMD5, bool FixedLengthMD5)
std::error_code readStringBasedProfileSymbolList()
std::error_code readLegacyFuncOffsetTable()
std::error_code readHeader() override
Read and validate the file header.
uint64_t getFileSize()
Get the total size of header and all sections.
std::error_code readProfileSymbolList(bool IsMD5)
std::error_code readMD5ProfileSymbolList()
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 LLVM_ABI ErrorOr< std::unique_ptr< SampleProfileReaderItaniumRemapper > > create(StringRef Filename, vfs::FileSystem &FS, SampleProfileReader &Reader, LLVMContext &C)
Create a remapper from the given remapping file.
LLVM_ABI void applyRemapping(LLVMContext &Ctx)
Apply remappings to the profile read by Reader.
LLVM_ABI 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.
bool ReadVTableProf
If true, the profile has vtable profiles and reader should decode them to parse profiles correctly.
bool ProfileIsPreInlined
Whether function profile contains ShouldBeInlined contexts.
DenseMap< uint64_t, std::pair< const uint8_t *, const uint8_t * > > FuncMetadataIndex
uint32_t CSProfileCount
Number of context-sensitive profiles.
static LLVM_ABI ErrorOr< std::unique_ptr< SampleProfileReader > > create(StringRef Filename, LLVMContext &C, vfs::FileSystem &FS, FSDiscriminatorPass P=FSDiscriminatorPass::Base, StringRef RemapFilename="")
Create a sample profile reader appropriate to the file format.
LLVM_ABI void dump(raw_ostream &OS=dbgs())
Print all the profiles on stream OS.
bool useMD5() const
Return whether names in the profile are all MD5 numbers.
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
bool ProfileHasAttribute
Whether the profile has attribute metadata.
bool SkipFlatProf
If SkipFlatProf is true, skip functions marked with !Flat in text mode or sections with SecFlagFlat f...
std::error_code read()
The interface to read sample profiles from the associated file.
ProfileSectionRange ProfileSecRange
Profile section most recently selected for on-demand loading.
bool ProfileIsCS
Whether function profiles are context-sensitive flat profiles.
bool ProfileIsMD5
Whether the profile uses MD5 for Sample Contexts and function names.
std::unique_ptr< ProfileSummary > Summary
Profile summary information.
LLVM_ABI 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 HasUnknownProfileTypes
Whether reading skipped at least one unknown composite profile block.
bool ProfileIsFS
Whether the function profiles use FS discriminators.
LLVM_ABI void dumpJson(raw_ostream &OS=dbgs())
Print all the profiles on stream OS in the JSON format.
SampleProfileMap Profiles
Map every function to its associated profile.
uint64_t FormatVersion
Format version of the profile.
LLVM_ABI void dumpFunctionProfile(const FunctionSamples &FS, raw_ostream &OS=dbgs())
Print the profile for FunctionSamples on stream OS.
bool ProfileIsProbeBased
Whether samples are collected based on pseudo probes.
void reportError(int64_t LineNumber, const Twine &Msg) const
Report a parse error message.
raw_ostream * ProfileTypeInfoOS
Optional stream for composite block structure; null disables the output.
LLVMContext & Ctx
LLVM context used to emit diagnostics.
Representation of a single sample record.
The virtual file system interface.
initializer< Ty > init(const Ty &Val)
LLVM_ABI Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)
LLVM_ABI bool isAvailable()
LLVM_ABI void sortFuncProfiles(const SampleProfileMap &ProfileMap, std::vector< NameFunctionSamples > &SortedProfiles)
static uint64_t SPMagic(SampleProfileFormat Format=SPF_Binary)
static bool formatVersionIsSupported(uint64_t Version)
std::map< LineLocation, FunctionSamplesMap > CallsiteSampleMap
static bool hasSecFlag(const SecHdrTableEntry &Entry, SecFlagType Flag)
SortedVectorMap< LineLocation, SampleRecord, 0 > BodySampleMap
@ HIST_TYPE_INDIR_CALL_TOPN
uint64_t MD5Hash(const FunctionId &Obj)
constexpr EytzingerModeT EytzingerMode
@ SecFlagIsPreInlined
SecFlagIsPreInlined means this profile contains ShouldBeInlined contexts thus this is CS preinliner c...
@ SecFlagHasVTableTypeProf
SecFlagHasVTableTypeProf means this profile contains vtable type profiles.
@ 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.
static StringRef getProfTypeName(uint64_t Type)
SmallVector< SampleContextFrame, 1 > SampleContextFrameVector
static std::string getSecName(SecType Type)
constexpr InMemoryModeT InMemoryMode
static constexpr uint64_t CompositeProfileVersion
constexpr char kVTableProfPrefix[]
SmallVector< FunctionSamples *, 10 > InlineCallStack
SortedVectorMap< FunctionId, uint64_t, 0 > TypeCountMap
Key represents type of a C++ polymorphic class type by its vtable and value represents its counter.
@ SecCompositeFuncOffsetTable
uint64_t read64le(const void *P)
void write64le(void *P, uint64_t V)
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.
detail::packed_endian_specific_integral< uint64_t, llvm::endianness::little, unaligned > ulittle64_t
detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t
This is an optimization pass for GlobalISel generic memory operations.
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
ULEB128DecodeError
Identifies why ULEB128 decoding failed.
@ UnexpectedEnd
The encoding requires bytes beyond the supplied buffer.
@ None
No decoding error has been reported.
@ TooBig
The encoded value does not fit in uint64_t.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
sampleprof_error mergeSampleProfErrors(sampleprof_error &Accumulator, sampleprof_error Result)
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
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...
ArrayRef(const T &OneElt) -> ArrayRef< T >
@ End
Run the machine verifier once, at the end of the pipeline.
std::enable_if_t< std::is_unsigned_v< T >, T > SaturatingAdd(T X, T Y, bool *ResultOverflowed=nullptr)
Add two unsigned integers, X and Y, of type T.
uint64_t decodeULEB128(const uint8_t *p, unsigned *n, const uint8_t *end, const char **error, ULEB128DecodeError *errorCode)
Utility function to decode a ULEB128 value and report a typed error.
A utility class that uses RAII to save and restore the value of a variable.
Represents the relative location of an instruction.
const uint8_t * Start
First byte of the retained section.
const uint8_t * End
One-past-the-end byte of the retained section.