29 cl::desc(
"Also inject (if missing) and verify MD_prof for "
30 "`select` instructions"));
32 "profcheck-default-select-true-weight",
cl::init(2U),
33 cl::desc(
"When annotating `select` instructions, this value will be used "
34 "for the first ('true') case."));
36 "profcheck-default-select-false-weight",
cl::init(3U),
37 cl::desc(
"When annotating `select` instructions, this value will be used "
38 "for the second ('false') case."));
40class ProfileInjector {
46 getTerminatorBenefitingFromMDProf(
const BasicBlock &BB) {
50 return (isa<BranchInst>(Term) || isa<SwitchInst>(Term) ||
51 isa<IndirectBrInst>(Term) || isa<CallBrInst>(Term))
58 getTerminatorBenefitingFromMDProf(
const_cast<const BasicBlock &
>(BB)));
68bool ProfileInjector::inject() {
87 if (!
F.getEntryCount(
true))
91 if (
F.getEntryCount(
true)->getCount() == 0)
97 if (isa<SelectInst>(
I) && !
I.getMetadata(LLVMContext::MD_prof))
102 auto *
Term = getTerminatorBenefitingFromMDProf(BB);
103 if (!Term ||
Term->getMetadata(LLVMContext::MD_prof))
107 for (
auto I = 0U, E =
Term->getNumSuccessors();
I < E; ++
I)
112 return P.isUnknown();
114 "All branch probabilities should be valid");
115 const auto *FirstZeroDenominator =
117 return P.getDenominator() == 0;
119 (void)FirstZeroDenominator;
120 assert(FirstZeroDenominator == Probs.
end());
121 const auto *FirstNonZeroNumerator =
123 assert(FirstNonZeroNumerator != Probs.
end());
125 DynamicAPInt GCD(FirstNonZeroNumerator->getNumerator());
127 if (!Prob.getNumerator())
134 for (
const auto &Prob : Probs) {
136 (Prob.getNumerator() * LCM / GCD) / Prob.getDenominator();
147 ProfileInjector PI(
F,
FAM);
156 const auto EntryCount =
F.getEntryCount(
true);
158 F.getContext().emitError(
"Profile verification failed: function entry "
159 "count missing (set to 0 if cold)");
162 if (EntryCount->getCount() == 0)
164 for (
const auto &BB :
F) {
166 for (
const auto &
I : BB)
167 if (isa<SelectInst>(
I) && !
I.getMetadata(LLVMContext::MD_prof))
168 F.getContext().emitError(
169 "Profile verification failed: select annotation missing");
171 if (
const auto *Term =
172 ProfileInjector::getTerminatorBenefitingFromMDProf(BB))
173 if (!Term->getMetadata(LLVMContext::MD_prof))
174 F.getContext().emitError(
175 "Profile verification failed: branch annotation missing");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
FunctionAnalysisManager FAM
This file contains the declarations for profiling metadata utility functions.
static cl::opt< uint32_t > SelectFalseWeight("profcheck-default-select-false-weight", cl::init(3U), cl::desc("When annotating `select` instructions, this value will be used " "for the second ('false') case."))
static cl::opt< int64_t > DefaultFunctionEntryCount("profcheck-default-function-entry-count", cl::init(1000))
static cl::opt< bool > AnnotateSelect("profcheck-annotate-select", cl::init(true), cl::desc("Also inject (if missing) and verify MD_prof for " "`select` instructions"))
static cl::opt< uint32_t > SelectTrueWeight("profcheck-default-select-true-weight", cl::init(2U), cl::desc("When annotating `select` instructions, this value will be used " "for the first ('true') case."))
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Analysis pass which computes BranchProbabilityInfo.
This class provides support for dynamic arbitrary-precision arithmetic.
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.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Pass manager infrastructure for declaring and invalidating analyses.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
auto succ_size(const MachineBasicBlock *BB)
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt lcm(const DynamicAPInt &A, const DynamicAPInt &B)
Returns the least common multiple of A and B.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.