35 cl::desc(
"Also inject (if missing) and verify MD_prof for "
36 "`select` instructions"));
39 cl::desc(
"Generate weights with small values for tests."));
42 "profcheck-default-select-true-weight",
cl::init(2U),
43 cl::desc(
"When annotating `select` instructions, this value will be used "
44 "for the first ('true') case."));
46 "profcheck-default-select-false-weight",
cl::init(3U),
47 cl::desc(
"When annotating `select` instructions, this value will be used "
48 "for the second ('false') case."));
50class ProfileInjector {
56 getTerminatorBenefitingFromMDProf(
const BasicBlock &BB) {
66 static Instruction *getTerminatorBenefitingFromMDProf(BasicBlock &BB) {
68 getTerminatorBenefitingFromMDProf(
const_cast<const BasicBlock &
>(BB)));
76 if (!
F.hasFnAttribute(Attribute::AttrKind::Naked))
78 for (
const auto &BB :
F)
81 if (!CB || !CB->isInlineAsm())
88 F.getContext().emitError(
"Profile verification failed for function '" +
89 F.getName() +
"': " +
Msg);
96bool ProfileInjector::inject() {
118 if (!
F.getEntryCount())
122 if (*
F.getEntryCount() == 0)
128 uint32_t WeightsForTestOffset = 0;
133 if (
SI->getCondition()->getType()->isVectorTy())
135 if (
I.getMetadata(LLVMContext::MD_prof))
142 auto *
Term = getTerminatorBenefitingFromMDProf(BB);
143 if (!Term ||
Term->getMetadata(LLVMContext::MD_prof))
147 SmallVector<uint32_t> Weights;
150 static const std::array Primes{3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
151 37, 41, 43, 47, 53, 59, 61, 67, 71};
152 for (uint32_t
I = 0,
E =
Term->getNumSuccessors();
I <
E; ++
I)
154 Primes[(WeightsForTestOffset +
I) % Primes.size()]);
155 ++WeightsForTestOffset;
158 for (
auto I = 0U,
E =
Term->getNumSuccessors();
I <
E; ++
I)
162 [](
const BranchProbability &
P) {
163 return P.isUnknown();
165 "All branch probabilities should be valid");
166 const auto *FirstZeroDenominator =
167 find_if(Probs, [](
const BranchProbability &
P) {
168 return P.getDenominator() == 0;
170 (void)FirstZeroDenominator;
171 assert(FirstZeroDenominator == Probs.
end());
172 const auto *FirstNonZeroNumerator =
find_if(
173 Probs, [](
const BranchProbability &
P) {
return !
P.isZero(); });
174 assert(FirstNonZeroNumerator != Probs.
end());
175 DynamicAPInt LCM(Probs[0].getDenominator());
176 DynamicAPInt GCD(FirstNonZeroNumerator->getNumerator());
178 if (!Prob.getNumerator())
180 LCM =
llvm::lcm(LCM, DynamicAPInt(Prob.getDenominator()));
181 GCD =
llvm::gcd(GCD, DynamicAPInt(Prob.getNumerator()));
183 for (
const auto &Prob : Probs) {
185 (Prob.getNumerator() * LCM / GCD) / Prob.getDenominator();
186 Weights.
emplace_back(
static_cast<uint32_t
>((int64_t)W));
197 ProfileInjector PI(
F,
FAM);
206 auto PopulateIgnoreList = [&](
StringRef GVName) {
207 if (
const auto *CT = M.getGlobalVariable(GVName))
208 if (CT->hasInitializer())
211 for (
const auto &Elt : CA->operands())
213 if (CS->getNumOperands() >= 2 && CS->getOperand(1))
215 CS->getOperand(1)->stripPointerCasts()))
216 IgnoreList.insert(
F);
218 PopulateIgnoreList(
"llvm.global_ctors");
219 PopulateIgnoreList(
"llvm.global_dtors");
227 return PVP.run(
F,
FAM);
240 if (IgnoreList.contains(&
F))
243 const auto EntryCount =
F.getEntryCount();
245 auto *MD =
F.getMetadata(LLVMContext::MD_prof);
247 emitProfileError(
"function entry count missing (set to 0 if cold)",
F);
250 }
else if (*EntryCount == 0) {
253 for (
const auto &BB :
F) {
255 for (
const auto &
I : BB)
257 if (
SI->getCondition()->getType()->isVectorTy())
259 if (
I.getMetadata(LLVMContext::MD_prof))
261 emitProfileError(
"select annotation missing",
F);
264 if (
const auto *Term =
265 ProfileInjector::getTerminatorBenefitingFromMDProf(BB))
266 if (!
Term->getMetadata(LLVMContext::MD_prof))
267 emitProfileError(
"branch annotation missing",
F);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
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; assumes that the block is well-formed.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Runs the function pass across every function in the module.
A Module instance is used to store all the information related to an LLVM module.
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)
Checks that MD_prof is present on every instruction that supports it.
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
Represent a constant reference to a string, i.e.
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)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
ModuleToFunctionPassAdaptor createModuleToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
LLVM_ABI bool isExplicitlyUnknownProfileMetadata(const MDNode &MD)
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected, bool ElideAllZero=false)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
auto succ_size(const MachineBasicBlock *BB)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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...
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
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.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
A CRTP mix-in for passes that can be skipped.