45#include <system_error>
49using namespace sampleprof;
51#define DEBUG_TYPE "samplepgo-reader"
58 cl::desc(
"Profile uses flow sensitive discriminators"));
66 OS <<
"Function: " << FS.getContext().toString() <<
": " << FS;
71 std::vector<NameFunctionSamples> V;
73 for (
const auto &
I : V)
80 for (
const auto &
I : BodySamples) {
90 if (!CallTargets.empty()) {
92 for (
const auto &J : CallTargets) {
105 for (
const auto &
I : CallsiteSamples)
106 for (
const auto &FS :
I.second) {
126 if (!BodySamples.empty())
130 if (!CallsiteSamples.empty())
132 [&] { DumpCallsiteSamples(CallsiteSamples); });
138 std::vector<NameFunctionSamples> V;
142 for (
const auto &
F : V)
161 size_t n2 = Input.
rfind(
':');
162 size_t n1 = Input.
rfind(
':', n2 - 1);
163 FName = Input.
substr(0, n1);
225 if (Input[
Depth] ==
'!') {
226 LineTy = LineType::Metadata;
237 size_t n1 = Input.
find(
':');
239 size_t n2 = Loc.
find(
'.');
253 LineTy = LineType::BodyProfile;
254 size_t n3 = Rest.
find(
' ');
304 if (n4 == Rest.
size())
310 LineTy = LineType::CallSiteProfile;
312 CalleeName = Rest.
substr(0, n3);
330 uint32_t TopLevelProbeProfileCount = 0;
336 std::vector<SampleContext *> FlatSamples;
342 if (pos == LineIt->
npos || (*LineIt)[pos] ==
'#')
356 if ((*LineIt)[0] !=
' ') {
357 uint64_t NumSamples, NumHeadSamples;
359 if (!
ParseHead(*LineIt, FName, NumSamples, NumHeadSamples)) {
361 "Expected 'mangled_name:NUM:NUM', found " + *LineIt);
383 Discriminator, FName, TargetCountMap, FunctionHash,
386 "Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " +
390 if (LineTy != LineType::Metadata &&
Depth == DepthMetadata) {
393 "Found non-metadata after metadata: " + *LineIt);
404 case LineType::CallSiteProfile: {
413 case LineType::BodyProfile: {
418 for (
const auto &name_count : TargetCountMap) {
420 LineOffset, Discriminator,
429 case LineType::Metadata: {
434 ++TopLevelProbeProfileCount;
439 DepthMetadata =
Depth;
442 FlatSamples.push_back(&FProfile.
getContext());
446 "!Flat may only be used at top level function.",
DS_Warning));
461 "Cannot have both context-sensitive and regular profile");
463 assert((TopLevelProbeProfileCount == 0 ||
464 TopLevelProbeProfileCount ==
Profiles.size()) &&
465 "Cannot have both probe-based profiles and regular profiles");
483 if ((*LineIt)[0] !=
' ') {
484 uint64_t NumSamples, NumHeadSamples;
486 result =
ParseHead(*LineIt, FName, NumSamples, NumHeadSamples);
494 unsigned NumBytesRead = 0;
497 if (Val > std::numeric_limits<T>::max()) {
501 }
else if (
Data + NumBytesRead >
End) {
507 Data += NumBytesRead;
508 return static_cast<T>(Val);
513 if (
Data + Str.size() + 1 >
End) {
519 Data += Str.size() + 1;
531 using namespace support;
532 T Val = endian::readNext<T, llvm::endianness::little>(
Data);
538 auto Idx = readNumber<size_t>();
539 if (std::error_code EC =
Idx.getError())
541 if (*
Idx >= Table.size())
549 if (std::error_code EC =
Idx.getError())
558 auto ContextIdx = readNumber<size_t>();
559 if (std::error_code EC = ContextIdx.getError())
564 *RetIdx = *ContextIdx;
574 if (std::error_code EC = FContext.getError())
579 if (std::error_code EC = FName.getError())
594 return std::make_pair(Context, Hash);
599 auto NumSamples = readNumber<uint64_t>();
600 if (std::error_code EC = NumSamples.getError())
605 auto NumRecords = readNumber<uint32_t>();
606 if (std::error_code EC = NumRecords.getError())
610 auto LineOffset = readNumber<uint64_t>();
611 if (std::error_code EC = LineOffset.getError())
615 return std::error_code();
618 auto Discriminator = readNumber<uint64_t>();
619 if (std::error_code EC = Discriminator.getError())
622 auto NumSamples = readNumber<uint64_t>();
623 if (std::error_code EC = NumSamples.getError())
626 auto NumCalls = readNumber<uint32_t>();
627 if (std::error_code EC = NumCalls.getError())
633 for (
uint32_t J = 0; J < *NumCalls; ++J) {
635 if (std::error_code EC = CalledFunction.getError())
638 auto CalledFunctionSamples = readNumber<uint64_t>();
639 if (std::error_code EC = CalledFunctionSamples.getError())
643 *CalledFunction, *CalledFunctionSamples);
646 FProfile.
addBodySamples(*LineOffset, DiscriminatorVal, *NumSamples);
650 auto NumCallsites = readNumber<uint32_t>();
651 if (std::error_code EC = NumCallsites.getError())
654 for (
uint32_t J = 0; J < *NumCallsites; ++J) {
655 auto LineOffset = readNumber<uint64_t>();
656 if (std::error_code EC = LineOffset.getError())
659 auto Discriminator = readNumber<uint64_t>();
660 if (std::error_code EC = Discriminator.getError())
664 if (std::error_code EC = FName.getError())
673 if (std::error_code EC =
readProfile(CalleeProfile))
684 auto NumHeadSamples = readNumber<uint64_t>();
685 if (std::error_code EC = NumHeadSamples.getError())
689 if (std::error_code EC = FContextHash.getError())
692 auto &[FContext, Hash] = *FContextHash;
699 if (FContext.hasContext())
727 switch (Entry.Type) {
732 Summary->setPartialProfile(
true);
741 bool FixedLengthMD5 =
771 "func offset table should always be sorted in CS profile");
855 auto Size = readNumber<uint64_t>();
856 if (std::error_code EC =
Size.getError())
860 if (UseFuncOffsetList)
867 if (std::error_code EC = FContextHash.getError())
870 auto &[FContext, Hash] = *FContextHash;
871 auto Offset = readNumber<uint64_t>();
872 if (std::error_code EC =
Offset.getError())
875 if (UseFuncOffsetList)
913 const auto &FContext = NameOffset.first;
925 if (!CommonContext || !CommonContext->
isPrefixOf(FContext))
926 CommonContext = &FContext;
929 if (CommonContext == &FContext ||
930 (CommonContext && CommonContext->
isPrefixOf(FContext))) {
933 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
945 const uint8_t *FuncProfileAddr = Start + iter->second;
954 StringRef FuncNameStr = FuncName.stringRef();
957 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
968 const uint8_t *FuncProfileAddr = Start + iter->second;
988 if (!LoadFuncsToBeUsed) {
1001 "Cannot have both context-sensitive and regular profile");
1003 "Section flag should be consistent with actual profile");
1009 ProfSymList = std::make_unique<ProfileSymbolList>();
1018std::error_code SampleProfileReaderExtBinaryBase::decompressSection(
1022 End = SecStart + SecSize;
1023 auto DecompressSize = readNumber<uint64_t>();
1024 if (std::error_code EC = DecompressSize.getError())
1026 DecompressBufSize = *DecompressSize;
1028 auto CompressSize = readNumber<uint64_t>();
1029 if (std::error_code EC = CompressSize.getError())
1036 size_t UCSize = DecompressBufSize;
1047 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1058 const uint8_t *SecStart = BufStart + Entry.Offset;
1069 if (std::error_code EC = decompressSection(
1070 SecStart, SecSize, DecompressBuf, DecompressBufSize))
1072 SecStart = DecompressBuf;
1073 SecSize = DecompressBufSize;
1076 if (std::error_code EC =
readOneSection(SecStart, SecSize, Entry))
1078 if (
Data != SecStart + SecSize)
1083 Data = BufStart + Entry.Offset;
1084 End = BufStart +
Buffer->getBufferSize();
1091std::error_code SampleProfileReaderRawBinary::verifySPMagic(
uint64_t Magic) {
1097std::error_code SampleProfileReaderExtBinary::verifySPMagic(
uint64_t Magic) {
1104 auto Size = readNumber<size_t>();
1105 if (std::error_code EC =
Size.getError())
1126 for (
size_t I = 0;
I < *
Size; ++
I) {
1128 if (std::error_code EC =
Name.getError())
1145 bool FixedLengthMD5) {
1146 if (FixedLengthMD5) {
1148 errs() <<
"If FixedLengthMD5 is true, UseMD5 has to be true";
1149 auto Size = readNumber<size_t>();
1150 if (std::error_code EC =
Size.getError())
1154 "Fixed length MD5 name table does not contain specified number of "
1161 for (
size_t I = 0;
I < *
Size; ++
I) {
1162 using namespace support;
1163 uint64_t FID = endian::read<uint64_t, endianness::little, unaligned>(
1174 assert(!FixedLengthMD5 &&
"FixedLengthMD5 should be unreachable here");
1175 auto Size = readNumber<size_t>();
1176 if (std::error_code EC =
Size.getError())
1183 for (
size_t I = 0;
I < *
Size; ++
I) {
1184 auto FID = readNumber<uint64_t>();
1185 if (std::error_code EC = FID.getError())
1204 auto Size = readNumber<size_t>();
1205 if (std::error_code EC =
Size.getError())
1218 for (
size_t I = 0;
I < *
Size; ++
I) {
1220 auto ContextSize = readNumber<uint32_t>();
1221 if (std::error_code EC = ContextSize.getError())
1223 for (
uint32_t J = 0; J < *ContextSize; ++J) {
1225 if (std::error_code EC = FName.getError())
1227 auto LineOffset = readNumber<uint64_t>();
1228 if (std::error_code EC = LineOffset.getError())
1232 return std::error_code();
1234 auto Discriminator = readNumber<uint64_t>();
1235 if (std::error_code EC = Discriminator.getError())
1239 FName.get(),
LineLocation(LineOffset.get(), Discriminator.get()));
1251 auto Checksum = readNumber<uint64_t>();
1252 if (std::error_code EC = Checksum.getError())
1260 if (std::error_code EC =
Attributes.getError())
1268 auto NumCallsites = readNumber<uint32_t>();
1269 if (std::error_code EC = NumCallsites.getError())
1272 for (
uint32_t J = 0; J < *NumCallsites; ++J) {
1273 auto LineOffset = readNumber<uint64_t>();
1274 if (std::error_code EC = LineOffset.getError())
1277 auto Discriminator = readNumber<uint64_t>();
1278 if (std::error_code EC = Discriminator.getError())
1282 if (std::error_code EC = FContextHash.getError())
1285 auto &[FContext, Hash] = *FContextHash;
1291 *Discriminator))[FContext.getFunction()]);
1293 if (std::error_code EC =
1315 Data = R->second.first;
1316 End = R->second.second;
1328 if (std::error_code EC = FContextHash.getError())
1330 auto &[FContext, Hash] = *FContextHash;
1334 FProfile = &It->second;
1350 auto Type = readUnencodedNumber<uint64_t>();
1351 if (std::error_code EC =
Type.getError())
1353 Entry.Type =
static_cast<SecType>(*Type);
1355 auto Flags = readUnencodedNumber<uint64_t>();
1356 if (std::error_code EC = Flags.getError())
1358 Entry.Flags = *Flags;
1360 auto Offset = readUnencodedNumber<uint64_t>();
1361 if (std::error_code EC =
Offset.getError())
1365 auto Size = readUnencodedNumber<uint64_t>();
1366 if (std::error_code EC =
Size.getError())
1370 Entry.LayoutIndex =
Idx;
1376 auto EntryNum = readUnencodedNumber<uint64_t>();
1377 if (std::error_code EC = EntryNum.getError())
1380 for (
uint64_t i = 0; i < (*EntryNum); i++)
1389 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1391 End = BufStart +
Buffer->getBufferSize();
1405 if (Entry.Type ==
Type)
1419 FileSize = std::max(Entry.Offset + Entry.Size, FileSize);
1427 Flags.append(
"{compressed,");
1432 Flags.append(
"flat,");
1434 switch (Entry.Type) {
1437 Flags.append(
"fixlenmd5,");
1439 Flags.append(
"md5,");
1441 Flags.append(
"uniq,");
1445 Flags.append(
"partial,");
1447 Flags.append(
"context,");
1449 Flags.append(
"preInlined,");
1451 Flags.append(
"fs-discriminator,");
1455 Flags.append(
"ordered,");
1459 Flags.append(
"probe,");
1461 Flags.append(
"attr,");
1466 char &last = Flags.back();
1477 OS <<
getSecName(Entry.Type) <<
" - Offset: " << Entry.Offset
1478 <<
", Size: " << Entry.Size <<
", Flags: " <<
getSecFlagsStr(Entry)
1481 TotalSecsSize += Entry.Size;
1485 "Size of 'header + sections' doesn't match the total size of profile");
1487 OS <<
"Header Size: " << HeaderSize <<
"\n";
1488 OS <<
"Total Sections Size: " << TotalSecsSize <<
"\n";
1495 auto Magic = readNumber<uint64_t>();
1496 if (std::error_code EC = Magic.getError())
1498 else if (std::error_code EC = verifySPMagic(*Magic))
1502 auto Version = readNumber<uint64_t>();
1503 if (std::error_code EC =
Version.getError())
1526std::error_code SampleProfileReaderBinary::readSummaryEntry(
1527 std::vector<ProfileSummaryEntry> &Entries) {
1528 auto Cutoff = readNumber<uint64_t>();
1529 if (std::error_code EC = Cutoff.getError())
1532 auto MinBlockCount = readNumber<uint64_t>();
1533 if (std::error_code EC = MinBlockCount.getError())
1536 auto NumBlocks = readNumber<uint64_t>();
1537 if (std::error_code EC = NumBlocks.getError())
1540 Entries.emplace_back(*Cutoff, *MinBlockCount, *NumBlocks);
1545 auto TotalCount = readNumber<uint64_t>();
1546 if (std::error_code EC = TotalCount.getError())
1549 auto MaxBlockCount = readNumber<uint64_t>();
1550 if (std::error_code EC = MaxBlockCount.getError())
1553 auto MaxFunctionCount = readNumber<uint64_t>();
1554 if (std::error_code EC = MaxFunctionCount.getError())
1557 auto NumBlocks = readNumber<uint64_t>();
1558 if (std::error_code EC = NumBlocks.getError())
1561 auto NumFunctions = readNumber<uint64_t>();
1562 if (std::error_code EC = NumFunctions.getError())
1565 auto NumSummaryEntries = readNumber<uint64_t>();
1566 if (std::error_code EC = NumSummaryEntries.getError())
1569 std::vector<ProfileSummaryEntry> Entries;
1570 for (
unsigned i = 0; i < *NumSummaryEntries; i++) {
1571 std::error_code EC = readSummaryEntry(Entries);
1575 Summary = std::make_unique<ProfileSummary>(
1577 *MaxFunctionCount, *NumBlocks, *NumFunctions);
1607 return static_cast<T>(Val);
1608 }
else if (
sizeof(
T) <=
sizeof(
uint64_t)) {
1611 return static_cast<T>(Val);
1673 Names.push_back(std::string(Str));
1699 if (InlineStack.
size() == 0)
1718 if (InlineStack.
size() == 0) {
1766 for (
auto *CallerProfile : NewStack)
1767 CallerProfile->addTotalSamples(Count);
1776 for (
uint32_t J = 0; J < NumTargets; J++) {
1837 StringRef Magic(
reinterpret_cast<const char *
>(
Buffer.getBufferStart()));
1838 return Magic ==
"adcg*704";
1847 "Profile data remapping cannot be applied to profile data "
1848 "using MD5 names (original mangled names are not available).",
1855 assert(Remappings &&
"should be initialized while creating remapper");
1858 Sample.second.findAllNames(NamesInSample);
1859 for (
auto &
Name : NamesInSample) {
1861 if (
auto Key = Remappings->insert(NameStr))
1862 NameMap.insert({Key, NameStr});
1866 RemappingApplied =
true;
1869std::optional<StringRef>
1871 if (
auto Key = Remappings->lookup(Fname)) {
1873 if (!Result.empty())
1876 return std::nullopt;
1885 : FS.getBufferForFile(Filename);
1886 if (std::error_code EC = BufferOrErr.getError())
1888 auto Buffer = std::move(BufferOrErr.get());
1890 return std::move(Buffer);
1909 if (std::error_code EC = BufferOrError.getError())
1911 return create(BufferOrError.get(),
C, FS,
P, RemapFilename);
1930 if (std::error_code EC = BufferOrError.getError())
1932 return create(BufferOrError.get(), Reader,
C);
1949 auto Remappings = std::make_unique<SymbolRemappingReader>();
1950 if (
Error E = Remappings->read(*
B)) {
1960 return std::make_unique<SampleProfileReaderItaniumRemapper>(
1961 std::move(
B), std::move(Remappings), Reader);
1979 std::unique_ptr<SampleProfileReader> Reader;
1991 if (!RemapFilename.
empty()) {
1993 RemapFilename, FS, *Reader,
C);
1994 if (std::error_code EC = ReaderOrErr.getError()) {
1995 std::string Msg =
"Could not create remapper: " + EC.message();
1999 Reader->Remapper = std::move(ReaderOrErr.get());
2002 if (std::error_code EC = Reader->readHeader()) {
2006 Reader->setDiscriminatorMaskedBitFrom(
P);
2008 return std::move(Reader);
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
Provides ErrorOr<T> smart pointer.
Module.h This file contains the declarations for the Module class.
This file supports working with JSON data.
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool ParseHead(const StringRef &Input, StringRef &FName, uint64_t &NumSamples, uint64_t &NumHeadSamples)
Parse Input as function head.
static void dumpFunctionProfileJson(const FunctionSamples &S, json::OStream &JOS, bool TopLevel=false)
static bool isOffsetLegal(unsigned L)
Returns true if line offset L is legal (only has 16 bits).
static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth, uint64_t &NumSamples, uint32_t &LineOffset, uint32_t &Discriminator, StringRef &CalleeName, DenseMap< StringRef, uint64_t > &TargetCountMap, uint64_t &FunctionHash, uint32_t &Attributes, bool &IsFlat)
Parse Input as line sample.
static cl::opt< bool > ProfileIsFSDisciminator("profile-isfs", cl::Hidden, cl::init(false), cl::desc("Profile uses flow sensitive discriminators"))
static std::string getSecFlagsStr(const SecHdrTableEntry &Entry)
static bool parseMetadata(const StringRef &Input, uint64_t &FunctionHash, uint32_t &Attributes)
Parse Input that contains metadata.
Defines the virtual file system interface vfs::FileSystem.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
Implements a dense probed hash-table based set.
Diagnostic information for the sample profiler.
Represents either an error or a value T.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
bool readInt(uint32_t &Val)
bool readInt64(uint64_t &Val)
bool readGCOVVersion(GCOV::GCOVVersion &version)
readGCOVVersion - Read GCOV version.
bool readString(StringRef &str)
bool readGCDAFormat()
readGCDAFormat - Check GCDA signature is valid at the beginning of buffer.
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
This is an important class for using LLVM in a threaded context.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getSTDIN()
Read all of stdin into a file buffer, and return it.
static const ArrayRef< uint32_t > DefaultCutoffs
A vector of useful cutoff values for detailed summary.
std::unique_ptr< ProfileSummary > computeSummaryForProfiles(const sampleprof::SampleProfileMap &Profiles)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
static constexpr size_t npos
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
int64_t getLineNum() const
StringRef getMessage() const
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
void object(Block Contents)
Emit an object whose elements are emitted in the provided Block.
void attribute(llvm::StringRef Key, const Value &Contents)
Emit an attribute whose value is self-contained (number, vector<int> etc).
void attributeArray(llvm::StringRef Key, Block Contents)
Emit an attribute whose value is an array with elements from the Block.
A forward iterator which reads text lines from a buffer.
int64_t line_number() const
Return the current line number. May return any number at EOF.
bool is_at_eof() const
Return true if we've reached EOF or are an "end" iterator.
This class implements an extremely fast bulk output stream that can only output to a stream.
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 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 bool ProfileIsProbeBased
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
sampleprof_error addBodySamples(uint32_t LineOffset, uint32_t Discriminator, uint64_t Num, uint64_t Weight=1)
void setFunctionHash(uint64_t Hash)
static bool ProfileIsFS
If this profile uses flow sensitive discriminators.
SampleContext & getContext() const
static bool HasUniqSuffix
Whether the profile contains any ".__uniq." suffix in a name.
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
const CallsiteSampleMap & getCallsiteSamples() const
Return all the callsite samples collected in the body of the function.
void setContext(const SampleContext &FContext)
const BodySampleMap & getBodySamples() const
Return all the samples collected in the body of the function.
std::pair< iterator, bool > try_emplace(const key_type &Hash, const original_key_type &Key, Ts &&...Args)
void setAllAttributes(uint32_t A)
uint64_t getHashCode() const
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)
mapped_type & create(const SampleContext &Ctx)
size_t erase(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::vector< FunctionId > 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(),...
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 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
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.
DenseSet< StringRef > FuncsToUse
The set containing the functions to use when compiling a module.
std::error_code readFuncMetadata(bool ProfileHasAttribute, SampleProfileMap &Profiles)
std::unique_ptr< ProfileSymbolList > ProfSymList
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 readNameTableSec(bool IsMD5, bool FixedLengthMD5)
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
DenseMap< hash_code, uint64_t > FuncOffsetTable
The table mapping from a function context's MD5 to the offset of its FunctionSample towards file star...
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()
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
ErrorOr< T > readNumber()
GCOVBuffer GcovBuffer
GCOV buffer containing the profile.
std::vector< std::string > Names
Function names in this profile.
std::error_code readImpl() override
Read sample profiles from the associated file.
std::error_code readNameTable()
std::error_code readHeader() override
Read and validate the file header.
ErrorOr< StringRef > readString()
static const uint32_t GCOVTagAFDOFunction
std::error_code readOneFunctionProfile(const InlineCallStack &InlineStack, bool Update, uint32_t Offset)
std::error_code readFunctionProfiles()
static const uint32_t GCOVTagAFDOFileNames
GCOV tags used to separate sections in the profile file.
std::error_code skipNextWord()
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
std::error_code readSectionTag(uint32_t Expected)
Read the section tag and check that it's the same as Expected.
static ErrorOr< std::unique_ptr< SampleProfileReaderItaniumRemapper > > create(StringRef Filename, vfs::FileSystem &FS, SampleProfileReader &Reader, LLVMContext &C)
Create a remapper from the given remapping file.
void applyRemapping(LLVMContext &Ctx)
Apply remappings to the profile read by Reader.
std::optional< StringRef > lookUpNameInProfile(StringRef FunctionName)
Return the equivalent name in the profile for FunctionName if it exists.
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
std::error_code readImpl() override
Read sample profiles from the associated file.
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Sample-based profile reader.
std::pair< const uint8_t *, const uint8_t * > ProfileSecRange
bool ProfileIsPreInlined
Whether function profile contains ShouldBeInlined contexts.
std::unordered_map< uint64_t, std::pair< const uint8_t *, const uint8_t * > > FuncMetadataIndex
SampleProfileMap & getProfiles()
Return all the profiles.
uint32_t CSProfileCount
Number of context-sensitive profiles.
static 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.
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.
MemoryBuffer * getBuffer() const
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.
void computeSummary()
Compute summary for this profile.
uint32_t getDiscriminatorMask() const
Get the bitmask the discriminators: For FS profiles, return the bit mask for this pass.
bool ProfileIsFS
Whether the function profiles use FS discriminators.
void dumpJson(raw_ostream &OS=dbgs())
Print all the profiles on stream OS in the JSON format.
SampleProfileMap Profiles
Map every function to its associated profile.
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.
uint64_t getSamples() const
const SortedCallTargetSet getSortedCallTargets() const
The virtual file system interface.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)
void sortFuncProfiles(const SampleProfileMap &ProfileMap, std::vector< NameFunctionSamples > &SortedProfiles)
static uint64_t SPMagic(SampleProfileFormat Format=SPF_Binary)
static bool hasSecFlag(const SecHdrTableEntry &Entry, SecFlagType Flag)
std::map< LineLocation, FunctionSamplesMap > CallsiteSampleMap
@ HIST_TYPE_INDIR_CALL_TOPN
uint64_t MD5Hash(const FunctionId &Obj)
std::map< LineLocation, SampleRecord > BodySampleMap
@ SecFlagIsPreInlined
SecFlagIsPreInlined means this profile contains ShouldBeInlined contexts thus this is CS preinliner c...
@ SecFlagPartial
SecFlagPartial means the profile is for common/shared code.
@ SecFlagFSDiscriminator
SecFlagFSDiscriminator means this profile uses flow-sensitive discriminators.
@ SecFlagFullContext
SecFlagContext means this is context-sensitive flat profile for CSSPGO.
SmallVector< SampleContextFrame, 1 > SampleContextFrameVector
static std::string getSecName(SecType Type)
static uint64_t SPVersion()
uint64_t read64le(const void *P)
void write64le(void *P, uint64_t V)
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)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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...
Represents the relative location of an instruction.