15#ifndef LLVM_TRANSFORMS_UTILS_SAMPLEPROFILELOADERBASEIMPL_H
16#define LLVM_TRANSFORMS_UTILS_SAMPLEPROFILELOADERBASEIMPL_H
52#define DEBUG_TYPE "sample-profile-impl"
73 return &
F->getEntryBlock();
92 for (
const auto *Operand : FuncInfo->operands()) {
100 for (
const auto &Func : M) {
101 if (Func.hasWeakLinkage() || Func.hasExternalWeakLinkage()) {
104 if (GUIDToProbeDescMap.contains(GUID))
105 GUIDIsWeakSymbol.insert(GUID);
112 auto I = GUIDToProbeDescMap.find(GUID);
113 return I == GUIDToProbeDescMap.end() ? nullptr : &
I->second;
127 return GUIDIsWeakSymbol.count(GUID);
141 bool IsAvailableExternallyLinkage =
155 if (IsAvailableExternallyLinkage || !
Desc)
156 return !
F.hasFnAttribute(
"profile-checksum-mismatch");
165 return F.isDeclaration() || !
F.hasFnAttribute(
"use-sample-profile");
170 std::vector<Function *> &FunctionOrderList) {
177 FunctionOrderList.push_back(&
F);
181 std::reverse(FunctionOrderList.begin(), FunctionOrderList.end());
192 using BT = std::remove_pointer_t<NodeRef>;
216 using Edge = std::pair<const BasicBlockT *, const BasicBlockT *>;
315 std::unique_ptr<SampleProfileReader>
Reader;
345template <
typename BT>
367template <
typename BT>
369 OS <<
"weight[" <<
E.first->getName() <<
"->" <<
E.second->getName()
377template <
typename BT>
381 OS <<
"equivalence[" << BB->getName()
389template <
typename BT>
394 OS <<
"weight[" << BB->getName() <<
"]: " << W <<
"\n";
409template <
typename BT>
417template <
typename BT>
422 return std::error_code();
424 const DebugLoc &DLoc = Inst.getDebugLoc();
426 return std::error_code();
432 Discriminator = DIL->getDiscriminator();
444 Remark <<
" samples from profile (offset: ";
455 << Inst <<
" (line offset: " << LineOffset <<
"."
456 << Discriminator <<
" - weight: " << R.get() <<
")\n");
461template <
typename BT>
465 "Profile is not pseudo probe based");
470 return std::error_code();
478 return std::error_code();
481 auto R =
FS->findSamplesAt(Probe->Id, Probe->Discriminator);
489 Remark <<
" samples from profile (ProbeId=";
491 if (Probe->Discriminator) {
497 Remark <<
", OriginalSamples=";
504 if (Probe->Discriminator)
505 dbgs() <<
"." << Probe->Discriminator;
506 dbgs() <<
":" << Inst <<
" - weight: " << R.get()
507 <<
" - factor: " <<
format(
"%0.2f", Probe->Factor) <<
")\n";});
521template <
typename BT>
525 bool HasWeight =
false;
526 for (
auto &
I : *BB) {
529 Max = std::max(Max, R.get());
542template <
typename BT>
546 for (
const auto &BB :
F) {
568template <
typename BT>
577 it.first->second =
Samples->findFunctionSamples(DIL,
Reader->getRemapper());
579 return it.first->second;
605template <
typename BT>
611 for (
const auto *BB2 : Descendants) {
612 bool IsDomParent = DomTree->dominates(BB2, BB1);
613 bool IsInSameLoop =
LI->getLoopFor(BB1) ==
LI->getLoopFor(BB2);
614 if (BB1 != BB2 && IsDomParent && IsInSameLoop) {
649template <
typename BT>
675 DominatedBBs.
clear();
676 DT->getDescendants(BB1, DominatedBBs);
689 dbgs() <<
"\nAssign the same weight to all blocks in the same class\n");
709template <
typename BT>
711 unsigned *NumUnknownEdges,
714 (*NumUnknownEdges)++;
735template <
typename BT>
740 for (
const auto &BI :
F) {
749 for (
unsigned i = 0; i < 2; i++) {
751 unsigned NumUnknownEdges = 0, NumTotalEdges = 0;
752 Edge UnknownEdge, SelfReferentialEdge, SingleEdge;
757 NumTotalEdges = Preds.size();
758 for (
auto *Pred : Preds) {
759 Edge E = std::make_pair(Pred, BB);
760 TotalWeight +=
visitEdge(
E, &NumUnknownEdges, &UnknownEdge);
761 if (
E.first ==
E.second)
762 SelfReferentialEdge =
E;
764 if (NumTotalEdges == 1) {
770 NumTotalEdges = Succs.size();
771 for (
auto *Succ : Succs) {
772 Edge E = std::make_pair(BB, Succ);
773 TotalWeight +=
visitEdge(
E, &NumUnknownEdges, &UnknownEdge);
775 if (NumTotalEdges == 1) {
776 SingleEdge = std::make_pair(BB,
Successors[BB][0]);
803 if (NumUnknownEdges <= 1) {
805 if (NumUnknownEdges == 0) {
810 if (TotalWeight > BBWeight) {
811 BBWeight = TotalWeight;
814 <<
" known. Set weight for block: ";
817 }
else if (NumTotalEdges == 1 &&
824 }
else if (NumUnknownEdges == 1 &&
VisitedBlocks.count(EC)) {
827 if (BBWeight >= TotalWeight)
849 Edge E = std::make_pair(Pred, BB);
855 Edge E = std::make_pair(BB, Succ);
860 }
else if (SelfReferentialEdge.first &&
VisitedBlocks.count(EC)) {
863 if (BBWeight >= TotalWeight)
864 EdgeWeights[SelfReferentialEdge] = BBWeight - TotalWeight;
872 if (UpdateBlockCount && TotalWeight > 0 &&
887template <
typename BT>
898 if (Visited.
insert(B2).second)
907 if (Visited.
insert(B2).second)
929template <
typename BT>
936 for (
const auto &BI :
F) {
939 SampleBlockWeights[&BI] = Weight.
get();
984template <
typename FT>
1038template <
typename BT>
1060template <
typename BT>
1086template <
typename BT>
1103template <
typename BT>
1114 Twine(Used) +
" of " +
Twine(
Total) +
" available profile records (" +
1115 Twine(Coverage) +
"%) were applied",
1127 Twine(Used) +
" of " +
Twine(
Total) +
" available profile samples (" +
1128 Twine(Coverage) +
"%) were applied",
1145template <
typename BT>
1149 return S->getLine();
1157 "No debug information found in function " + Func.getName() +
1158 ": Function profile not used",
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")
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file defines a set of templates that efficiently compute a dominator tree over a generic graph.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This file defines the RefCountedBase, ThreadSafeRefCountedBase, and IntrusiveRefCntPtr classes.
Implements a lazy call graph analysis and related passes for the new pass manager.
This file provides the interface for the profile inference algorithm, profi.
This file provides the utility functions for the sampled PGO loader base implementation.
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
Contains the forward declaration for vfs::FileSystem, as well as the IntrusiveRefCntPtrInfo specializ...
static Function * getFunction(FunctionType *Ty, const Twine &Name, Module *M)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
unsigned getBaseDiscriminator() const
Returns the base discriminator stored in the discriminator.
Subprogram description. Uses SubclassData1.
LLVM_ABI unsigned getLine() const
Implements a dense probed hash-table based set.
Diagnostic information for the sample profiler.
Represents either an error or a value T.
void setEntryCount(uint64_t Count, const DenseSet< GlobalValue::GUID > *Imports=nullptr)
Set the entry count for this function.
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
A node in the call graph.
A RefSCC of the call graph.
An SCC of the call graph.
A lazily constructed view of the call graph of a module.
LLVM_ABI void buildRefSCCs()
iterator_range< postorder_ref_scc_iterator > postorder_ref_sccs()
Represents a single loop in the control flow graph.
A Module instance is used to store all the information related to an LLVM module.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
Analysis providing profile information.
uint64_t getFunctionHash() const
const PseudoProbeDescriptor * getDesc(StringRef FProfileName) const
bool probeFromWeakSymbol(uint64_t GUID) const
bool profileIsHashMismatched(const PseudoProbeDescriptor &FuncDesc, const FunctionSamples &Samples) const
const PseudoProbeDescriptor * getDesc(const Function &F) const
bool moduleIsProbed(const Module &M) const
bool profileIsValid(const Function &F, const FunctionSamples &Samples) const
PseudoProbeManager(const Module &M)
const PseudoProbeDescriptor * getDesc(uint64_t GUID) const
Sample profile inference pass.
bool computeAndPropagateWeights(FunctionT &F, const DenseSet< GlobalValue::GUID > &InlinedGUIDs)
Generate branch weight metadata for all branches in F.
void computeDominanceAndLoopInfo(FunctionT &F)
typename afdo_detail::IRTraits< BT >::BasicBlockT BasicBlockT
IntrusiveRefCntPtr< vfs::FileSystem > FS
VirtualFileSystem to load profile files from.
typename afdo_detail::IRTraits< BT >::SuccRangeT SuccRangeT
DenseMap< const BasicBlockT *, uint64_t > BlockWeightMap
EdgeWeightMap EdgeWeights
Function & getFunction(FunctionT &F)
SmallSet< Edge, 32 > VisitedEdges
Set of visited edges during propagation.
std::map< SampleContext, FunctionSamples > OutlineFunctionSamples
Synthetic samples created by duplicating the samples of inlined functions from the original profile a...
OptRemarkEmitterT * ORE
Optimization Remark Emitter used to emit diagnostic remarks.
const BasicBlockT * getEntryBB(const FunctionT *F)
ErrorOr< uint64_t > getBlockWeight(const BasicBlockT *BB)
Compute the weight of a basic block.
unsigned getFunctionLoc(FunctionT &Func)
Get the line number for the function header.
PredRangeT getPredecessors(BasicBlockT *BB)
ErrorOr< uint64_t > getInstWeightImpl(const InstructionT &Inst)
virtual ErrorOr< uint64_t > getInstWeight(const InstructionT &Inst)
Get the weight for an instruction.
SmallPtrSet< const BasicBlockT *, 32 > VisitedBlocks
Set of visited blocks during propagation.
EquivalenceClassMap EquivalenceClass
Equivalence classes for block weights.
typename afdo_detail::IRTraits< BT >::PostDominatorTreePtrT PostDominatorTreePtrT
SampleCoverageTracker CoverageTracker
Profile coverage tracker.
typename afdo_detail::IRTraits< BT >::LoopT LoopT
typename GraphTraits< FT * >::NodeRef NodeRef
std::unique_ptr< SampleProfileReader > Reader
Profile reader object.
void printBlockWeight(raw_ostream &OS, const BasicBlockT *BB) const
Print the weight of block BB on stream OS.
DominatorTreePtrT DT
Dominance, post-dominance and loop information.
void printBlockEquivalence(raw_ostream &OS, const BasicBlockT *BB)
Print the equivalence class of block BB on stream OS.
DenseMap< const BasicBlockT *, SmallVector< const BasicBlockT *, 8 > > BlockEdgeMap
std::remove_pointer_t< NodeRef > BT
SampleProfileLoaderBaseImpl(std::string Name, std::string RemapName, IntrusiveRefCntPtr< vfs::FileSystem > FS)
std::unique_ptr< PseudoProbeManager > ProbeManager
typename afdo_detail::IRTraits< BT >::OptRemarkAnalysisT OptRemarkAnalysisT
~SampleProfileLoaderBaseImpl()=default
DenseMap< Edge, uint64_t > EdgeWeightMap
typename afdo_detail::IRTraits< BT >::DominatorTreePtrT DominatorTreePtrT
typename afdo_detail::IRTraits< BT >::LoopInfoPtrT LoopInfoPtrT
void emitCoverageRemarks(FunctionT &F)
SuccRangeT getSuccessors(BasicBlockT *BB)
std::string Filename
Name of the profile file to load.
bool propagateThroughEdges(FunctionT &F, bool UpdateBlockCount)
Propagate weights through incoming/outgoing edges.
PostDominatorTreePtrT PDT
typename afdo_detail::IRTraits< BT >::InstructionT InstructionT
uint64_t visitEdge(Edge E, unsigned *NumUnknownEdges, Edge *UnknownEdge)
Visit the given edge to decide if it has a valid weight.
void initWeightPropagation(FunctionT &F, const DenseSet< GlobalValue::GUID > &InlinedGUIDs)
BlockEdgeMap Predecessors
Predecessors for each basic block in the CFG.
void finalizeWeightPropagation(FunctionT &F, const DenseSet< GlobalValue::GUID > &InlinedGUIDs)
typename afdo_detail::IRTraits< BT >::BlockFrequencyInfoT BlockFrequencyInfoT
bool computeBlockWeights(FunctionT &F)
Compute and store the weights of every basic block.
virtual const FunctionSamples * findFunctionSamples(const InstructionT &I) const
Get the FunctionSamples for an instruction.
friend class SampleCoverageTracker
DenseMap< const BasicBlockT *, const BasicBlockT * > EquivalenceClassMap
typename afdo_detail::IRTraits< BT >::PostDominatorTreeT PostDominatorTreeT
virtual ErrorOr< uint64_t > getProbeWeight(const InstructionT &Inst)
std::string RemappingFilename
Name of the profile remapping file to load.
typename afdo_detail::IRTraits< BT >::PredRangeT PredRangeT
void applyProfi(FunctionT &F, BlockEdgeMap &Successors, BlockWeightMap &SampleBlockWeights, BlockWeightMap &BlockWeights, EdgeWeightMap &EdgeWeights)
FunctionSamples * Samples
Samples collected for the body of this function.
void findEquivalenceClasses(FunctionT &F)
Find equivalence classes.
std::pair< const BasicBlockT *, const BasicBlockT * > Edge
ProfileSummaryInfo * PSI
Profile Summary Info computed from sample profile.
typename afdo_detail::IRTraits< BT >::OptRemarkEmitterT OptRemarkEmitterT
void clearFunctionData(bool ResetDT=true)
Clear all the per-function data used to load samples and propagate weights.
DenseMap< const DILocation *, const FunctionSamples * > DILocation2SampleMap
void buildEdges(FunctionT &F)
Build in/out edge lists for each basic block in the CFG.
void findEquivalencesFor(BasicBlockT *BB1, ArrayRef< BasicBlockT * > Descendants, PostDominatorTreeT *DomTree)
Find equivalence classes for the given block.
void printEdgeWeight(raw_ostream &OS, Edge E)
Print the weight of edge E on stream OS.
typename afdo_detail::IRTraits< BT >::FunctionT FunctionT
BlockWeightMap BlockWeights
void propagateWeights(FunctionT &F)
Propagate weights into edges.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
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.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This class implements an extremely fast bulk output stream that can only output to a stream.
Representation of the samples collected for a function.
uint64_t getFunctionHash() const
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
static LLVM_ABI unsigned getOffset(const DILocation *DIL)
Returns the line offset to the start line of the subprogram.
static LLVM_ABI std::atomic< bool > ProfileIsProbeBased
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
template class LLVM_TEMPLATE_ABI opt< bool >
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract(Y &&MD)
Extract a Value from Metadata, if any.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< pred_iterator > pred_range
iterator_range< succ_iterator > succ_range
auto successors(const MachineBasicBlock *BB)
LLVM_ABI cl::opt< bool > EnableFSDiscriminator
LLVM_ABI cl::opt< unsigned > SampleProfileSampleCoverage
static void buildTopDownFuncOrder(LazyCallGraph &CG, std::vector< Function * > &FunctionOrderList)
LLVM_ABI cl::opt< unsigned > SampleProfileRecordCoverage
LLVM_ABI cl::opt< unsigned > SampleProfileMaxPropagateIterations
LLVM_ABI cl::opt< bool > SampleProfileUseProfi
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.
LLVM_ABI cl::opt< bool > NoWarnSampleUnused
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
static bool skipProfileForFunction(const Function &F)
auto predecessors(const MachineBasicBlock *BB)
constexpr const char * PseudoProbeDescMetadataName
Implement std::hash so that hash_code can be used in STL containers.
typename GraphType::UnknownGraphTypeError NodeRef
OptimizationRemarkEmitter OptRemarkEmitterT
std::unique_ptr< LoopInfo > LoopInfoPtrT
std::unique_ptr< PostDominatorTree > PostDominatorTreePtrT
static Function & getFunction(Function &F)
static pred_range getPredecessors(BasicBlock *BB)
static succ_range getSuccessors(BasicBlock *BB)
PostDominatorTree PostDominatorTreeT
BlockFrequencyInfo BlockFrequencyInfoT
OptimizationRemarkAnalysis OptRemarkAnalysisT
std::unique_ptr< DominatorTree > DominatorTreePtrT
static const BasicBlock * getEntryBB(const Function *F)