45#include <system_error>
51#define DEBUG_TYPE "samplepgo-reader"
58 cl::desc(
"Profile uses flow sensitive discriminators"));
63 cl::desc(
"Lazy load the name table from the profile."));
71 OS <<
"Function: " << FS.getContext().toString() <<
": " << FS;
76 std::vector<NameFunctionSamples> V;
78 for (
const auto &
I : V)
85 for (
const auto &
I : BodySamples) {
90 if (
Loc.Discriminator)
95 if (!CallTargets.empty()) {
97 for (
const auto &J : CallTargets) {
110 for (
const auto &
I : CallsiteSamples)
111 for (
const auto &FS :
I.second) {
116 if (
Loc.Discriminator)
131 if (!BodySamples.empty())
135 if (!CallsiteSamples.empty())
137 [&] { DumpCallsiteSamples(CallsiteSamples); });
143 std::vector<NameFunctionSamples> V;
147 for (
const auto &
F : V)
166 size_t n2 =
Input.rfind(
':');
167 size_t n1 =
Input.rfind(
':', n2 - 1);
168 FName =
Input.substr(0, n1);
169 if (
Input.substr(n1 + 1, n2 - n1 - 1).getAsInteger(10, NumSamples))
171 if (
Input.substr(n2 + 1).getAsInteger(10, NumHeadSamples))
188 if (
Input.starts_with(
"!CFGChecksum:")) {
193 if (
Input.starts_with(
"!Attributes:")) {
213 size_t ColonIndex =
Input.find(
':', Index);
218 size_t CountStartIndex = ColonIndex + 1;
220 size_t NextIndex =
Input.find_first_of(
' ', CountStartIndex);
222 if (
Input.substr(CountStartIndex, NextIndex - CountStartIndex)
223 .getAsInteger(10,
Count))
231 :
Input.find_first_not_of(
' ', NextIndex);
272 size_t n1 =
Input.find(
':');
274 size_t n2 =
Loc.find(
'.');
280 if (
Loc.substr(0, n2).getAsInteger(10, LineOffset))
282 if (
Loc.substr(n2 + 1).getAsInteger(10, Discriminator))
289 size_t n3 = Rest.
find(
' ');
339 if (n4 == Rest.
size())
351 CalleeName = Rest.
substr(0, n3);
369 uint32_t TopLevelProbeProfileCount = 0;
375 std::vector<SampleContext *> FlatSamples;
381 if (pos == LineIt->
npos || (*LineIt)[pos] ==
'#')
395 if ((*LineIt)[0] !=
' ') {
396 uint64_t NumSamples, NumHeadSamples;
398 if (!
ParseHead(*LineIt, FName, NumSamples, NumHeadSamples)) {
400 "Expected 'mangled_name:NUM:NUM', found " + *LineIt);
426 FunctionHash, Attributes, IsFlat)) {
430 "Cannot parse metadata: " + *LineIt);
434 "Expected 'vtables [mangled_vtable:NUM]+', found " +
439 "Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " +
447 "Found non-metadata after metadata: " + *LineIt);
470 Result, InlineStack.
back()->addCallsiteVTableTypeProfAt(
477 for (
const auto &name_count : TargetCountMap) {
479 LineOffset, Discriminator,
493 ++TopLevelProbeProfileCount;
498 DepthMetadata =
Depth;
501 FlatSamples.push_back(&FProfile.
getContext());
505 "!Flat may only be used at top level function.",
DS_Warning));
520 "Cannot have both context-sensitive and regular profile");
522 assert((TopLevelProbeProfileCount == 0 ||
523 TopLevelProbeProfileCount ==
Profiles.size()) &&
524 "Cannot have both probe-based profiles and regular profiles");
542 if ((*LineIt)[0] !=
' ') {
543 uint64_t NumSamples, NumHeadSamples;
545 result =
ParseHead(*LineIt, FName, NumSamples, NumHeadSamples);
553 unsigned NumBytesRead = 0;
556 if (Val > std::numeric_limits<T>::max()) {
560 }
else if (
Data + NumBytesRead >
End) {
566 Data += NumBytesRead;
567 return static_cast<T>(Val);
572 if (
Data + Str.size() + 1 >
End) {
578 Data += Str.size() + 1;
598 if (std::error_code EC = Idx.getError())
600 if (*Idx >=
Table.size())
610 if (std::error_code EC = Idx.getError())
620 if (std::error_code EC = ContextIdx.getError())
625 *RetIdx = *ContextIdx;
635 if (std::error_code EC = FContext.getError())
640 if (std::error_code EC = FName.getError())
652 Hash = Context.getHashCode();
655 return std::make_pair(Context, Hash);
661 if (std::error_code EC = NumVTableTypes.getError())
666 if (std::error_code EC = VTableType.getError())
670 if (std::error_code EC = VTableSamples.getError())
675 if (!
M.insert(std::make_pair(*VTableType, *VTableSamples)).second) {
677 Buffer->getBufferIdentifier(), 0,
678 "Duplicate vtable type " + VTableType->str() +
679 " at the same location. Additional counters will be ignored.",
690 "Cannot read vtable profiles if ReadVTableProf is false");
694 if (std::error_code EC = NumCallsites.getError())
699 if (std::error_code EC = LineOffset.getError())
706 if (std::error_code EC = Discriminator.getError())
722 if (std::error_code EC = NumSamples.getError())
728 if (std::error_code EC = NumRecords.getError())
733 if (std::error_code EC = LineOffset.getError())
741 if (std::error_code EC = Discriminator.getError())
745 if (std::error_code EC = NumSamples.getError())
749 if (std::error_code EC = NumCalls.getError())
755 for (
uint32_t J = 0; J < *NumCalls; ++J) {
757 if (std::error_code EC = CalledFunction.getError())
761 if (std::error_code EC = CalledFunctionSamples.getError())
765 *CalledFunction, *CalledFunctionSamples);
768 FProfile.
addBodySamples(*LineOffset, DiscriminatorVal, *NumSamples);
773 if (std::error_code EC = NumCallsites.getError())
776 for (
uint32_t J = 0; J < *NumCallsites; ++J) {
778 if (std::error_code EC = LineOffset.getError())
782 if (std::error_code EC = Discriminator.getError())
786 if (std::error_code EC = FName.getError())
795 if (std::error_code EC =
readProfile(CalleeProfile))
810 if (std::error_code EC = NumHeadSamples.getError())
814 if (std::error_code EC = FContextHash.getError())
817 auto &[FContext, Hash] = *FContextHash;
824 if (FContext.hasContext())
852 switch (Entry.Type) {
857 Summary->setPartialProfile(
true);
868 bool FixedLengthMD5 =
877 if (std::error_code EC =
900 "func offset table should always be sorted in CS profile");
971 ProfilesToReadMetadata.
insert(&
I->second);
995 if (std::error_code EC =
Size.getError())
999 if (UseFuncOffsetList)
1006 if (std::error_code EC = FContextHash.getError())
1009 auto &[FContext, Hash] = *FContextHash;
1011 if (std::error_code EC =
Offset.getError())
1014 if (UseFuncOffsetList)
1052 const auto &FContext = NameOffset.first;
1064 if (!CommonContext || !CommonContext->
isPrefixOf(FContext))
1065 CommonContext = &FContext;
1068 if (CommonContext == &FContext ||
1069 (CommonContext && CommonContext->
isPrefixOf(FContext))) {
1072 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
1092 StringRef FuncNameStr = FuncName.stringRef();
1095 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
1124 if (!LoadFuncsToBeUsed) {
1137 "Cannot have both context-sensitive and regular profile");
1139 "Section flag should be consistent with actual profile");
1157 ProfSymList = std::make_unique<ProfileSymbolList>();
1167 ProfSymList = std::make_unique<ProfileSymbolList>();
1176std::error_code SampleProfileReaderExtBinaryBase::decompressSection(
1180 End = SecStart + SecSize;
1182 if (std::error_code EC = DecompressSize.getError())
1184 DecompressBufSize = *DecompressSize;
1187 if (std::error_code EC = CompressSize.getError())
1194 size_t UCSize = DecompressBufSize;
1205 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1216 const uint8_t *SecStart = BufStart + Entry.Offset;
1227 if (std::error_code EC = decompressSection(
1228 SecStart, SecSize, DecompressBuf, DecompressBufSize))
1230 SecStart = DecompressBuf;
1231 SecSize = DecompressBufSize;
1234 if (std::error_code EC =
readOneSection(SecStart, SecSize, Entry))
1236 if (
Data != SecStart + SecSize)
1241 Data = BufStart + Entry.Offset;
1242 End = BufStart +
Buffer->getBufferSize();
1249std::error_code SampleProfileReaderRawBinary::verifySPMagic(
uint64_t Magic) {
1255std::error_code SampleProfileReaderExtBinary::verifySPMagic(
uint64_t Magic) {
1263 if (std::error_code EC =
Size.getError())
1272 std::vector<FunctionId> TableVec;
1273 TableVec.reserve(*
Size);
1284 for (
size_t I = 0;
I < *
Size; ++
I) {
1286 if (std::error_code EC = Name.getError())
1292 TableVec.emplace_back(FID);
1300 std::make_unique<MD5SampleProfileNameTable>(std::move(TableVec));
1303 std::make_unique<StringSampleProfileNameTable>(std::move(TableVec));
1308 bool IsMD5,
bool FixedLengthMD5,
bool IsEytzinger) {
1320 bool IsMD5,
bool FixedLengthMD5) {
1321 assert(IsMD5 &&
"Eytzinger name tables require MD5 representation");
1329 if (std::error_code EC = ValOrErr.getError())
1333 auto [NumCS, NumFlat, NumInlinees] = Counts;
1336 if (NumCS > std::numeric_limits<uint32_t>::max() ||
1337 NumFlat > std::numeric_limits<uint32_t>::max() ||
1338 NumInlinees > std::numeric_limits<uint32_t>::max())
1341 uint64_t TotalEntries = NumCS + NumFlat + NumInlinees;
1342 if (
static_cast<size_t>(
End -
Data) < TotalEntries *
sizeof(
uint64_t))
1345 NameTable = std::make_unique<EytzingerSampleProfileNameTable>(
1357 bool FixedLengthMD5) {
1358 if (FixedLengthMD5) {
1360 errs() <<
"If FixedLengthMD5 is true, UseMD5 has to be true";
1362 if (std::error_code EC =
Size.getError())
1366 "Fixed length MD5 name table does not contain specified number of "
1374 std::vector<FunctionId> TableVec;
1375 TableVec.reserve(*
Size);
1376 for (
size_t I = 0;
I < *
Size; ++
I) {
1383 std::make_unique<MD5SampleProfileNameTable>(std::move(TableVec));
1392 assert(!FixedLengthMD5 &&
"FixedLengthMD5 should be unreachable here");
1394 if (std::error_code EC =
Size.getError())
1397 std::vector<FunctionId> TableVec;
1398 TableVec.reserve(*
Size);
1401 for (
size_t I = 0;
I < *
Size; ++
I) {
1403 if (std::error_code EC = FID.getError())
1412 std::make_unique<MD5SampleProfileNameTable>(std::move(TableVec));
1425 if (std::error_code EC =
Size.getError())
1438 for (
size_t I = 0;
I < *
Size; ++
I) {
1441 if (std::error_code EC = ContextSize.getError())
1443 for (
uint32_t J = 0; J < *ContextSize; ++J) {
1445 if (std::error_code EC = FName.getError())
1448 if (std::error_code EC = LineOffset.getError())
1455 if (std::error_code EC = Discriminator.getError())
1459 FName.get(),
LineLocation(LineOffset.get(), Discriminator.get()));
1471 if (std::error_code EC = Checksum.getError())
1479 if (std::error_code EC = Attributes.getError())
1488 if (std::error_code EC = NumCallsites.getError())
1491 for (
uint32_t J = 0; J < *NumCallsites; ++J) {
1493 if (std::error_code EC = LineOffset.getError())
1497 if (std::error_code EC = Discriminator.getError())
1501 if (std::error_code EC = FContextHash.getError())
1504 auto &[FContext, Hash] = *FContextHash;
1509 *LineOffset, *Discriminator))[FContext.getFunction()]);
1530 Data = R->second.first;
1531 End = R->second.second;
1542 if (std::error_code EC = FContextHash.getError())
1544 auto &[FContext, Hash] = *FContextHash;
1548 FProfile = &It->second;
1565 if (std::error_code EC =
Type.getError())
1567 Entry.Type =
static_cast<SecType>(*Type);
1570 if (std::error_code EC = Flags.getError())
1572 Entry.Flags = *Flags;
1575 if (std::error_code EC =
Offset.getError())
1580 if (std::error_code EC =
Size.getError())
1584 Entry.LayoutIndex = Idx;
1591 if (std::error_code EC = EntryNum.getError())
1594 for (
uint64_t i = 0; i < (*EntryNum); i++)
1603 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1605 End = BufStart +
Buffer->getBufferSize();
1619 if (Entry.Type ==
Type)
1633 FileSize = std::max(Entry.Offset + Entry.Size, FileSize);
1641 Flags.append(
"{compressed,");
1646 Flags.append(
"flat,");
1648 switch (Entry.Type) {
1651 Flags.append(
"eytzinger,");
1653 Flags.append(
"fixlenmd5,");
1655 Flags.append(
"md5,");
1657 Flags.append(
"uniq,");
1661 Flags.append(
"partial,");
1663 Flags.append(
"context,");
1665 Flags.append(
"preInlined,");
1667 Flags.append(
"fs-discriminator,");
1671 Flags.append(
"ordered,");
1675 Flags.append(
"probe,");
1677 Flags.append(
"attr,");
1681 Flags.append(
"md5,");
1686 char &last = Flags.back();
1697 OS <<
getSecName(Entry.Type) <<
" - Offset: " << Entry.Offset
1698 <<
", Size: " << Entry.Size <<
", Flags: " <<
getSecFlagsStr(Entry)
1701 TotalSecsSize += Entry.Size;
1705 "Size of 'header + sections' doesn't match the total size of profile");
1707 OS <<
"Header Size: " << HeaderSize <<
"\n";
1708 OS <<
"Total Sections Size: " << TotalSecsSize <<
"\n";
1716 if (std::error_code EC = Magic.getError())
1718 else if (std::error_code EC = verifySPMagic(*Magic))
1723 if (std::error_code EC =
Version.getError())
1747std::error_code SampleProfileReaderBinary::readSummaryEntry(
1748 std::vector<ProfileSummaryEntry> &Entries) {
1750 if (std::error_code EC = Cutoff.getError())
1754 if (std::error_code EC = MinBlockCount.getError())
1758 if (std::error_code EC = NumBlocks.getError())
1761 Entries.emplace_back(*Cutoff, *MinBlockCount, *NumBlocks);
1767 if (std::error_code EC = TotalCount.getError())
1771 if (std::error_code EC = MaxBlockCount.getError())
1775 if (std::error_code EC = MaxFunctionCount.getError())
1779 if (std::error_code EC = NumBlocks.getError())
1783 if (std::error_code EC = NumFunctions.getError())
1787 if (std::error_code EC = NumSummaryEntries.getError())
1790 std::vector<ProfileSummaryEntry> Entries;
1791 for (
unsigned i = 0; i < *NumSummaryEntries; i++) {
1792 std::error_code EC = readSummaryEntry(Entries);
1796 Summary = std::make_unique<ProfileSummary>(
1798 *MaxFunctionCount, *NumBlocks, *NumFunctions);
1827 if (
GcovBuffer.readInt(Val) && Val <= std::numeric_limits<T>::max())
1828 return static_cast<T>(Val);
1829 }
else if (
sizeof(
T) <=
sizeof(
uint64_t)) {
1831 if (
GcovBuffer.readInt64(Val) && Val <= std::numeric_limits<T>::max())
1832 return static_cast<T>(Val);
1894 Names.push_back(std::string(Str));
1920 if (InlineStack.
size() == 0)
1939 if (InlineStack.
size() == 0) {
1987 for (
auto *CallerProfile : NewStack)
1988 CallerProfile->addTotalSamples(
Count);
1997 for (
uint32_t J = 0; J < NumTargets; J++) {
2058 return Magic ==
"adcg*704";
2064 if (Reader.useMD5()) {
2066 Reader.getBuffer()->getBufferIdentifier(),
2067 "Profile data remapping cannot be applied to profile data "
2068 "using MD5 names (original mangled names are not available).",
2075 assert(Remappings &&
"should be initialized while creating remapper");
2076 for (
auto &Sample : Reader.getProfiles()) {
2078 Sample.second.findAllNames(NamesInSample);
2079 for (
auto &Name : NamesInSample) {
2081 if (
auto Key = Remappings->insert(NameStr))
2082 NameMap.insert({
Key, NameStr});
2086 RemappingApplied =
true;
2089std::optional<StringRef>
2091 if (
auto Key = Remappings->lookup(Fname)) {
2093 if (!Result.empty())
2096 return std::nullopt;
2106 if (std::error_code EC = BufferOrErr.getError())
2108 auto Buffer = std::move(BufferOrErr.get());
2110 return std::move(Buffer);
2124ErrorOr<std::unique_ptr<SampleProfileReader>>
2129 if (std::error_code EC = BufferOrError.getError())
2131 return create(BufferOrError.get(),
C, FS,
P, RemapFilename);
2150 if (std::error_code EC = BufferOrError.getError())
2152 return create(BufferOrError.get(), Reader,
C);
2169 auto Remappings = std::make_unique<SymbolRemappingReader>();
2170 if (
Error E = Remappings->read(*
B)) {
2174 ParseError.getLineNum(),
2175 ParseError.getMessage()));
2180 return std::make_unique<SampleProfileReaderItaniumRemapper>(
2181 std::move(
B), std::move(Remappings), Reader);
2199 std::unique_ptr<SampleProfileReader> Reader;
2211 if (!RemapFilename.
empty()) {
2213 RemapFilename, FS, *Reader,
C);
2214 if (std::error_code EC = ReaderOrErr.getError()) {
2215 std::string
Msg =
"Could not create remapper: " + EC.message();
2219 Reader->Remapper = std::move(ReaderOrErr.get());
2222 if (std::error_code EC = Reader->readHeader()) {
2226 Reader->setDiscriminatorMaskedBitFrom(
P);
2228 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 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.
Defines the virtual file system interface vfs::FileSystem.
Implements a dense probed hash-table based set.
Diagnostic information for the sample profiler.
Represents either an error or a value T.
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...
static ErrorOr< std::unique_ptr< MemoryBuffer > > getSTDIN()
Read all of stdin into a file buffer, and return it.
static LLVM_ABI const ArrayRef< uint32_t > DefaultCutoffs
A vector of useful cutoff values for detailed summary.
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.
FunctionId getFunction() const
Return the function name.
sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight=1)
sampleprof_error addCalledTargetSamples(uint32_t LineOffset, uint32_t Discriminator, FunctionId Func, uint64_t Num, uint64_t Weight=1)
FunctionSamplesMap & functionSamplesAt(const LineLocation &Loc)
Return the function samples at the given callsite location.
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
SampleContext & getContext() const
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)
static LLVM_ABI std::atomic< bool > ProfileIsCS
TypeCountMap & getTypeSamplesAt(const LineLocation &Loc)
Returns the vtable access samples for the C++ types for Loc.
const BodySampleMap & getBodySamples() const
Return all the samples collected in the body of the function.
void setAllAttributes(uint32_t A)
FunctionId getFunction() 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 readProfile(FunctionSamples &FProfile)
Read the contents of the given profile instance.
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::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.
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::error_code readFuncOffsetTable()
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()
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 readNameTableSecLegacy(bool IsMD5, bool FixedLengthMD5)
std::error_code readStringBasedProfileSymbolList()
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.
std::pair< const uint8_t *, const uint8_t * > ProfileSecRange
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.
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 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.
LLVMContext & Ctx
LLVM context used to emit diagnostics.
Representation of a single sample record.
SortedCallTargetSet getSortedCallTargets() const
uint64_t getSamples() const
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)
@ HIST_TYPE_INDIR_CALL_TOPN
uint64_t MD5Hash(const FunctionId &Obj)
@ 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.
SmallVector< SampleContextFrame, 1 > SampleContextFrameVector
std::map< FunctionId, uint64_t > TypeCountMap
Key represents type of a C++ polymorphic class type by its vtable and value represents its counter.
static std::string getSecName(SecType Type)
constexpr InMemoryModeT InMemoryMode
constexpr char kVTableProfPrefix[]
SmallVector< FunctionSamples *, 10 > InlineCallStack
std::map< LineLocation, SampleRecord > BodySampleMap
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
This is an optimization pass for GlobalISel generic memory operations.
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS)
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 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 >
Represents the relative location of an instruction.