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);
224 if (Input[
Depth] ==
'!') {
225 LineTy = LineType::Metadata;
229 size_t n1 = Input.
find(
':');
231 size_t n2 = Loc.
find(
'.');
245 LineTy = LineType::BodyProfile;
246 size_t n3 = Rest.
find(
' ');
296 if (n4 == Rest.
size())
302 LineTy = LineType::CallSiteProfile;
304 CalleeName = Rest.
substr(0, n3);
322 uint32_t TopLevelProbeProfileCount = 0;
332 if (pos == LineIt->
npos || (*LineIt)[pos] ==
'#')
346 if ((*LineIt)[0] !=
' ') {
347 uint64_t NumSamples, NumHeadSamples;
349 if (!
ParseHead(*LineIt, FName, NumSamples, NumHeadSamples)) {
351 "Expected 'mangled_name:NUM:NUM', found " + *LineIt);
372 Discriminator, FName, TargetCountMap, FunctionHash,
375 "Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " +
379 if (LineTy != LineType::Metadata &&
Depth == DepthMetadata) {
382 "Found non-metadata after metadata: " + *LineIt);
393 case LineType::CallSiteProfile: {
395 LineLocation(LineOffset, Discriminator))[std::string(FName)];
402 case LineType::BodyProfile: {
407 for (
const auto &name_count : TargetCountMap) {
409 LineOffset, Discriminator, name_count.first,
416 case LineType::Metadata: {
421 ++TopLevelProbeProfileCount;
426 DepthMetadata =
Depth;
434 "Cannot have both context-sensitive and regular profile");
436 assert((TopLevelProbeProfileCount == 0 ||
437 TopLevelProbeProfileCount ==
Profiles.size()) &&
438 "Cannot have both probe-based profiles and regular profiles");
456 if ((*LineIt)[0] !=
' ') {
457 uint64_t NumSamples, NumHeadSamples;
459 result =
ParseHead(*LineIt, FName, NumSamples, NumHeadSamples);
467 unsigned NumBytesRead = 0;
471 if (Val > std::numeric_limits<T>::max())
473 else if (
Data + NumBytesRead >
End)
483 Data += NumBytesRead;
484 return static_cast<T>(Val);
490 if (
Data + Str.size() + 1 >
End) {
496 Data += Str.size() + 1;
510 using namespace support;
511 T Val = endian::readNext<T, little, unaligned>(
Data);
518 auto Idx = readNumber<size_t>();
519 if (std::error_code EC =
Idx.getError())
521 if (*
Idx >= Table.size())
529 if (std::error_code EC =
Idx.getError())
540 using namespace support;
541 uint64_t FID = endian::read<uint64_t, little, unaligned>(
552 auto ContextIdx = readNumber<size_t>();
553 if (std::error_code EC = ContextIdx.getError())
558 *RetIdx = *ContextIdx;
568 if (std::error_code EC = FContext.getError())
573 if (std::error_code EC = FName.getError())
588 return std::make_pair(
Context, Hash);
593 auto NumSamples = readNumber<uint64_t>();
594 if (std::error_code EC = NumSamples.getError())
599 auto NumRecords = readNumber<uint32_t>();
600 if (std::error_code EC = NumRecords.getError())
604 auto LineOffset = readNumber<uint64_t>();
605 if (std::error_code EC = LineOffset.getError())
609 return std::error_code();
612 auto Discriminator = readNumber<uint64_t>();
613 if (std::error_code EC = Discriminator.getError())
616 auto NumSamples = readNumber<uint64_t>();
617 if (std::error_code EC = NumSamples.getError())
620 auto NumCalls = readNumber<uint32_t>();
621 if (std::error_code EC = NumCalls.getError())
627 for (
uint32_t J = 0; J < *NumCalls; ++J) {
629 if (std::error_code EC = CalledFunction.getError())
632 auto CalledFunctionSamples = readNumber<uint64_t>();
633 if (std::error_code EC = CalledFunctionSamples.getError())
637 *CalledFunction, *CalledFunctionSamples);
640 FProfile.
addBodySamples(*LineOffset, DiscriminatorVal, *NumSamples);
644 auto NumCallsites = readNumber<uint32_t>();
645 if (std::error_code EC = NumCallsites.getError())
648 for (
uint32_t J = 0; J < *NumCallsites; ++J) {
649 auto LineOffset = readNumber<uint64_t>();
650 if (std::error_code EC = LineOffset.getError())
653 auto Discriminator = readNumber<uint64_t>();
654 if (std::error_code EC = Discriminator.getError())
658 if (std::error_code EC = FName.getError())
665 LineLocation(*LineOffset, DiscriminatorVal))[std::string(*FName)];
667 if (std::error_code EC =
readProfile(CalleeProfile))
677 auto NumHeadSamples = readNumber<uint64_t>();
678 if (std::error_code EC = NumHeadSamples.getError())
682 if (std::error_code EC = FContextHash.getError())
685 auto &[FContext, Hash] = *FContextHash;
692 if (FContext.hasContext())
715 switch (Entry.Type) {
720 Summary->setPartialProfile(
true);
729 bool FixedLengthMD5 =
758 "func offset table should always be sorted in CS profile");
829 auto Size = readNumber<uint64_t>();
830 if (std::error_code EC =
Size.getError())
834 if (UseFuncOffsetList)
841 if (std::error_code EC = FContextHash.getError())
844 auto &[FContext, Hash] = *FContextHash;
845 auto Offset = readNumber<uint64_t>();
846 if (std::error_code EC =
Offset.getError())
849 if (UseFuncOffsetList)
871 const uint8_t *Start =
Data;
872 if (!LoadFuncsToBeUsed) {
903 const auto &FContext = NameOffset.first;
904 auto FName = FContext.
getName();
908 if ((
useMD5() && FuncGuidsToUse.
count(std::stoull(FName.data()))) ||
911 if (!CommonContext || !CommonContext->
IsPrefixOf(FContext))
912 CommonContext = &FContext;
915 if (CommonContext == &FContext ||
916 (CommonContext && CommonContext->
IsPrefixOf(FContext))) {
919 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
931 const uint8_t *FuncProfileAddr = Start + iter->second;
939 auto FuncName = FContext.
getName();
942 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
952 const uint8_t *FuncProfileAddr = Start + iter->second;
960 "Cannot have both context-sensitive and regular profile");
962 "Section flag should be consistent with actual profile");
968 ProfSymList = std::make_unique<ProfileSymbolList>();
977std::error_code SampleProfileReaderExtBinaryBase::decompressSection(
978 const uint8_t *SecStart,
const uint64_t SecSize,
979 const uint8_t *&DecompressBuf,
uint64_t &DecompressBufSize) {
981 End = SecStart + SecSize;
982 auto DecompressSize = readNumber<uint64_t>();
983 if (std::error_code EC = DecompressSize.getError())
985 DecompressBufSize = *DecompressSize;
987 auto CompressSize = readNumber<uint64_t>();
988 if (std::error_code EC = CompressSize.getError())
995 size_t UCSize = DecompressBufSize;
1000 DecompressBuf =
reinterpret_cast<const uint8_t *
>(
Buffer);
1005 const uint8_t *BufStart =
1006 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1017 const uint8_t *SecStart = BufStart + Entry.Offset;
1026 const uint8_t *DecompressBuf;
1028 if (std::error_code EC = decompressSection(
1029 SecStart, SecSize, DecompressBuf, DecompressBufSize))
1031 SecStart = DecompressBuf;
1032 SecSize = DecompressBufSize;
1035 if (std::error_code EC =
readOneSection(SecStart, SecSize, Entry))
1037 if (
Data != SecStart + SecSize)
1042 Data = BufStart + Entry.Offset;
1043 End = BufStart +
Buffer->getBufferSize();
1050std::error_code SampleProfileReaderRawBinary::verifySPMagic(
uint64_t Magic) {
1056std::error_code SampleProfileReaderExtBinary::verifySPMagic(
uint64_t Magic) {
1063 auto Size = readNumber<size_t>();
1064 if (std::error_code EC =
Size.getError())
1087 for (
size_t I = 0;
I < *
Size; ++
I) {
1089 if (std::error_code EC =
Name.getError())
1106 bool FixedLengthMD5) {
1107 if (FixedLengthMD5) {
1109 errs() <<
"If FixedLengthMD5 is true, UseMD5 has to be true";
1110 auto Size = readNumber<size_t>();
1111 if (std::error_code EC =
Size.getError())
1115 "Fixed length MD5 name table does not contain specified number of "
1135 assert(!FixedLengthMD5 &&
"FixedLengthMD5 should be unreachable here");
1136 auto Size = readNumber<size_t>();
1137 if (std::error_code EC =
Size.getError())
1145 for (
size_t I = 0;
I < *
Size; ++
I) {
1146 auto FID = readNumber<uint64_t>();
1147 if (std::error_code EC = FID.getError())
1166 auto Size = readNumber<size_t>();
1167 if (std::error_code EC =
Size.getError())
1180 for (
size_t I = 0;
I < *
Size; ++
I) {
1182 auto ContextSize = readNumber<uint32_t>();
1183 if (std::error_code EC = ContextSize.getError())
1185 for (
uint32_t J = 0; J < *ContextSize; ++J) {
1187 if (std::error_code EC = FName.getError())
1189 auto LineOffset = readNumber<uint64_t>();
1190 if (std::error_code EC = LineOffset.getError())
1194 return std::error_code();
1196 auto Discriminator = readNumber<uint64_t>();
1197 if (std::error_code EC = Discriminator.getError())
1201 FName.get(),
LineLocation(LineOffset.get(), Discriminator.get()));
1213 auto Checksum = readNumber<uint64_t>();
1214 if (std::error_code EC = Checksum.getError())
1220 if (ProfileHasAttribute) {
1222 if (std::error_code EC =
Attributes.getError())
1230 auto NumCallsites = readNumber<uint32_t>();
1231 if (std::error_code EC = NumCallsites.getError())
1234 for (
uint32_t J = 0; J < *NumCallsites; ++J) {
1235 auto LineOffset = readNumber<uint64_t>();
1236 if (std::error_code EC = LineOffset.getError())
1239 auto Discriminator = readNumber<uint64_t>();
1240 if (std::error_code EC = Discriminator.getError())
1244 if (std::error_code EC = FContextHash.getError())
1247 auto &[FContext, Hash] = *FContextHash;
1253 *Discriminator))[std::string(FContext.getName())]);
1255 if (std::error_code EC =
1269 if (std::error_code EC = FContextHash.getError())
1271 auto &[FContext, Hash] = *FContextHash;
1275 FProfile = &It->second;
1288 auto Type = readUnencodedNumber<uint64_t>();
1289 if (std::error_code EC =
Type.getError())
1291 Entry.Type =
static_cast<SecType>(*Type);
1293 auto Flags = readUnencodedNumber<uint64_t>();
1294 if (std::error_code EC = Flags.getError())
1296 Entry.Flags = *Flags;
1298 auto Offset = readUnencodedNumber<uint64_t>();
1299 if (std::error_code EC =
Offset.getError())
1303 auto Size = readUnencodedNumber<uint64_t>();
1304 if (std::error_code EC =
Size.getError())
1308 Entry.LayoutIndex =
Idx;
1314 auto EntryNum = readUnencodedNumber<uint64_t>();
1315 if (std::error_code EC = EntryNum.getError())
1318 for (
uint64_t i = 0; i < (*EntryNum); i++)
1326 const uint8_t *BufStart =
1327 reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1329 End = BufStart +
Buffer->getBufferSize();
1343 if (Entry.Type ==
Type)
1357 FileSize = std::max(Entry.Offset + Entry.Size, FileSize);
1365 Flags.append(
"{compressed,");
1370 Flags.append(
"flat,");
1372 switch (Entry.Type) {
1375 Flags.append(
"fixlenmd5,");
1377 Flags.append(
"md5,");
1379 Flags.append(
"uniq,");
1383 Flags.append(
"partial,");
1385 Flags.append(
"context,");
1387 Flags.append(
"preInlined,");
1389 Flags.append(
"fs-discriminator,");
1393 Flags.append(
"ordered,");
1397 Flags.append(
"probe,");
1399 Flags.append(
"attr,");
1404 char &last = Flags.back();
1415 OS <<
getSecName(Entry.Type) <<
" - Offset: " << Entry.Offset
1416 <<
", Size: " << Entry.Size <<
", Flags: " <<
getSecFlagsStr(Entry)
1419 TotalSecsSize += Entry.Size;
1423 "Size of 'header + sections' doesn't match the total size of profile");
1425 OS <<
"Header Size: " << HeaderSize <<
"\n";
1426 OS <<
"Total Sections Size: " << TotalSecsSize <<
"\n";
1433 auto Magic = readNumber<uint64_t>();
1434 if (std::error_code EC = Magic.getError())
1436 else if (std::error_code EC = verifySPMagic(*Magic))
1440 auto Version = readNumber<uint64_t>();
1441 if (std::error_code EC = Version.getError())
1450 Data =
reinterpret_cast<const uint8_t *
>(
Buffer->getBufferStart());
1464std::error_code SampleProfileReaderBinary::readSummaryEntry(
1465 std::vector<ProfileSummaryEntry> &Entries) {
1466 auto Cutoff = readNumber<uint64_t>();
1467 if (std::error_code EC = Cutoff.getError())
1470 auto MinBlockCount = readNumber<uint64_t>();
1471 if (std::error_code EC = MinBlockCount.getError())
1474 auto NumBlocks = readNumber<uint64_t>();
1475 if (std::error_code EC = NumBlocks.getError())
1478 Entries.emplace_back(*Cutoff, *MinBlockCount, *NumBlocks);
1483 auto TotalCount = readNumber<uint64_t>();
1484 if (std::error_code EC = TotalCount.getError())
1487 auto MaxBlockCount = readNumber<uint64_t>();
1488 if (std::error_code EC = MaxBlockCount.getError())
1491 auto MaxFunctionCount = readNumber<uint64_t>();
1492 if (std::error_code EC = MaxFunctionCount.getError())
1495 auto NumBlocks = readNumber<uint64_t>();
1496 if (std::error_code EC = NumBlocks.getError())
1499 auto NumFunctions = readNumber<uint64_t>();
1500 if (std::error_code EC = NumFunctions.getError())
1503 auto NumSummaryEntries = readNumber<uint64_t>();
1504 if (std::error_code EC = NumSummaryEntries.getError())
1507 std::vector<ProfileSummaryEntry> Entries;
1508 for (
unsigned i = 0; i < *NumSummaryEntries; i++) {
1509 std::error_code EC = readSummaryEntry(Entries);
1513 Summary = std::make_unique<ProfileSummary>(
1515 *MaxFunctionCount, *NumBlocks, *NumFunctions);
1521 const uint8_t *
Data =
1522 reinterpret_cast<const uint8_t *
>(
Buffer.getBufferStart());
1528 const uint8_t *
Data =
1529 reinterpret_cast<const uint8_t *
>(
Buffer.getBufferStart());
1545 return static_cast<T>(Val);
1546 }
else if (
sizeof(
T) <=
sizeof(
uint64_t)) {
1549 return static_cast<T>(Val);
1611 Names.push_back(std::string(Str));
1637 if (InlineStack.
size() == 0)
1656 if (InlineStack.
size() == 0) {
1704 for (
auto *CallerProfile : NewStack)
1705 CallerProfile->addTotalSamples(Count);
1714 for (
uint32_t J = 0; J < NumTargets; J++) {
1733 TargetName, TargetCount);
1774 StringRef Magic(
reinterpret_cast<const char *
>(
Buffer.getBufferStart()));
1775 return Magic ==
"adcg*704";
1784 "Profile data remapping cannot be applied to profile data "
1785 "using MD5 names (original mangled names are not available).",
1792 assert(Remappings &&
"should be initialized while creating remapper");
1795 Sample.second.findAllNames(NamesInSample);
1796 for (
auto &
Name : NamesInSample)
1797 if (
auto Key = Remappings->insert(
Name))
1798 NameMap.insert({Key,
Name});
1801 RemappingApplied =
true;
1804std::optional<StringRef>
1806 if (
auto Key = Remappings->lookup(Fname))
1807 return NameMap.lookup(Key);
1808 return std::nullopt;
1817 : FS.getBufferForFile(Filename);
1818 if (std::error_code EC = BufferOrErr.getError())
1820 auto Buffer = std::move(BufferOrErr.get());
1822 return std::move(Buffer);
1839 const std::string RemapFilename) {
1841 if (std::error_code EC = BufferOrError.getError())
1843 return create(BufferOrError.get(),
C, FS,
P, RemapFilename);
1862 if (std::error_code EC = BufferOrError.getError())
1864 return create(BufferOrError.get(), Reader,
C);
1881 auto Remappings = std::make_unique<SymbolRemappingReader>();
1882 if (
Error E = Remappings->read(*
B)) {
1892 return std::make_unique<SampleProfileReaderItaniumRemapper>(
1893 std::move(
B), std::move(Remappings), Reader);
1910 const std::string RemapFilename) {
1911 std::unique_ptr<SampleProfileReader> Reader;
1923 if (!RemapFilename.empty()) {
1925 RemapFilename, FS, *Reader,
C);
1926 if (std::error_code EC = ReaderOrErr.getError()) {
1927 std::string Msg =
"Could not create remapper: " + EC.message();
1931 Reader->Remapper = std::move(ReaderOrErr.get());
1934 if (std::error_code EC = Reader->readHeader()) {
1938 Reader->setDiscriminatorMaskedBitFrom(
P);
1940 return std::move(Reader);
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
Provides ErrorOr<T> smart pointer.
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS)
This file supports working with JSON data.
Module.h This file contains the declarations for the Module class.
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool ParseHead(const StringRef &Input, StringRef &FName, uint64_t &NumSamples, uint64_t &NumHeadSamples)
Parse Input as function head.
static void dumpFunctionProfileJson(const FunctionSamples &S, json::OStream &JOS, bool TopLevel=false)
static bool isOffsetLegal(unsigned L)
Returns true if line offset L is legal (only has 16 bits).
static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth, uint64_t &NumSamples, uint32_t &LineOffset, uint32_t &Discriminator, StringRef &CalleeName, DenseMap< StringRef, uint64_t > &TargetCountMap, uint64_t &FunctionHash, uint32_t &Attributes)
Parse Input as line sample.
static cl::opt< bool > ProfileIsFSDisciminator("profile-isfs", cl::Hidden, cl::init(false), cl::desc("Profile uses flow sensitive discriminators"))
static std::string getSecFlagsStr(const SecHdrTableEntry &Entry)
static bool parseMetadata(const StringRef &Input, uint64_t &FunctionHash, uint32_t &Attributes)
Parse Input that contains metadata.
Defines the virtual file system interface vfs::FileSystem.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
Implements a dense probed hash-table based set.
Diagnostic information for the sample profiler.
Represents either an error or a value T.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
bool readInt(uint32_t &Val)
bool readInt64(uint64_t &Val)
bool readGCOVVersion(GCOV::GCOVVersion &version)
readGCOVVersion - Read GCOV version.
bool readString(StringRef &str)
bool readGCDAFormat()
readGCDAFormat - Check GCDA signature is valid at the beginning of buffer.
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
This is an important class for using LLVM in a threaded context.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getSTDIN()
Read all of stdin into a file buffer, and return it.
static const ArrayRef< uint32_t > DefaultCutoffs
A vector of useful cutoff values for detailed summary.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr size_t size() const
size - Get the string size.
size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
bool startswith(StringRef Prefix) const
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
static constexpr size_t npos
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
int64_t getLineNum() const
StringRef getMessage() const
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
void object(Block Contents)
Emit an object whose elements are emitted in the provided Block.
void attribute(llvm::StringRef Key, const Value &Contents)
Emit an attribute whose value is self-contained (number, vector<int> etc).
void attributeArray(llvm::StringRef Key, Block Contents)
Emit an attribute whose value is an array with elements from the Block.
A forward iterator which reads text lines from a buffer.
int64_t line_number() const
Return the current line number. May return any number at EOF.
bool is_at_eof() const
Return true if we've reached EOF or are an "end" iterator.
This class implements an extremely fast bulk output stream that can only output to a stream.
Representation of the samples collected for a function.
static bool ProfileIsPreInlined
void setName(StringRef FunctionName)
Set the name of the function.
sampleprof_error addTotalSamples(uint64_t Num, uint64_t Weight=1)
uint64_t getHeadSamples() const
For top-level functions, return the total number of branch samples that have the function as the bran...
sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight=1)
FunctionSamplesMap & functionSamplesAt(const LineLocation &Loc)
Return the function samples at the given callsite location.
static bool ProfileIsProbeBased
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
sampleprof_error addBodySamples(uint32_t LineOffset, uint32_t Discriminator, uint64_t Num, uint64_t Weight=1)
void setFunctionHash(uint64_t Hash)
static bool ProfileIsFS
If this profile uses flow sensitive discriminators.
sampleprof_error addCalledTargetSamples(uint32_t LineOffset, uint32_t Discriminator, StringRef FName, uint64_t Num, uint64_t Weight=1)
SampleContext & getContext() const
static bool HasUniqSuffix
Whether the profile contains any ".__uniq." suffix in a name.
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
const CallsiteSampleMap & getCallsiteSamples() const
Return all the callsite samples collected in the body of the function.
void setContext(const SampleContext &FContext)
StringRef getName() const
Return the function name.
const BodySampleMap & getBodySamples() const
Return all the samples collected in the body of the function.
std::pair< iterator, bool > try_emplace(const key_type &Hash, const original_key_type &Key, Ts &&...Args)
StringRef getName() const
void setAllAttributes(uint32_t A)
bool IsPrefixOf(const SampleContext &That) const
iterator find(const SampleContext &Ctx)
mapped_type & Create(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.
std::vector< std::string > MD5StringBuf
If MD5 is used in NameTable section, the section saves uint64_t data.
ErrorOr< StringRef > readString()
Read a string from the profile.
std::vector< StringRef > NameTable
Function name table.
ErrorOr< T > readNumber()
Read a numeric value of type T from the profile.
const uint8_t * MD5NameMemStart
The starting address of fixed length MD5 name table section.
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.
ErrorOr< StringRef > readStringFromTable(size_t *RetIdx=nullptr)
Read a string indirectly via the name table. Optionally return the index.
std::error_code readImpl() override
Read sample profiles from the associated file.
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
std::error_code readFuncMetadata(bool ProfileHasAttribute)
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::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
bool SkipFlatProf
If SkipFlatProf is true, skip the sections with SecFlagFlat flag.
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(const std::string Filename, vfs::FileSystem &FS, SampleProfileReader &Reader, LLVMContext &C)
Create a remapper from the given remapping file.
void applyRemapping(LLVMContext &Ctx)
Apply remappings to the profile read by Reader.
std::optional< StringRef > lookUpNameInProfile(StringRef FunctionName)
Return the equivalent name in the profile for FunctionName if it exists.
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
std::error_code readImpl() override
Read sample profiles from the associated file.
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Sample-based profile reader.
bool ProfileIsPreInlined
Whether function profile contains ShouldBeInlined contexts.
SampleProfileMap & getProfiles()
Return all the profiles.
uint32_t CSProfileCount
Number of context-sensitive profiles.
void dump(raw_ostream &OS=dbgs())
Print all the profiles on stream OS.
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
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.
static ErrorOr< std::unique_ptr< SampleProfileReader > > create(const std::string Filename, LLVMContext &C, vfs::FileSystem &FS, FSDiscriminatorPass P=FSDiscriminatorPass::Base, const std::string RemapFilename="")
Create a sample profile reader appropriate to the file format.
SampleProfileMap Profiles
Map every function to its associated profile.
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.
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)
static uint64_t hashFuncName(StringRef F)
void sortFuncProfiles(const SampleProfileMap &ProfileMap, std::vector< NameFunctionSamples > &SortedProfiles)
static uint64_t SPMagic(SampleProfileFormat Format=SPF_Binary)
static bool hasSecFlag(const SecHdrTableEntry &Entry, SecFlagType Flag)
std::map< LineLocation, FunctionSamplesMap > CallsiteSampleMap
@ HIST_TYPE_INDIR_CALL_TOPN
std::map< LineLocation, SampleRecord > BodySampleMap
@ SecFlagIsPreInlined
SecFlagIsPreInlined means this profile contains ShouldBeInlined contexts thus this is CS preinliner c...
@ SecFlagPartial
SecFlagPartial means the profile is for common/shared code.
@ SecFlagFSDiscriminator
SecFlagFSDiscriminator means this profile uses flow-sensitive discriminators.
@ SecFlagFullContext
SecFlagContext means this is context-sensitive flat profile for CSSPGO.
SmallVector< SampleContextFrame, 1 > SampleContextFrameVector
static std::string getSecName(SecType Type)
static uint64_t SPVersion()
uint64_t read64le(const void *P)
void write64le(void *P, uint64_t V)
This is an optimization pass for GlobalISel generic memory operations.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
sampleprof_error MergeResult(sampleprof_error &Accumulator, sampleprof_error Result)
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
uint64_t MD5Hash(StringRef Str)
Helper to compute and return lower 64 bits of the given string's MD5 hash.
Represents the relative location of an instruction.