29 cl::desc(
"Also inject (if missing) and verify MD_prof for "
30 "`select` instructions"));
33 cl::desc(
"Generate weights with small values for tests."));
36 "profcheck-default-select-true-weight",
cl::init(2U),
37 cl::desc(
"When annotating `select` instructions, this value will be used "
38 "for the first ('true') case."));
40 "profcheck-default-select-false-weight",
cl::init(3U),
41 cl::desc(
"When annotating `select` instructions, this value will be used "
42 "for the second ('false') case."));
44class ProfileInjector {
50 getTerminatorBenefitingFromMDProf(
const BasicBlock &BB) {
60 static Instruction *getTerminatorBenefitingFromMDProf(BasicBlock &BB) {
62 getTerminatorBenefitingFromMDProf(
const_cast<const BasicBlock &
>(BB)));
72bool ProfileInjector::inject() {
91 if (!
F.getEntryCount(
true))
95 if (
F.getEntryCount(
true)->getCount() == 0)
101 uint32_t WeightsForTestOffset = 0;
110 auto *
Term = getTerminatorBenefitingFromMDProf(BB);
111 if (!Term ||
Term->getMetadata(LLVMContext::MD_prof))
113 SmallVector<BranchProbability> Probs;
115 SmallVector<uint32_t> Weights;
118 static const std::array Primes{3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
119 37, 41, 43, 47, 53, 59, 61, 67, 71};
120 for (uint32_t
I = 0,
E =
Term->getNumSuccessors();
I <
E; ++
I)
122 Primes[(WeightsForTestOffset +
I) % Primes.size()]);
123 ++WeightsForTestOffset;
126 for (
auto I = 0U,
E =
Term->getNumSuccessors();
I <
E; ++
I)
130 [](
const BranchProbability &
P) {
131 return P.isUnknown();
133 "All branch probabilities should be valid");
134 const auto *FirstZeroDenominator =
135 find_if(Probs, [](
const BranchProbability &
P) {
136 return P.getDenominator() == 0;
138 (void)FirstZeroDenominator;
139 assert(FirstZeroDenominator == Probs.
end());
140 const auto *FirstNonZeroNumerator =
find_if(
141 Probs, [](
const BranchProbability &
P) {
return !
P.isZero(); });
142 assert(FirstNonZeroNumerator != Probs.
end());
143 DynamicAPInt LCM(Probs[0].getDenominator());
144 DynamicAPInt GCD(FirstNonZeroNumerator->getNumerator());
146 if (!Prob.getNumerator())
148 LCM =
llvm::lcm(LCM, DynamicAPInt(Prob.getDenominator()));
149 GCD =
llvm::gcd(GCD, DynamicAPInt(Prob.getNumerator()));
151 for (
const auto &Prob : Probs) {
153 (Prob.getNumerator() * LCM / GCD) / Prob.getDenominator();
154 Weights.
emplace_back(
static_cast<uint32_t
>((int64_t)W));
165 ProfileInjector PI(
F,
FAM);
174 const auto EntryCount =
F.getEntryCount(
true);
176 auto *MD =
F.getMetadata(LLVMContext::MD_prof);
178 F.getContext().emitError(
"Profile verification failed: function entry "
179 "count missing (set to 0 if cold)");
182 }
else if (EntryCount->getCount() == 0) {
185 for (
const auto &BB :
F) {
187 for (
const auto &
I : BB)
189 F.getContext().emitError(
190 "Profile verification failed: select annotation missing");
192 if (
const auto *Term =
193 ProfileInjector::getTerminatorBenefitingFromMDProf(BB))
194 if (!Term->getMetadata(LLVMContext::MD_prof))
195 F.getContext().emitError(
196 "Profile verification failed: branch annotation missing");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
FunctionAnalysisManager FAM
This file contains the declarations for profiling metadata utility functions.
static cl::opt< bool > WeightsForTest("profcheck-weights-for-test", cl::init(false), cl::desc("Generate weights with small values for tests."))
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."))
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...
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)
Pass manager infrastructure for declaring and invalidating analyses.
@ BasicBlock
Various leaf nodes.
initializer< Ty > init(const Ty &Val)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
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 bool isExplicitlyUnknownProfileMetadata(const MDNode &MD)
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)
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...
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.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.