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);
419 uint64_t FunctionHash = 0;
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())
663 M.reserve(*NumVTableTypes);
667 if (std::error_code EC = VTableType.getError())
671 if (std::error_code EC = VTableSamples.getError())
676 if (!
M.insert(std::make_pair(*VTableType, *VTableSamples)).second) {
678 Buffer->getBufferIdentifier(), 0,
679 "Duplicate vtable type " + VTableType->str() +
680 " at the same location. Additional counters will be ignored.",
691 "Cannot read vtable profiles if ReadVTableProf is false");
695 if (std::error_code EC = NumCallsites.getError())
701 if (std::error_code EC = LineOffset.getError())
708 if (std::error_code EC = Discriminator.getError())
724 if (std::error_code EC = NumSamples.getError())
730 if (std::error_code EC = NumRecords.getError())
736 if (std::error_code EC = LineOffset.getError())
744 if (std::error_code EC = Discriminator.getError())
748 if (std::error_code EC = NumSamples.getError())
752 if (std::error_code EC = NumCalls.getError())
758 for (
uint32_t J = 0; J < *NumCalls; ++J) {
760 if (std::error_code EC = CalledFunction.getError())
764 if (std::error_code EC = CalledFunctionSamples.getError())
768 *CalledFunction, *CalledFunctionSamples);
771 FProfile.
addBodySamples(*LineOffset, DiscriminatorVal, *NumSamples);
776 if (std::error_code EC = NumCallsites.getError())
779 for (
uint32_t J = 0; J < *NumCallsites; ++J) {
781 if (std::error_code EC = LineOffset.getError())
785 if (std::error_code EC = Discriminator.getError())
789 if (std::error_code EC = FName.getError())
798 if (std::error_code EC =
readProfile(CalleeProfile))
813 if (std::error_code EC = NumHeadSamples.getError())
817 if (std::error_code EC = FContextHash.getError())
820 auto &[FContext, Hash] = *FContextHash;
827 if (FContext.hasContext())
855 switch (Entry.Type) {
860 Summary->setPartialProfile(
true);
871 bool FixedLengthMD5 =
880 if (std::error_code EC =
906 bool IsNested = !IsFlat;
910 "func offset table should always be sorted or in Eytzinger BFS "
911 "order in CS profile");
982 ProfilesToReadMetadata.
insert(&
I->second);
1014 size_t SpanSize =
NameTable->getEytzingerSpan(IsNested).size();
1035 if (std::error_code EC =
Size.getError())
1039 if (UseFuncOffsetList)
1044 for (uint64_t
I = 0;
I < *
Size; ++
I) {
1046 if (std::error_code EC = FContextHash.getError())
1049 auto &[FContext, Hash] = *FContextHash;
1051 if (std::error_code EC =
Offset.getError())
1054 if (UseFuncOffsetList)
1081 if (RelOffset == UINT32_MAX)
1083 const uint8_t *FuncProfileAddr = Start + RelOffset;
1107 const auto &FContext = NameOffset.first;
1119 if (!CommonContext || !CommonContext->
isPrefixOf(FContext))
1120 CommonContext = &FContext;
1123 if (CommonContext == &FContext ||
1124 (CommonContext && CommonContext->
isPrefixOf(FContext))) {
1127 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
1147 StringRef FuncNameStr = FuncName.stringRef();
1150 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
1179 if (!LoadFuncsToBeUsed) {
1192 "Cannot have both context-sensitive and regular profile");
1194 "Section flag should be consistent with actual profile");
1207 if (
Size %
sizeof(uint64_t) != 0)
1210 size_t NumEntries =
Size /
sizeof(uint64_t);
1212 ProfSymList = std::make_unique<ProfileSymbolList>();
1222 ProfSymList = std::make_unique<ProfileSymbolList>();
1231std::error_code SampleProfileReaderExtBinaryBase::decompressSection(
1232 const uint8_t *SecStart,
const uint64_t SecSize,
1233 const uint8_t *&DecompressBuf, uint64_t &DecompressBufSize) {
1235 End = SecStart + SecSize;
1237 if (std::error_code EC = DecompressSize.getError())
1239 DecompressBufSize = *DecompressSize;
1242 if (std::error_code EC = CompressSize.getError())
1249 size_t UCSize = DecompressBufSize;
1260 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1271 const uint8_t *SecStart = BufStart + Entry.Offset;
1272 uint64_t SecSize = Entry.Size;
1281 uint64_t DecompressBufSize;
1282 if (std::error_code EC = decompressSection(
1283 SecStart, SecSize, DecompressBuf, DecompressBufSize))
1285 SecStart = DecompressBuf;
1286 SecSize = DecompressBufSize;
1289 if (std::error_code EC =
readOneSection(SecStart, SecSize, Entry))
1291 if (
Data != SecStart + SecSize)
1296 Data = BufStart + Entry.Offset;
1297 End = BufStart +
Buffer->getBufferSize();
1304std::error_code SampleProfileReaderRawBinary::verifySPMagic(uint64_t Magic) {
1310std::error_code SampleProfileReaderExtBinary::verifySPMagic(uint64_t Magic) {
1318 if (std::error_code EC =
Size.getError())
1327 std::vector<FunctionId> TableVec;
1328 TableVec.reserve(*
Size);
1339 for (
size_t I = 0;
I < *
Size; ++
I) {
1341 if (std::error_code EC = Name.getError())
1347 TableVec.emplace_back(FID);
1355 std::make_unique<MD5SampleProfileNameTable>(std::move(TableVec));
1358 std::make_unique<StringSampleProfileNameTable>(std::move(TableVec));
1363 bool IsMD5,
bool FixedLengthMD5,
bool IsEytzinger) {
1375 bool IsMD5,
bool FixedLengthMD5) {
1376 assert(IsMD5 &&
"Eytzinger name tables require MD5 representation");
1382 for (uint64_t &
Count : Counts) {
1384 if (std::error_code EC = ValOrErr.getError())
1388 auto [NumNested, NumFlat, NumInlinees] = Counts;
1391 if (NumNested > std::numeric_limits<uint32_t>::max() ||
1392 NumFlat > std::numeric_limits<uint32_t>::max() ||
1393 NumInlinees > std::numeric_limits<uint32_t>::max())
1396 uint64_t TotalEntries = NumNested + NumFlat + NumInlinees;
1397 if (
static_cast<size_t>(
End -
Data) < TotalEntries *
sizeof(uint64_t))
1400 NameTable = std::make_unique<EytzingerSampleProfileNameTable>(
1406 Data =
Data + TotalEntries *
sizeof(uint64_t);
1412 bool FixedLengthMD5) {
1413 if (FixedLengthMD5) {
1415 errs() <<
"If FixedLengthMD5 is true, UseMD5 has to be true";
1417 if (std::error_code EC =
Size.getError())
1421 "Fixed length MD5 name table does not contain specified number of "
1429 std::vector<FunctionId> TableVec;
1430 TableVec.reserve(*
Size);
1431 for (
size_t I = 0;
I < *
Size; ++
I) {
1438 std::make_unique<MD5SampleProfileNameTable>(std::move(TableVec));
1442 Data =
Data + (*Size) *
sizeof(uint64_t);
1447 assert(!FixedLengthMD5 &&
"FixedLengthMD5 should be unreachable here");
1449 if (std::error_code EC =
Size.getError())
1452 std::vector<FunctionId> TableVec;
1453 TableVec.reserve(*
Size);
1456 for (
size_t I = 0;
I < *
Size; ++
I) {
1458 if (std::error_code EC = FID.getError())
1467 std::make_unique<MD5SampleProfileNameTable>(std::move(TableVec));
1480 if (std::error_code EC =
Size.getError())
1493 for (
size_t I = 0;
I < *
Size; ++
I) {
1496 if (std::error_code EC = ContextSize.getError())
1498 for (
uint32_t J = 0; J < *ContextSize; ++J) {
1500 if (std::error_code EC = FName.getError())
1503 if (std::error_code EC = LineOffset.getError())
1510 if (std::error_code EC = Discriminator.getError())
1514 FName.get(),
LineLocation(LineOffset.get(), Discriminator.get()));
1526 if (std::error_code EC = Checksum.getError())
1534 if (std::error_code EC = Attributes.getError())
1543 if (std::error_code EC = NumCallsites.getError())
1546 for (
uint32_t J = 0; J < *NumCallsites; ++J) {
1548 if (std::error_code EC = LineOffset.getError())
1552 if (std::error_code EC = Discriminator.getError())
1556 if (std::error_code EC = FContextHash.getError())
1559 auto &[FContext, Hash] = *FContextHash;
1564 *LineOffset, *Discriminator))[FContext.getFunction()]);
1585 Data = R->second.first;
1586 End = R->second.second;
1597 if (std::error_code EC = FContextHash.getError())
1599 auto &[FContext, Hash] = *FContextHash;
1603 FProfile = &It->second;
1620 if (std::error_code EC =
Type.getError())
1622 Entry.Type =
static_cast<SecType>(*Type);
1625 if (std::error_code EC = Flags.getError())
1627 Entry.Flags = *Flags;
1630 if (std::error_code EC =
Offset.getError())
1635 if (std::error_code EC =
Size.getError())
1639 Entry.LayoutIndex = Idx;
1646 if (std::error_code EC = EntryNum.getError())
1649 for (uint64_t i = 0; i < (*EntryNum); i++)
1658 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1660 End = BufStart +
Buffer->getBufferSize();
1674 if (Entry.Type ==
Type)
1686 uint64_t FileSize = 0;
1688 FileSize = std::max(Entry.Offset + Entry.Size, FileSize);
1696 Flags.append(
"{compressed,");
1701 Flags.append(
"flat,");
1703 switch (Entry.Type) {
1706 Flags.append(
"eytzinger,");
1708 Flags.append(
"fixlenmd5,");
1710 Flags.append(
"md5,");
1712 Flags.append(
"uniq,");
1716 Flags.append(
"partial,");
1718 Flags.append(
"context,");
1720 Flags.append(
"preInlined,");
1722 Flags.append(
"fs-discriminator,");
1726 Flags.append(
"ordered,");
1728 Flags.append(
"eytzinger,");
1732 Flags.append(
"probe,");
1734 Flags.append(
"attr,");
1738 Flags.append(
"md5,");
1743 char &last = Flags.back();
1752 uint64_t TotalSecsSize = 0;
1754 OS <<
getSecName(Entry.Type) <<
" - Offset: " << Entry.Offset
1755 <<
", Size: " << Entry.Size <<
", Flags: " <<
getSecFlagsStr(Entry)
1758 TotalSecsSize += Entry.Size;
1762 "Size of 'header + sections' doesn't match the total size of profile");
1764 OS <<
"Header Size: " << HeaderSize <<
"\n";
1765 OS <<
"Total Sections Size: " << TotalSecsSize <<
"\n";
1773 if (std::error_code EC = Magic.getError())
1775 else if (std::error_code EC = verifySPMagic(*Magic))
1780 if (std::error_code EC =
Version.getError())
1804std::error_code SampleProfileReaderBinary::readSummaryEntry(
1805 std::vector<ProfileSummaryEntry> &Entries) {
1807 if (std::error_code EC = Cutoff.getError())
1811 if (std::error_code EC = MinBlockCount.getError())
1815 if (std::error_code EC = NumBlocks.getError())
1818 Entries.emplace_back(*Cutoff, *MinBlockCount, *NumBlocks);
1824 if (std::error_code EC = TotalCount.getError())
1828 if (std::error_code EC = MaxBlockCount.getError())
1832 if (std::error_code EC = MaxFunctionCount.getError())
1836 if (std::error_code EC = NumBlocks.getError())
1840 if (std::error_code EC = NumFunctions.getError())
1844 if (std::error_code EC = NumSummaryEntries.getError())
1847 std::vector<ProfileSummaryEntry> Entries;
1848 for (
unsigned i = 0; i < *NumSummaryEntries; i++) {
1849 std::error_code EC = readSummaryEntry(Entries);
1853 Summary = std::make_unique<ProfileSummary>(
1855 *MaxFunctionCount, *NumBlocks, *NumFunctions);
1884 if (
GcovBuffer.readInt(Val) && Val <= std::numeric_limits<T>::max())
1885 return static_cast<T>(Val);
1886 }
else if (
sizeof(
T) <=
sizeof(uint64_t)) {
1888 if (
GcovBuffer.readInt64(Val) && Val <= std::numeric_limits<T>::max())
1889 return static_cast<T>(Val);
1951 Names.push_back(std::string(Str));
1976 uint64_t HeadCount = 0;
1977 if (InlineStack.
size() == 0)
1996 if (InlineStack.
size() == 0) {
2045 for (
auto *CallerProfile : NewStack)
2046 CallerProfile->addTotalSamples(
Count);
2055 for (
uint32_t J = 0; J < NumTargets; J++) {
2068 uint64_t TargetCount;
2116 return Magic ==
"adcg*704";
2122 if (Reader.useMD5()) {
2124 Reader.getBuffer()->getBufferIdentifier(),
2125 "Profile data remapping cannot be applied to profile data "
2126 "using MD5 names (original mangled names are not available).",
2133 assert(Remappings &&
"should be initialized while creating remapper");
2134 for (
auto &Sample : Reader.getProfiles()) {
2136 Sample.second.findAllNames(NamesInSample);
2137 for (
auto &Name : NamesInSample) {
2139 if (
auto Key = Remappings->insert(NameStr))
2140 NameMap.insert({
Key, NameStr});
2144 RemappingApplied =
true;
2147std::optional<StringRef>
2149 if (
auto Key = Remappings->lookup(Fname)) {
2151 if (!Result.empty())
2154 return std::nullopt;
2164 if (std::error_code EC = BufferOrErr.getError())
2166 auto Buffer = std::move(BufferOrErr.get());
2168 return std::move(Buffer);
2182ErrorOr<std::unique_ptr<SampleProfileReader>>
2187 if (std::error_code EC = BufferOrError.getError())
2189 return create(BufferOrError.get(),
C, FS,
P, RemapFilename);
2208 if (std::error_code EC = BufferOrError.getError())
2210 return create(BufferOrError.get(), Reader,
C);
2227 auto Remappings = std::make_unique<SymbolRemappingReader>();
2228 if (
Error E = Remappings->read(*
B)) {
2232 ParseError.getLineNum(),
2233 ParseError.getMessage()));
2238 return std::make_unique<SampleProfileReaderItaniumRemapper>(
2239 std::move(
B), std::move(Remappings), Reader);
2257 std::unique_ptr<SampleProfileReader> Reader;
2269 if (!RemapFilename.
empty()) {
2271 RemapFilename, FS, *Reader,
C);
2272 if (std::error_code EC = ReaderOrErr.getError()) {
2273 std::string
Msg =
"Could not create remapper: " + EC.message();
2277 Reader->Remapper = std::move(ReaderOrErr.get());
2280 if (std::error_code EC = Reader->readHeader()) {
2284 Reader->setDiscriminatorMaskedBitFrom(
P);
2286 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.
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.
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.
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
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::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.
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)
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.
SmallVector< SampleContextFrame, 1 > SampleContextFrameVector
static std::string getSecName(SecType Type)
constexpr InMemoryModeT InMemoryMode
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.
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...
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.