#include "ProfileGenerator.h"
#include "ErrorHandling.h"
#include "MissingFrameInferrer.h"
#include "PerfReader.h"
#include "ProfiledBinary.h"
#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
#include "llvm/ProfileData/ProfileCommon.h"
#include <algorithm>
#include <float.h>
#include <unordered_set>
#include <utility>
cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
cl::Required,
cl::desc("Output profile file"));
static cl::alias OutputA("o", cl::desc("Alias for --output"),
cl::aliasopt(OutputFilename));
static cl::opt<SampleProfileFormat> OutputFormat(
"format", cl::desc("Format of output profile"), cl::init(SPF_Ext_Binary),
cl::values(
clEnumValN(SPF_Binary, "binary", "Binary encoding (default)"),
clEnumValN(SPF_Ext_Binary, "extbinary", "Extensible binary encoding"),
clEnumValN(SPF_Text, "text", "Text encoding"),
clEnumValN(SPF_GCC, "gcc",
"GCC encoding (only meaningful for -sample)")));
static cl::opt<bool> UseMD5(
"use-md5", cl::Hidden,
cl::desc("Use md5 to represent function names in the output profile (only "
"meaningful for -extbinary)"));
static cl::opt<bool> PopulateProfileSymbolList(
"populate-profile-symbol-list", cl::init(false), cl::Hidden,
cl::desc("Populate profile symbol list (only meaningful for -extbinary)"));
static cl::opt<bool> FillZeroForAllFuncs(
"fill-zero-for-all-funcs", cl::init(false), cl::Hidden,
cl::desc("Attribute all functions' range with zero count "
"even it's not hit by any samples."));
static cl::opt<int32_t, true> RecursionCompression(
"compress-recursion",
cl::desc("Compressing recursion by deduplicating adjacent frame "
"sequences up to the specified size. -1 means no size limit."),
cl::Hidden,
cl::location(llvm::sampleprof::CSProfileGenerator::MaxCompressionSize));
static cl::opt<bool>
TrimColdProfile("trim-cold-profile",
cl::desc("If the total count of the profile is smaller "
"than threshold, it will be trimmed."));
static cl::opt<bool> CSProfMergeColdContext(
"csprof-merge-cold-context", cl::init(true),
cl::desc("If the total count of context profile is smaller than "
"the threshold, it will be merged into context-less base "
"profile."));
static cl::opt<uint32_t> CSProfMaxColdContextDepth(
"csprof-max-cold-context-depth", cl::init(1),
cl::desc("Keep the last K contexts while merging cold profile. 1 means the "
"context-less base profile"));
static cl::opt<int, true> CSProfMaxContextDepth(
"csprof-max-context-depth",
cl::desc("Keep the last K contexts while merging profile. -1 means no "
"depth limit."),
cl::location(llvm::sampleprof::CSProfileGenerator::MaxContextDepth));
static cl::opt<double> ProfileDensityThreshold(
"profile-density-threshold", llvm::cl::init(50),
llvm::cl::desc("If the profile density is below the given threshold, it "
"will be suggested to increase the sampling rate."),
llvm::cl::Optional);
static cl::opt<bool> ShowDensity("show-density", llvm::cl::init(false),
llvm::cl::desc("show profile density details"),
llvm::cl::Optional);
static cl::opt<int> ProfileDensityCutOffHot(
"profile-density-cutoff-hot", llvm::cl::init(990000),
llvm::cl::desc("Total samples cutoff for functions used to calculate "
"profile density."));
static cl::opt<bool> UpdateTotalSamples(
"update-total-samples", llvm::cl::init(false),
llvm::cl::desc(
"Update total samples by accumulating all its body samples."),
llvm::cl::Optional);
static cl::opt<bool> GenCSNestedProfile(
"gen-cs-nested-profile", cl::Hidden, cl::init(true),
cl::desc("Generate nested function profiles for CSSPGO"));
cl::opt<bool> InferMissingFrames(
"infer-missing-frames", llvm::cl::init(true),
llvm::cl::desc(
"Infer missing call frames due to compiler tail call elimination."),
llvm::cl::Optional);
usingnamespacellvm;
usingnamespacesampleprof;
namespace llvm {
extern cl::opt<int> ProfileSummaryCutoffHot;
extern cl::opt<bool> UseContextLessSummary;
namespace sampleprof {
int32_t CSProfileGenerator::MaxCompressionSize = …;
int CSProfileGenerator::MaxContextDepth = …;
bool ProfileGeneratorBase::UseFSDiscriminator = …;
std::unique_ptr<ProfileGeneratorBase>
ProfileGeneratorBase::create(ProfiledBinary *Binary,
const ContextSampleCounterMap *SampleCounters,
bool ProfileIsCS) { … }
std::unique_ptr<ProfileGeneratorBase>
ProfileGeneratorBase::create(ProfiledBinary *Binary, SampleProfileMap &Profiles,
bool ProfileIsCS) { … }
void ProfileGeneratorBase::write(std::unique_ptr<SampleProfileWriter> Writer,
SampleProfileMap &ProfileMap) { … }
void ProfileGeneratorBase::write() { … }
void ProfileGeneratorBase::showDensitySuggestion(double Density) { … }
bool ProfileGeneratorBase::filterAmbiguousProfile(FunctionSamples &FS) { … }
void ProfileGeneratorBase::filterAmbiguousProfile(SampleProfileMap &Profiles) { … }
void ProfileGeneratorBase::findDisjointRanges(RangeSample &DisjointRanges,
const RangeSample &Ranges) { … }
void ProfileGeneratorBase::updateBodySamplesforFunctionProfile(
FunctionSamples &FunctionProfile, const SampleContextFrame &LeafLoc,
uint64_t Count) { … }
void ProfileGeneratorBase::updateTotalSamples() { … }
void ProfileGeneratorBase::updateCallsiteSamples() { … }
void ProfileGeneratorBase::updateFunctionSamples() { … }
void ProfileGeneratorBase::collectProfiledFunctions() { … }
bool ProfileGeneratorBase::collectFunctionsFromRawProfile(
std::unordered_set<const BinaryFunction *> &ProfiledFunctions) { … }
bool ProfileGenerator::collectFunctionsFromLLVMProfile(
std::unordered_set<const BinaryFunction *> &ProfiledFunctions) { … }
bool CSProfileGenerator::collectFunctionsFromLLVMProfile(
std::unordered_set<const BinaryFunction *> &ProfiledFunctions) { … }
FunctionSamples &
ProfileGenerator::getTopLevelFunctionProfile(FunctionId FuncName) { … }
void ProfileGenerator::generateProfile() { … }
void ProfileGenerator::postProcessProfiles() { … }
void ProfileGenerator::trimColdProfiles(const SampleProfileMap &Profiles,
uint64_t ColdCntThreshold) { … }
void ProfileGenerator::generateLineNumBasedProfile() { … }
void ProfileGenerator::generateProbeBasedProfile() { … }
void ProfileGenerator::populateBodySamplesWithProbesForAllFunctions(
const RangeSample &RangeCounter) { … }
void ProfileGenerator::populateBoundarySamplesWithProbesForAllFunctions(
const BranchSample &BranchCounters) { … }
FunctionSamples &ProfileGenerator::getLeafProfileAndAddTotalSamples(
const SampleContextFrameVector &FrameVec, uint64_t Count) { … }
RangeSample
ProfileGenerator::preprocessRangeCounter(const RangeSample &RangeCounter) { … }
void ProfileGenerator::populateBodySamplesForAllFunctions(
const RangeSample &RangeCounter) { … }
StringRef
ProfileGeneratorBase::getCalleeNameForAddress(uint64_t TargetAddress) { … }
void ProfileGenerator::populateBoundarySamplesForAllFunctions(
const BranchSample &BranchCounters) { … }
void ProfileGeneratorBase::calculateBodySamplesAndSize(
const FunctionSamples &FSamples, uint64_t &TotalBodySamples,
uint64_t &FuncBodySize) { … }
double
ProfileGeneratorBase::calculateDensity(const SampleProfileMap &Profiles) { … }
void ProfileGeneratorBase::calculateAndShowDensity(
const SampleProfileMap &Profiles) { … }
FunctionSamples *
CSProfileGenerator::getOrCreateFunctionSamples(ContextTrieNode *ContextNode,
bool WasLeafInlined) { … }
ContextTrieNode *
CSProfileGenerator::getOrCreateContextNode(const SampleContextFrames Context,
bool WasLeafInlined) { … }
void CSProfileGenerator::generateProfile() { … }
void CSProfileGenerator::initializeMissingFrameInferrer() { … }
void CSProfileGenerator::inferMissingFrames(
const SmallVectorImpl<uint64_t> &Context,
SmallVectorImpl<uint64_t> &NewContext) { … }
void CSProfileGenerator::computeSizeForProfiledFunctions() { … }
void CSProfileGenerator::updateFunctionSamples() { … }
void CSProfileGenerator::generateLineNumBasedProfile() { … }
void CSProfileGenerator::populateBodySamplesForFunction(
FunctionSamples &FunctionProfile, const RangeSample &RangeCounter) { … }
void CSProfileGenerator::populateBoundarySamplesForFunction(
ContextTrieNode *Node, const BranchSample &BranchCounters) { … }
void CSProfileGenerator::populateInferredFunctionSamples(
ContextTrieNode &Node) { … }
void CSProfileGenerator::convertToProfileMap(
ContextTrieNode &Node, SampleContextFrameVector &Context) { … }
void CSProfileGenerator::convertToProfileMap() { … }
void CSProfileGenerator::postProcessProfiles() { … }
void ProfileGeneratorBase::computeSummaryAndThreshold(
SampleProfileMap &Profiles) { … }
void CSProfileGenerator::computeSummaryAndThreshold() { … }
void ProfileGeneratorBase::extractProbesFromRange(
const RangeSample &RangeCounter, ProbeCounterMap &ProbeCounter,
bool FindDisjointRanges) { … }
static void extractPrefixContextStack(SampleContextFrameVector &ContextStack,
const SmallVectorImpl<uint64_t> &AddrVec,
ProfiledBinary *Binary) { … }
void CSProfileGenerator::generateProbeBasedProfile() { … }
void CSProfileGenerator::populateBodySamplesWithProbes(
const RangeSample &RangeCounter, const AddrBasedCtxKey *CtxKey) { … }
void CSProfileGenerator::populateBoundarySamplesWithProbes(
const BranchSample &BranchCounter, const AddrBasedCtxKey *CtxKey) { … }
ContextTrieNode *CSProfileGenerator::getContextNodeForLeafProbe(
const AddrBasedCtxKey *CtxKey, const MCDecodedPseudoProbe *LeafProbe) { … }
FunctionSamples &CSProfileGenerator::getFunctionProfileForLeafProbe(
const AddrBasedCtxKey *CtxKey, const MCDecodedPseudoProbe *LeafProbe) { … }
}
}