#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Debuginfod/HTTPClient.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Object/Binary.h"
#include "llvm/ProfileData/InstrProfCorrelator.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/ProfileData/InstrProfWriter.h"
#include "llvm/ProfileData/MemProf.h"
#include "llvm/ProfileData/MemProfReader.h"
#include "llvm/ProfileData/ProfileCommon.h"
#include "llvm/ProfileData/SampleProfReader.h"
#include "llvm/ProfileData/SampleProfWriter.h"
#include "llvm/Support/BalancedPartitioning.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Discriminator.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/LLVMDriver.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cmath>
#include <optional>
#include <queue>
usingnamespacellvm;
ProfCorrelatorKind;
cl::SubCommand ShowSubcommand(
"show",
"Takes a profile data file and displays the profiles. See detailed "
"documentation in "
"https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-show");
cl::SubCommand OrderSubcommand(
"order",
"Reads temporal profiling traces from a profile and outputs a function "
"order that reduces the number of page faults for those traces. See "
"detailed documentation in "
"https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-order");
cl::SubCommand OverlapSubcommand(
"overlap",
"Computes and displays the overlap between two profiles. See detailed "
"documentation in "
"https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-overlap");
cl::SubCommand MergeSubcommand(
"merge",
"Takes several profiles and merge them together. See detailed "
"documentation in "
"https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge");
namespace {
enum ProfileKinds { … };
enum FailureMode { … };
enum ProfileFormat { … };
enum class ShowFormat { … };
}
cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
cl::init("-"), cl::desc("Output file"),
cl::sub(ShowSubcommand),
cl::sub(OrderSubcommand),
cl::sub(OverlapSubcommand),
cl::sub(MergeSubcommand));
cl::alias OutputFilenameA("o", cl::desc("Alias for --output"),
cl::aliasopt(OutputFilename));
cl::opt<ProfileKinds> ProfileKind(
cl::desc("Profile kind:"), cl::sub(MergeSubcommand),
cl::sub(OverlapSubcommand), cl::init(instr),
cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
clEnumVal(sample, "Sample profile")));
cl::opt<std::string> Filename(cl::Positional, cl::desc("<profdata-file>"),
cl::sub(ShowSubcommand),
cl::sub(OrderSubcommand));
cl::opt<unsigned> MaxDbgCorrelationWarnings(
"max-debug-info-correlation-warnings",
cl::desc("The maximum number of warnings to emit when correlating "
"profile from debug info (0 = no limit)"),
cl::sub(MergeSubcommand), cl::sub(ShowSubcommand), cl::init(5));
cl::opt<std::string> ProfiledBinary(
"profiled-binary", cl::init(""),
cl::desc("Path to binary from which the profile was collected."),
cl::sub(ShowSubcommand), cl::sub(MergeSubcommand));
cl::opt<std::string> DebugInfoFilename(
"debug-info", cl::init(""),
cl::desc(
"For show, read and extract profile metadata from debug info and show "
"the functions it found. For merge, use the provided debug info to "
"correlate the raw profile."),
cl::sub(ShowSubcommand), cl::sub(MergeSubcommand));
cl::opt<std::string>
BinaryFilename("binary-file", cl::init(""),
cl::desc("For merge, use the provided unstripped bianry to "
"correlate the raw profile."),
cl::sub(MergeSubcommand));
cl::list<std::string> DebugFileDirectory(
"debug-file-directory",
cl::desc("Directories to search for object files by build ID"));
cl::opt<bool> DebugInfod("debuginfod", cl::init(false), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc("Enable debuginfod"));
cl::opt<ProfCorrelatorKind> BIDFetcherProfileCorrelate(
"correlate",
cl::desc("Use debug-info or binary correlation to correlate profiles with "
"build id fetcher"),
cl::init(InstrProfCorrelator::NONE),
cl::values(clEnumValN(InstrProfCorrelator::NONE, "",
"No profile correlation"),
clEnumValN(InstrProfCorrelator::DEBUG_INFO, "debug-info",
"Use debug info to correlate"),
clEnumValN(InstrProfCorrelator::BINARY, "binary",
"Use binary to correlate")));
cl::opt<std::string> FuncNameFilter(
"function",
cl::desc("Only functions matching the filter are shown in the output. For "
"overlapping CSSPGO, this takes a function name with calling "
"context."),
cl::sub(ShowSubcommand), cl::sub(OverlapSubcommand),
cl::sub(MergeSubcommand));
cl::list<std::string> InputFilenames(cl::Positional, cl::sub(MergeSubcommand),
cl::desc("<filename...>"));
cl::list<std::string> WeightedInputFilenames("weighted-input",
cl::sub(MergeSubcommand),
cl::desc("<weight>,<filename>"));
cl::opt<ProfileFormat> OutputFormat(
cl::desc("Format of output profile"), cl::sub(MergeSubcommand),
cl::init(PF_Ext_Binary),
cl::values(clEnumValN(PF_Binary, "binary", "Binary encoding"),
clEnumValN(PF_Ext_Binary, "extbinary",
"Extensible binary encoding "
"(default)"),
clEnumValN(PF_Text, "text", "Text encoding"),
clEnumValN(PF_GCC, "gcc",
"GCC encoding (only meaningful for -sample)")));
cl::opt<std::string>
InputFilenamesFile("input-files", cl::init(""), cl::sub(MergeSubcommand),
cl::desc("Path to file containing newline-separated "
"[<weight>,]<filename> entries"));
cl::alias InputFilenamesFileA("f", cl::desc("Alias for --input-files"),
cl::aliasopt(InputFilenamesFile));
cl::opt<bool> DumpInputFileList(
"dump-input-file-list", cl::init(false), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc("Dump the list of input files and their weights, then exit"));
cl::opt<std::string> RemappingFile("remapping-file", cl::value_desc("file"),
cl::sub(MergeSubcommand),
cl::desc("Symbol remapping file"));
cl::alias RemappingFileA("r", cl::desc("Alias for --remapping-file"),
cl::aliasopt(RemappingFile));
cl::opt<bool>
UseMD5("use-md5", cl::init(false), cl::Hidden,
cl::desc("Choose to use MD5 to represent string in name table (only "
"meaningful for -extbinary)"),
cl::sub(MergeSubcommand));
cl::opt<bool> CompressAllSections(
"compress-all-sections", cl::init(false), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc("Compress all sections when writing the profile (only "
"meaningful for -extbinary)"));
cl::opt<bool> SampleMergeColdContext(
"sample-merge-cold-context", cl::init(false), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc(
"Merge context sample profiles whose count is below cold threshold"));
cl::opt<bool> SampleTrimColdContext(
"sample-trim-cold-context", cl::init(false), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc(
"Trim context sample profiles whose count is below cold threshold"));
cl::opt<uint32_t> SampleColdContextFrameDepth(
"sample-frame-depth-for-cold-context", cl::init(1),
cl::sub(MergeSubcommand),
cl::desc("Keep the last K frames while merging cold profile. 1 means the "
"context-less base profile"));
cl::opt<size_t> OutputSizeLimit(
"output-size-limit", cl::init(0), cl::Hidden, cl::sub(MergeSubcommand),
cl::desc("Trim cold functions until profile size is below specified "
"limit in bytes. This uses a heursitic and functions may be "
"excessively trimmed"));
cl::opt<bool> GenPartialProfile(
"gen-partial-profile", cl::init(false), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc("Generate a partial profile (only meaningful for -extbinary)"));
cl::opt<bool> SplitLayout(
"split-layout", cl::init(false), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc("Split the profile to two sections with one containing sample "
"profiles with inlined functions and the other without (only "
"meaningful for -extbinary)"));
cl::opt<std::string> SupplInstrWithSample(
"supplement-instr-with-sample", cl::init(""), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc("Supplement an instr profile with sample profile, to correct "
"the profile unrepresentativeness issue. The sample "
"profile is the input of the flag. Output will be in instr "
"format (The flag only works with -instr)"));
cl::opt<float> ZeroCounterThreshold(
"zero-counter-threshold", cl::init(0.7), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc("For the function which is cold in instr profile but hot in "
"sample profile, if the ratio of the number of zero counters "
"divided by the total number of counters is above the "
"threshold, the profile of the function will be regarded as "
"being harmful for performance and will be dropped."));
cl::opt<unsigned> SupplMinSizeThreshold(
"suppl-min-size-threshold", cl::init(10), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc("If the size of a function is smaller than the threshold, "
"assume it can be inlined by PGO early inliner and it won't "
"be adjusted based on sample profile."));
cl::opt<unsigned> InstrProfColdThreshold(
"instr-prof-cold-threshold", cl::init(0), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc("User specified cold threshold for instr profile which will "
"override the cold threshold got from profile summary. "));
cl::opt<uint64_t> TemporalProfTraceReservoirSize(
"temporal-profile-trace-reservoir-size", cl::init(100),
cl::sub(MergeSubcommand),
cl::desc("The maximum number of stored temporal profile traces (default: "
"100)"));
cl::opt<uint64_t> TemporalProfMaxTraceLength(
"temporal-profile-max-trace-length", cl::init(10000),
cl::sub(MergeSubcommand),
cl::desc("The maximum length of a single temporal profile trace "
"(default: 10000)"));
cl::opt<std::string> FuncNameNegativeFilter(
"no-function", cl::init(""),
cl::sub(MergeSubcommand),
cl::desc("Exclude functions matching the filter from the output."));
cl::opt<FailureMode>
FailMode("failure-mode", cl::init(failIfAnyAreInvalid),
cl::desc("Failure mode:"), cl::sub(MergeSubcommand),
cl::values(clEnumValN(warnOnly, "warn",
"Do not fail and just print warnings."),
clEnumValN(failIfAnyAreInvalid, "any",
"Fail if any profile is invalid."),
clEnumValN(failIfAllAreInvalid, "all",
"Fail only if all profiles are invalid.")));
cl::opt<bool> OutputSparse(
"sparse", cl::init(false), cl::sub(MergeSubcommand),
cl::desc("Generate a sparse profile (only meaningful for -instr)"));
cl::opt<unsigned> NumThreads(
"num-threads", cl::init(0), cl::sub(MergeSubcommand),
cl::desc("Number of merge threads to use (default: autodetect)"));
cl::alias NumThreadsA("j", cl::desc("Alias for --num-threads"),
cl::aliasopt(NumThreads));
cl::opt<std::string> ProfileSymbolListFile(
"prof-sym-list", cl::init(""), cl::sub(MergeSubcommand),
cl::desc("Path to file containing the list of function symbols "
"used to populate profile symbol list"));
cl::opt<SampleProfileLayout> ProfileLayout(
"convert-sample-profile-layout",
cl::desc("Convert the generated profile to a profile with a new layout"),
cl::sub(MergeSubcommand), cl::init(SPL_None),
cl::values(
clEnumValN(SPL_Nest, "nest",
"Nested profile, the input should be CS flat profile"),
clEnumValN(SPL_Flat, "flat",
"Profile with nested inlinee flatten out")));
cl::opt<bool> DropProfileSymbolList(
"drop-profile-symbol-list", cl::init(false), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc("Drop the profile symbol list when merging AutoFDO profiles "
"(only meaningful for -sample)"));
cl::opt<bool> KeepVTableSymbols(
"keep-vtable-symbols", cl::init(false), cl::Hidden,
cl::sub(MergeSubcommand),
cl::desc("If true, keep the vtable symbols in indexed profiles"));
cl::opt<bool> DoWritePrevVersion(
"write-prev-version", cl::init(false), cl::Hidden,
cl::desc("Write the previous version of indexed format, to enable "
"some forward compatibility."));
cl::opt<memprof::IndexedVersion> MemProfVersionRequested(
"memprof-version", cl::Hidden, cl::sub(MergeSubcommand),
cl::desc("Specify the version of the memprof format to use"),
cl::init(memprof::Version0),
cl::values(clEnumValN(memprof::Version0, "0", "version 0"),
clEnumValN(memprof::Version1, "1", "version 1"),
clEnumValN(memprof::Version2, "2", "version 2"),
clEnumValN(memprof::Version3, "3", "version 3")));
cl::opt<bool> MemProfFullSchema(
"memprof-full-schema", cl::Hidden, cl::sub(MergeSubcommand),
cl::desc("Use the full schema for serialization"), cl::init(false));
cl::opt<std::string> BaseFilename(cl::Positional, cl::Required,
cl::desc("<base profile file>"),
cl::sub(OverlapSubcommand));
cl::opt<std::string> TestFilename(cl::Positional, cl::Required,
cl::desc("<test profile file>"),
cl::sub(OverlapSubcommand));
cl::opt<unsigned long long> SimilarityCutoff(
"similarity-cutoff", cl::init(0),
cl::desc("For sample profiles, list function names (with calling context "
"for csspgo) for overlapped functions "
"with similarities below the cutoff (percentage times 10000)."),
cl::sub(OverlapSubcommand));
cl::opt<bool> IsCS(
"cs", cl::init(false),
cl::desc("For context sensitive PGO counts. Does not work with CSSPGO."),
cl::sub(OverlapSubcommand));
cl::opt<unsigned long long> OverlapValueCutoff(
"value-cutoff", cl::init(-1),
cl::desc(
"Function level overlap information for every function (with calling "
"context for csspgo) in test "
"profile with max count value greater then the parameter value"),
cl::sub(OverlapSubcommand));
cl::opt<bool> ShowCounts("counts", cl::init(false),
cl::desc("Show counter values for shown functions"),
cl::sub(ShowSubcommand));
cl::opt<ShowFormat>
SFormat("show-format", cl::init(ShowFormat::Text),
cl::desc("Emit output in the selected format if supported"),
cl::sub(ShowSubcommand),
cl::values(clEnumValN(ShowFormat::Text, "text",
"emit normal text output (default)"),
clEnumValN(ShowFormat::Json, "json", "emit JSON"),
clEnumValN(ShowFormat::Yaml, "yaml", "emit YAML")));
cl::opt<bool>
TextFormat("text", cl::init(false),
cl::desc("Show instr profile data in text dump format"),
cl::sub(ShowSubcommand));
cl::opt<bool>
JsonFormat("json",
cl::desc("Show sample profile data in the JSON format "
"(deprecated, please use --show-format=json)"),
cl::sub(ShowSubcommand));
cl::opt<bool> ShowIndirectCallTargets(
"ic-targets", cl::init(false),
cl::desc("Show indirect call site target values for shown functions"),
cl::sub(ShowSubcommand));
cl::opt<bool> ShowVTables("show-vtables", cl::init(false),
cl::desc("Show vtable names for shown functions"),
cl::sub(ShowSubcommand));
cl::opt<bool> ShowMemOPSizes(
"memop-sizes", cl::init(false),
cl::desc("Show the profiled sizes of the memory intrinsic calls "
"for shown functions"),
cl::sub(ShowSubcommand));
cl::opt<bool> ShowDetailedSummary("detailed-summary", cl::init(false),
cl::desc("Show detailed profile summary"),
cl::sub(ShowSubcommand));
cl::list<uint32_t> DetailedSummaryCutoffs(
cl::CommaSeparated, "detailed-summary-cutoffs",
cl::desc(
"Cutoff percentages (times 10000) for generating detailed summary"),
cl::value_desc("800000,901000,999999"), cl::sub(ShowSubcommand));
cl::opt<bool>
ShowHotFuncList("hot-func-list", cl::init(false),
cl::desc("Show profile summary of a list of hot functions"),
cl::sub(ShowSubcommand));
cl::opt<bool> ShowAllFunctions("all-functions", cl::init(false),
cl::desc("Details for each and every function"),
cl::sub(ShowSubcommand));
cl::opt<bool> ShowCS("showcs", cl::init(false),
cl::desc("Show context sensitive counts"),
cl::sub(ShowSubcommand));
cl::opt<ProfileKinds> ShowProfileKind(
cl::desc("Profile kind supported by show:"), cl::sub(ShowSubcommand),
cl::init(instr),
cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
clEnumVal(sample, "Sample profile"),
clEnumVal(memory, "MemProf memory access profile")));
cl::opt<uint32_t> TopNFunctions(
"topn", cl::init(0),
cl::desc("Show the list of functions with the largest internal counts"),
cl::sub(ShowSubcommand));
cl::opt<uint32_t> ShowValueCutoff(
"value-cutoff", cl::init(0),
cl::desc("Set the count value cutoff. Functions with the maximum count "
"less than this value will not be printed out. (Default is 0)"),
cl::sub(ShowSubcommand));
cl::opt<bool> OnlyListBelow(
"list-below-cutoff", cl::init(false),
cl::desc("Only output names of functions whose max count values are "
"below the cutoff value"),
cl::sub(ShowSubcommand));
cl::opt<bool> ShowProfileSymbolList(
"show-prof-sym-list", cl::init(false),
cl::desc("Show profile symbol list if it exists in the profile. "),
cl::sub(ShowSubcommand));
cl::opt<bool> ShowSectionInfoOnly(
"show-sec-info-only", cl::init(false),
cl::desc("Show the information of each section in the sample profile. "
"The flag is only usable when the sample profile is in "
"extbinary format"),
cl::sub(ShowSubcommand));
cl::opt<bool> ShowBinaryIds("binary-ids", cl::init(false),
cl::desc("Show binary ids in the profile. "),
cl::sub(ShowSubcommand));
cl::opt<bool> ShowTemporalProfTraces(
"temporal-profile-traces",
cl::desc("Show temporal profile traces in the profile."),
cl::sub(ShowSubcommand));
cl::opt<bool>
ShowCovered("covered", cl::init(false),
cl::desc("Show only the functions that have been executed."),
cl::sub(ShowSubcommand));
cl::opt<bool> ShowProfileVersion("profile-version", cl::init(false),
cl::desc("Show profile version. "),
cl::sub(ShowSubcommand));
cl::opt<unsigned>
NumTestTraces("num-test-traces", cl::init(0),
cl::desc("Keep aside the last <num-test-traces> traces in "
"the profile when computing the function order and "
"instead use them to evaluate that order"),
cl::sub(OrderSubcommand));
const std::string DuplicateNameStr = …;
static void warn(Twine Message, StringRef Whence = "", StringRef Hint = "") { … }
static void warn(Error E, StringRef Whence = "") { … }
static void exitWithError(Twine Message, StringRef Whence = "",
StringRef Hint = "") { … }
static void exitWithError(Error E, StringRef Whence = "") { … }
static void exitWithErrorCode(std::error_code EC, StringRef Whence = "") { … }
static void warnOrExitGivenError(FailureMode FailMode, std::error_code EC,
StringRef Whence = "") { … }
static void handleMergeWriterError(Error E, StringRef WhenceFile = "",
StringRef WhenceFunction = "",
bool ShowHint = true) { … }
namespace {
class SymbolRemapper { … };
}
struct WeightedFile { … };
WeightedFileVector;
struct WriterContext { … };
static void overlapInput(const std::string &BaseFilename,
const std::string &TestFilename, WriterContext *WC,
OverlapStats &Overlap,
const OverlapFuncFilters &FuncFilter,
raw_fd_ostream &OS, bool IsCS) { … }
static void
loadInput(const WeightedFile &Input, SymbolRemapper *Remapper,
const InstrProfCorrelator *Correlator, const StringRef ProfiledBinary,
WriterContext *WC, const object::BuildIDFetcher *BIDFetcher = nullptr,
const ProfCorrelatorKind *BIDFetcherCorrelatorKind = nullptr) { … }
static void mergeWriterContexts(WriterContext *Dst, WriterContext *Src) { … }
static StringRef
getFuncName(const StringMap<InstrProfWriter::ProfilingData>::value_type &Val) { … }
static std::string
getFuncName(const SampleProfileMap::value_type &Val) { … }
template <typename T>
static void filterFunctions(T &ProfileMap) { … }
static void writeInstrProfile(StringRef OutputFilename,
ProfileFormat OutputFormat,
InstrProfWriter &Writer) { … }
static void mergeInstrProfile(const WeightedFileVector &Inputs,
SymbolRemapper *Remapper,
int MaxDbgCorrelationWarnings,
const StringRef ProfiledBinary) { … }
struct InstrProfileEntry { … };
InstrProfileEntry::InstrProfileEntry(InstrProfRecord *Record) { … }
static void updateInstrProfileEntry(InstrProfileEntry &IFE, bool SetToHot,
uint64_t HotInstrThreshold,
uint64_t ColdInstrThreshold,
float ZeroCounterThreshold) { … }
const uint64_t ColdPercentileIdx = …;
const uint64_t HotPercentileIdx = …;
FSDiscriminatorPass;
static cl::opt<FSDiscriminatorPass> FSDiscriminatorPassOption(
"fs-discriminator-pass", cl::init(PassLast), cl::Hidden,
cl::desc("Zero out the discriminator bits for the FS discrimiantor "
"pass beyond this value. The enum values are defined in "
"Support/Discriminator.h"),
cl::values(clEnumVal(Base, "Use base discriminators only"),
clEnumVal(Pass1, "Use base and pass 1 discriminators"),
clEnumVal(Pass2, "Use base and pass 1-2 discriminators"),
clEnumVal(Pass3, "Use base and pass 1-3 discriminators"),
clEnumVal(PassLast, "Use all discriminator bits (default)")));
static unsigned getDiscriminatorMask() { … }
static void
adjustInstrProfile(std::unique_ptr<WriterContext> &WC,
std::unique_ptr<sampleprof::SampleProfileReader> &Reader,
unsigned SupplMinSizeThreshold, float ZeroCounterThreshold,
unsigned InstrProfColdThreshold) { … }
static void supplementInstrProfile(const WeightedFileVector &Inputs,
StringRef SampleFilename, bool OutputSparse,
unsigned SupplMinSizeThreshold,
float ZeroCounterThreshold,
unsigned InstrProfColdThreshold) { … }
static sampleprof::FunctionSamples
remapSamples(const sampleprof::FunctionSamples &Samples,
SymbolRemapper &Remapper, sampleprof_error &Error) { … }
static sampleprof::SampleProfileFormat FormatMap[] = …;
static std::unique_ptr<MemoryBuffer>
getInputFileBuf(const StringRef &InputFile) { … }
static void populateProfileSymbolList(MemoryBuffer *Buffer,
sampleprof::ProfileSymbolList &PSL) { … }
static void handleExtBinaryWriter(sampleprof::SampleProfileWriter &Writer,
ProfileFormat OutputFormat,
MemoryBuffer *Buffer,
sampleprof::ProfileSymbolList &WriterList,
bool CompressAllSections, bool UseMD5,
bool GenPartialProfile) { … }
static void mergeSampleProfile(const WeightedFileVector &Inputs,
SymbolRemapper *Remapper,
StringRef ProfileSymbolListFile,
size_t OutputSizeLimit) { … }
static WeightedFile parseWeightedFile(const StringRef &WeightedFilename) { … }
static void addWeightedInput(WeightedFileVector &WNI, const WeightedFile &WF) { … }
static void parseInputFilenamesFile(MemoryBuffer *Buffer,
WeightedFileVector &WFV) { … }
static int merge_main(StringRef ProgName) { … }
static void overlapInstrProfile(const std::string &BaseFilename,
const std::string &TestFilename,
const OverlapFuncFilters &FuncFilter,
raw_fd_ostream &OS, bool IsCS) { … }
namespace {
struct SampleOverlapStats { … };
}
namespace {
struct FuncSampleStats { … };
}
namespace {
enum MatchStatus { … };
template <class T> class MatchStep { … };
}
template <class T> void MatchStep<T>::updateOneStep() { … }
static void getFuncSampleStats(const sampleprof::FunctionSamples &Func,
FuncSampleStats &FuncStats,
uint64_t HotThreshold) { … }
static bool isFunctionHot(const FuncSampleStats &FuncStats,
uint64_t HotThreshold) { … }
namespace {
class SampleOverlapAggregator { … };
}
bool SampleOverlapAggregator::detectZeroSampleProfile(
raw_fd_ostream &OS) const { … }
double SampleOverlapAggregator::computeBlockSimilarity(
uint64_t BaseSample, uint64_t TestSample,
const SampleOverlapStats &FuncOverlap) const { … }
void SampleOverlapAggregator::updateHotBlockOverlap(uint64_t BaseSample,
uint64_t TestSample,
uint64_t HotBlockCount) { … }
void SampleOverlapAggregator::getHotFunctions(
const FuncSampleStatsMap &ProfStats, FuncSampleStatsMap &HotFunc,
uint64_t HotThreshold) const { … }
void SampleOverlapAggregator::computeHotFuncOverlap() { … }
void SampleOverlapAggregator::updateOverlapStatsForFunction(
uint64_t BaseSample, uint64_t TestSample, uint64_t HotBlockCount,
SampleOverlapStats &FuncOverlap, double &Difference, MatchStatus Status) { … }
void SampleOverlapAggregator::updateForUnmatchedCallee(
const sampleprof::FunctionSamples &Func, SampleOverlapStats &FuncOverlap,
double &Difference, MatchStatus Status) { … }
double SampleOverlapAggregator::computeSampleFunctionInternalOverlap(
const sampleprof::FunctionSamples &BaseFunc,
const sampleprof::FunctionSamples &TestFunc,
SampleOverlapStats &FuncOverlap) { … }
double SampleOverlapAggregator::weightForFuncSimilarity(
double FuncInternalSimilarity, uint64_t BaseFuncSample,
uint64_t TestFuncSample) const { … }
double
SampleOverlapAggregator::weightByImportance(double FuncSimilarity,
uint64_t BaseFuncSample,
uint64_t TestFuncSample) const { … }
double SampleOverlapAggregator::computeSampleFunctionOverlap(
const sampleprof::FunctionSamples *BaseFunc,
const sampleprof::FunctionSamples *TestFunc,
SampleOverlapStats *FuncOverlap, uint64_t BaseFuncSample,
uint64_t TestFuncSample) { … }
void SampleOverlapAggregator::computeSampleProfileOverlap(raw_fd_ostream &OS) { … }
void SampleOverlapAggregator::initializeSampleProfileOverlap() { … }
void SampleOverlapAggregator::dumpFuncSimilarity(raw_fd_ostream &OS) const { … }
void SampleOverlapAggregator::dumpProgramSummary(raw_fd_ostream &OS) const { … }
void SampleOverlapAggregator::dumpHotFuncAndBlockOverlap(
raw_fd_ostream &OS) const { … }
std::error_code SampleOverlapAggregator::loadProfiles() { … }
void overlapSampleProfile(const std::string &BaseFilename,
const std::string &TestFilename,
const OverlapFuncFilters &FuncFilter,
uint64_t SimilarityCutoff, raw_fd_ostream &OS) { … }
static int overlap_main() { … }
namespace {
struct ValueSitesStats { … };
}
static void traverseAllValueSites(const InstrProfRecord &Func, uint32_t VK,
ValueSitesStats &Stats, raw_fd_ostream &OS,
InstrProfSymtab *Symtab) { … }
static void showValueSitesStats(raw_fd_ostream &OS, uint32_t VK,
ValueSitesStats &Stats) { … }
static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) { … }
static void showSectionInfo(sampleprof::SampleProfileReader *Reader,
raw_fd_ostream &OS) { … }
namespace {
struct HotFuncInfo { … };
}
static void dumpHotFunctionList(const std::vector<std::string> &ColumnTitle,
const std::vector<int> &ColumnOffset,
const std::vector<HotFuncInfo> &PrintValues,
uint64_t HotFuncCount, uint64_t TotalFuncCount,
uint64_t HotProfCount, uint64_t TotalProfCount,
const std::string &HotFuncMetric,
uint32_t TopNFunctions, raw_fd_ostream &OS) { … }
static int showHotFunctionList(const sampleprof::SampleProfileMap &Profiles,
ProfileSummary &PS, uint32_t TopN,
raw_fd_ostream &OS) { … }
static int showSampleProfile(ShowFormat SFormat, raw_fd_ostream &OS) { … }
static int showMemProfProfile(ShowFormat SFormat, raw_fd_ostream &OS) { … }
static int showDebugInfoCorrelation(const std::string &Filename,
ShowFormat SFormat, raw_fd_ostream &OS) { … }
static int show_main(StringRef ProgName) { … }
static int order_main() { … }
int llvm_profdata_main(int argc, char **argvNonConst,
const llvm::ToolContext &) { … }