40#define DEBUG_TYPE "pseudo-probe"
43 "Number of probes that have an artificial debug line");
47 const DILocation *InlinedAt = DIL ? DIL->getInlinedAt() :
nullptr;
49 Hash ^=
MD5Hash(std::to_string(InlinedAt->getLine()));
50 Hash ^=
MD5Hash(std::to_string(InlinedAt->getColumn()));
51 auto Name = InlinedAt->getSubprogramLinkageName();
53 InlinedAt = InlinedAt->getInlinedAt();
62bool PseudoProbeVerifier::shouldVerifyFunction(
const Function *
F) {
64 if (
F->isDeclaration())
68 if (
F->hasAvailableExternallyLinkage())
70 return VerifyFuncNames.empty() || VerifyFuncNames.contains(
F->getName());
80 PIC.registerAfterPassCallback(
90 "\n*** Pseudo Probe Verification After " +
PassID.str() +
" ***\n";
115 if (!shouldVerifyFunction(
F))
118 for (
const auto &BB : *
F)
119 collectProbeFactors(&BB, ProbeFactors);
120 verifyProbeFactors(
F, ProbeFactors);
124 const Function *
F =
L->getHeader()->getParent();
130 for (
const auto &
I : *
Block) {
133 ProbeFactors[{Probe->Id, Hash}] += Probe->Factor;
138void PseudoProbeVerifier::verifyProbeFactors(
140 bool BannerPrinted =
false;
141 auto &PrevProbeFactors = FunctionProbeFactors[
F->getName()];
142 for (
const auto &
I : ProbeFactors) {
143 float CurProbeFactor =
I.second;
144 auto [It,
Inserted] = PrevProbeFactors.try_emplace(
I.first);
146 float PrevProbeFactor = It->second;
147 if (std::abs(CurProbeFactor - PrevProbeFactor) >
148 DistributionFactorVariance) {
149 if (!BannerPrinted) {
150 dbgs() <<
"Function " <<
F->getName() <<
":\n";
151 BannerPrinted =
true;
153 dbgs() <<
"Probe " <<
I.first.first <<
"\tprevious factor "
154 <<
format(
"%0.2f", PrevProbeFactor) <<
"\tcurrent factor "
155 <<
format(
"%0.2f", CurProbeFactor) <<
"\n";
160 It->second =
I.second;
165 BlockProbeIds.clear();
166 CallProbeIds.clear();
171 computeBlocksToIgnore(BlocksToIgnore, BlocksAndCallsToIgnore);
173 computeProbeId(BlocksToIgnore, BlocksAndCallsToIgnore);
174 computeCFGHash(BlocksToIgnore);
186void SampleProfileProber::computeBlocksToIgnore(
191 findUnreachableBlocks(BlocksAndCallsToIgnore);
201 findInvokeNormalDests(BlocksToIgnore);
205void SampleProfileProber::findUnreachableBlocks(
207 for (
auto &BB : *
F) {
208 if (&BB != &
F->getEntryBlock() &&
pred_size(&BB) == 0)
209 BlocksToIgnore.
insert(&BB);
226 OnCurrentPath.
clear();
231 auto CycleStart =
llvm::find(CurrentPath, Cur);
232 assert(CycleStart != CurrentPath.
end() &&
233 "OnCurrentPath must hold exactly the blocks in CurrentPath");
234 CycleBlocks.
insert(CycleStart, CurrentPath.
end());
239 OnCurrentPath.
insert(Cur);
242 Cur =
II->getNormalDest();
253void SampleProfileProber::findInvokeNormalDests(
255 DenseSet<const BasicBlock *> CycleBlocks;
258 for (
auto &BB : *F) {
259 auto *TI = BB.getTerminator();
261 auto *ND =
II->getNormalDest();
264 InvokeNormalDests.
insert(ND);
285const Instruction *SampleProfileProber::getOriginalTerminator(
289 DenseSet<const BasicBlock *> Visited;
296 Next =
II->getNormalDest();
315void SampleProfileProber::computeCFGHash(
317 std::vector<uint8_t> Indexes;
319 for (
auto &BB : *F) {
323 auto *TI = getOriginalTerminator(&BB, BlocksToIgnore);
324 for (
unsigned I = 0,
E = TI->getNumSuccessors();
I !=
E; ++
I) {
325 auto *Succ = TI->getSuccessor(
I);
326 auto Index = getBlockId(Succ);
330 for (
int J = 0; J < 4; J++)
331 Indexes.push_back((uint8_t)(Index >> (J * 8)));
337 FunctionHash = (
uint64_t)CallProbeIds.size() << 48 |
340 FunctionHash &= 0x0FFFFFFFFFFFFFFF;
341 assert(FunctionHash &&
"Function checksum should not be zero");
342 LLVM_DEBUG(
dbgs() <<
"\nFunction Hash Computation for " << F->getName()
344 <<
" CRC = " << JC.
getCRC() <<
", Edges = "
345 << Indexes.size() <<
", ICSites = " << CallProbeIds.size()
346 <<
", Hash = " << FunctionHash <<
"\n");
349void SampleProfileProber::computeProbeId(
352 LLVMContext &Ctx = F->getContext();
355 for (
auto &BB : *F) {
357 BlockProbeIds[&BB] = ++LastProbeId;
359 if (BlocksAndCallsToIgnore.
contains(&BB))
367 if (LastProbeId >= 0xFFFF) {
368 std::string
Msg =
"Pseudo instrumentation incomplete for " +
369 std::string(F->getName()) +
" because it's too large";
371 DiagnosticInfoSampleProfile(
M->getName().data(),
Msg,
DS_Warning));
375 CallProbeIds[&
I] = ++LastProbeId;
380uint32_t SampleProfileProber::getBlockId(
const BasicBlock *BB)
const {
381 auto I = BlockProbeIds.find(
const_cast<BasicBlock *
>(BB));
382 return I == BlockProbeIds.end() ? 0 :
I->second;
385uint32_t SampleProfileProber::getCallsiteId(
const Instruction *
Call)
const {
387 return Iter == CallProbeIds.end() ? 0 : Iter->second;
391 Module *M = F.getParent();
397 if (
auto *SP = F.getSubprogram()) {
398 FName = SP->getLinkageName();
400 FName = SP->getName();
411 "Expecting pseudo probe or call instructions");
412 if (!
I->getDebugLoc()) {
413 if (
auto *SP = F.getSubprogram()) {
418 dbgs() <<
"\nIn Function " << F.getName()
419 <<
" Probe gets an artificial debug line\n";
427 for (
auto &
I : BlockProbeIds) {
437 return !
isa<PHINode>(J) && !J->isLifetimeStartOrEnd() && J->getDebugLoc();
452 if ((CI->isMustTailCall() ||
453 CI->getIntrinsicID() == Intrinsic::experimental_deoptimize) &&
458 assert(Builder.GetInsertPoint() != BB->
end() &&
459 "Cannot get the probing point");
462 Value *Args[] = {Builder.getInt64(
Guid), Builder.getInt64(Index),
465 auto *Probe = Builder.CreateCall(ProbeFn, Args);
466 AssignDebugLoc(Probe);
469 if (
auto DIL = Probe->getDebugLoc()) {
470 if (DIL->getDiscriminator()) {
471 DIL = DIL->cloneWithDiscriminator(0);
472 Probe->setDebugLoc(DIL);
480 for (
auto &
I : CallProbeIds) {
481 auto *
Call =
I.first;
486 AssignDebugLoc(
Call);
487 if (
auto DIL =
Call->getDebugLoc()) {
493 DIL->getBaseDiscriminator());
494 DIL = DIL->cloneWithDiscriminator(V);
495 Call->setDebugLoc(DIL);
504 auto Hash = getFunctionHash();
507 assert(NMD &&
"llvm.pseudo_probe_desc should be pre-created");
519 if (
F.isDeclaration())
528void PseudoProbeUpdatePass::runOnFunction(
Function &
F,
531 auto BBProfileCount = [&BFI](
BasicBlock *BB) {
541 ProbeFactors[{Probe->Id, Hash}] += BBProfileCount(&
Block);
551 float Sum = ProbeFactors[{Probe->Id, Hash}];
563 if (
F.isDeclaration())
567 runOnFunction(
F,
FAM);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Module.h This file contains the declarations for the Module class.
Legalize the Machine IR a function s Machine IR
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
PassInstrumentationCallbacks PIC
This file defines the Pass Instrumentation classes that provide instrumentation points into the pass ...
static void findInvokeNormalDestCycles(const Function &F, DenseSet< const BasicBlock * > &CycleBlocks)
static uint64_t computeCallStackHash(const Instruction &Inst)
static uint64_t getCallStackHash(const DILocation *DIL)
This file provides the interface for the pseudo probe implementation for AutoFDO.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
StringSet - A set-like wrapper for the StringMap.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const BasicBlock *BB) const
Returns the estimated profile count of BB.
Implements a dense probed hash-table based set.
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
A type-erased reference to the IR unit a pass or analysis is running on, together with the kind of IR...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
LLVM_ABI void update(ArrayRef< uint8_t > Data)
This is an important class for using LLVM in a threaded context.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
A node in the call graph.
An SCC of the call graph.
Represents a single loop in the control flow graph.
LLVM_ABI MDNode * createPseudoProbeDesc(uint64_t GUID, uint64_t Hash, StringRef FName)
Return metadata containing the pseudo probe descriptor for a function.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
A Module instance is used to store all the information related to an LLVM module.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC)
LLVM_ABI void runAfterPass(StringRef PassID, IRUnitRef IR)
LLVM_ABI PseudoProbeVerifier(const LLVMContext &C)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Sample profile pseudo prober.
LLVM_ABI SampleProfileProber(Function &F)
LLVM_ABI void instrumentOneFunc(Function &F, TargetMachine *TM)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
Primary interface to the complete machine description for the target machine.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
void insert_range(Range &&R)
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ BasicBlock
Various leaf nodes.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
uint64_t MD5Hash(const FunctionId &Obj)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
DenseMap< std::pair< uint64_t, uint64_t >, float > ProbeFactorMap
static constexpr uint64_t PseudoProbeFullDistributionFactor
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr from_range_t from_range
auto pred_size(const MachineBasicBlock *BB)
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
LLVM_ABI void setProbeDistributionFactor(Instruction &Inst, float Factor)
auto dyn_cast_or_null(const Y &Val)
const IPOOptions & getIPOOptions(const LLVMContext &C)
LLVM_ABI std::optional< PseudoProbe > extractProbe(const Instruction &Inst)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto succ_size(const MachineBasicBlock *BB)
static void computeEHOnlyBlocks(FunctionT &F, DenseSet< BlockT * > &EHBlocks)
Compute a list of blocks that are only reachable via EH paths.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
constexpr const char * PseudoProbeDescMetadataName
static constexpr uint8_t FullDistributionFactor
static uint32_t packProbeData(uint32_t Index, uint32_t Type, uint32_t Flags, uint32_t Factor, std::optional< uint32_t > DwarfBaseDiscriminator)