LLVM 23.0.0git
ProfDataUtils.cpp
Go to the documentation of this file.
1//===- ProfDataUtils.cpp - Utility functions for MD_prof Metadata ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements utilities for working with Profiling Metadata.
10//
11//===----------------------------------------------------------------------===//
12
14
15#include "llvm/ADT/STLExtras.h"
18#include "llvm/IR/Constants.h"
19#include "llvm/IR/Function.h"
21#include "llvm/IR/LLVMContext.h"
22#include "llvm/IR/MDBuilder.h"
23#include "llvm/IR/Metadata.h"
25
26using namespace llvm;
27
28namespace llvm {
30}
31
32// MD_prof nodes have the following layout
33//
34// In general:
35// { String name, Array of i32 }
36//
37// In terms of Types:
38// { MDString, [i32, i32, ...]}
39//
40// Concretely for Branch Weights
41// { "branch_weights", [i32 1, i32 10000]}
42//
43// We maintain some constants here to ensure that we access the branch weights
44// correctly, and can change the behavior in the future if the layout changes
45
46// the minimum number of operands for MD_prof nodes with branch weights
47static constexpr unsigned MinBWOps = 3;
48
49// the minimum number of operands for MD_prof nodes with value profiles
50static constexpr unsigned MinVPOps = 5;
51
52// We may want to add support for other MD_prof types, so provide an abstraction
53// for checking the metadata type.
54static bool isTargetMD(const MDNode *ProfData, const char *Name,
55 unsigned MinOps) {
56 // TODO: This routine may be simplified if MD_prof used an enum instead of a
57 // string to differentiate the types of MD_prof nodes.
58 if (!ProfData || !Name || MinOps < 2)
59 return false;
60
61 unsigned NOps = ProfData->getNumOperands();
62 if (NOps < MinOps)
63 return false;
64
65 auto *ProfDataName = dyn_cast<MDString>(ProfData->getOperand(0));
66 if (!ProfDataName)
67 return false;
68
69 return ProfDataName->getString() == Name;
70}
71
72template <typename T,
73 typename = typename std::enable_if<std::is_arithmetic_v<T>>>
74static void extractFromBranchWeightMD(const MDNode *ProfileData,
75 SmallVectorImpl<T> &Weights) {
76 assert(isBranchWeightMD(ProfileData) && "wrong metadata");
77
78 unsigned NOps = ProfileData->getNumOperands();
79 unsigned WeightsIdx = getBranchWeightOffset(ProfileData);
80 assert(WeightsIdx < NOps && "Weights Index must be less than NOps.");
81 Weights.resize(NOps - WeightsIdx);
82
83 for (unsigned Idx = WeightsIdx, E = NOps; Idx != E; ++Idx) {
84 ConstantInt *Weight =
86 assert(Weight && "Malformed branch_weight in MD_prof node");
87 assert(Weight->getValue().getActiveBits() <= (sizeof(T) * 8) &&
88 "Too many bits for MD_prof branch_weight");
89 Weights[Idx - WeightsIdx] = Weight->getZExtValue();
90 }
91}
92
93/// Push the weights right to fit in uint32_t.
96 Ret.reserve(Weights.size());
97 uint64_t Max = *llvm::max_element(Weights);
98 if (Max > UINT_MAX) {
99 unsigned Offset = 32 - llvm::countl_zero(Max);
100 for (const uint64_t &Value : Weights)
101 Ret.push_back(static_cast<uint32_t>(Value >> Offset));
102 } else {
103 append_range(Ret, Weights);
104 }
105 return Ret;
106}
107
108static cl::opt<bool> ElideAllZeroBranchWeights("elide-all-zero-branch-weights",
109#if defined(LLVM_ENABLE_PROFCHECK)
110 cl::init(false)
111#else
112 cl::init(true)
113#endif
114);
115const char *MDProfLabels::BranchWeights = "branch_weights";
116const char *MDProfLabels::ExpectedBranchWeights = "expected";
117const char *MDProfLabels::ValueProfile = "VP";
118const char *MDProfLabels::FunctionEntryCount = "function_entry_count";
120 "synthetic_function_entry_count";
121const char *MDProfLabels::UnknownBranchWeightsMarker = "unknown";
122const char *llvm::LLVMLoopEstimatedTripCount = "llvm.loop.estimated_trip_count";
123
125 return I.hasMetadata(LLVMContext::MD_prof);
126}
127
128bool llvm::isBranchWeightMD(const MDNode *ProfileData) {
129 return isTargetMD(ProfileData, MDProfLabels::BranchWeights, MinBWOps);
130}
131
132bool llvm::isValueProfileMD(const MDNode *ProfileData) {
133 return isTargetMD(ProfileData, MDProfLabels::ValueProfile, MinVPOps);
134}
135
137 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
138 return isBranchWeightMD(ProfileData);
139}
140
141static bool hasCountTypeMD(const Instruction &I) {
142 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
143 // Value profiles record count-type information.
144 if (isValueProfileMD(ProfileData))
145 return true;
146 // Conservatively assume non CallBase instruction only get taken/not-taken
147 // branch probability, so not interpret them as count.
148 return isa<CallBase>(I) && !isBranchWeightMD(ProfileData);
149}
150
154
156 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
157 return hasBranchWeightOrigin(ProfileData);
158}
159
160bool llvm::hasBranchWeightOrigin(const MDNode *ProfileData) {
161 if (!isBranchWeightMD(ProfileData))
162 return false;
163 auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(1));
164 // NOTE: if we ever have more types of branch weight provenance,
165 // we need to check the string value is "expected". For now, we
166 // supply a more generic API, and avoid the spurious comparisons.
167 assert(ProfDataName == nullptr ||
168 ProfDataName->getString() == MDProfLabels::ExpectedBranchWeights);
169 return ProfDataName != nullptr;
170}
171
172unsigned llvm::getBranchWeightOffset(const MDNode *ProfileData) {
173 return hasBranchWeightOrigin(ProfileData) ? 2 : 1;
174}
175
176unsigned llvm::getNumBranchWeights(const MDNode &ProfileData) {
177 return ProfileData.getNumOperands() - getBranchWeightOffset(&ProfileData);
178}
179
181 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
182 if (!isBranchWeightMD(ProfileData))
183 return nullptr;
184 return ProfileData;
185}
186
188 auto *ProfileData = getBranchWeightMDNode(I);
189 if (ProfileData && getNumBranchWeights(*ProfileData) == I.getNumSuccessors())
190 return ProfileData;
191 return nullptr;
192}
193
195 SmallVectorImpl<uint32_t> &Weights) {
196 extractFromBranchWeightMD(ProfileData, Weights);
197}
198
200 SmallVectorImpl<uint64_t> &Weights) {
201 extractFromBranchWeightMD(ProfileData, Weights);
202}
203
204bool llvm::extractBranchWeights(const MDNode *ProfileData,
205 SmallVectorImpl<uint32_t> &Weights) {
206 if (!isBranchWeightMD(ProfileData))
207 return false;
208 extractFromBranchWeightMD(ProfileData, Weights);
209 return true;
210}
211
213 SmallVectorImpl<uint32_t> &Weights) {
214 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
215 return extractBranchWeights(ProfileData, Weights);
216}
217
219 uint64_t &FalseVal) {
220 assert((I.getOpcode() == Instruction::Br ||
221 I.getOpcode() == Instruction::Select) &&
222 "Looking for branch weights on something besides branch, select, or "
223 "switch");
224
226 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
227 if (!extractBranchWeights(ProfileData, Weights))
228 return false;
229
230 if (Weights.size() > 2)
231 return false;
232
233 TrueVal = Weights[0];
234 FalseVal = Weights[1];
235 return true;
236}
237
238bool llvm::extractProfTotalWeight(const MDNode *ProfileData,
239 uint64_t &TotalVal) {
240 TotalVal = 0;
241 if (!ProfileData)
242 return false;
243
244 auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(0));
245 if (!ProfDataName)
246 return false;
247
248 if (ProfDataName->getString() == MDProfLabels::BranchWeights) {
249 unsigned Offset = getBranchWeightOffset(ProfileData);
250 for (unsigned Idx = Offset; Idx < ProfileData->getNumOperands(); ++Idx) {
251 auto *V = mdconst::extract<ConstantInt>(ProfileData->getOperand(Idx));
252 TotalVal += V->getValue().getZExtValue();
253 }
254 return true;
255 }
256
257 if (ProfDataName->getString() == MDProfLabels::ValueProfile &&
258 ProfileData->getNumOperands() > 3) {
259 TotalVal = mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(2))
260 ->getValue()
261 .getZExtValue();
262 return true;
263 }
264 return false;
265}
266
268 return extractProfTotalWeight(I.getMetadata(LLVMContext::MD_prof), TotalVal);
269}
270
273 MDBuilder MDB(I.getContext());
274 I.setMetadata(
275 LLVMContext::MD_prof,
276 MDNode::get(I.getContext(),
277 {MDB.createString(MDProfLabels::UnknownBranchWeightsMarker),
278 MDB.createString(PassName)}));
279}
280
283 const Function *F) {
284 F = F ? F : I.getFunction();
285 assert(F && "Either pass a instruction attached to a Function, or explicitly "
286 "pass the Function that it will be attached to");
287 if (std::optional<Function::ProfileCount> EC = F->getEntryCount();
288 EC && EC->getCount() > 0)
290}
291
294 MDBuilder MDB(F.getContext());
295 F.setMetadata(
296 LLVMContext::MD_prof,
297 MDNode::get(F.getContext(),
298 {MDB.createString(MDProfLabels::UnknownBranchWeightsMarker),
299 MDB.createString(PassName)}));
300}
301
303 if (MD.getNumOperands() != 2)
304 return false;
306}
307
309 auto *MD = I.getMetadata(LLVMContext::MD_prof);
310 if (!MD)
311 return false;
313}
314
316 bool IsExpected, bool ElideAllZero) {
317 if ((ElideAllZeroBranchWeights && ElideAllZero) &&
318 llvm::all_of(Weights, equal_to(0))) {
319 I.setMetadata(LLVMContext::MD_prof, nullptr);
320 return;
321 }
322
323 MDBuilder MDB(I.getContext());
324 MDNode *BranchWeights = MDB.createBranchWeights(Weights, IsExpected);
325 I.setMetadata(LLVMContext::MD_prof, BranchWeights);
326}
327
329 bool IsExpected, bool ElideAllZero) {
330 setBranchWeights(I, fitWeights(Weights), IsExpected, ElideAllZero);
331}
332
335 std::optional<uint64_t> KnownMaxCount) {
336 uint64_t MaxCount = KnownMaxCount.has_value() ? KnownMaxCount.value()
337 : *llvm::max_element(Weights);
338 assert(MaxCount > 0 && "Bad max count");
339 uint64_t Scale = calculateCountScale(MaxCount);
340 SmallVector<uint32_t> DownscaledWeights;
341 for (const auto &ECI : Weights)
342 DownscaledWeights.push_back(scaleBranchCount(ECI, Scale));
343 return DownscaledWeights;
344}
345
347 assert(T != 0 && "Caller should guarantee");
348 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
349 if (ProfileData == nullptr)
350 return;
351
352 auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(0));
353 if (!ProfDataName ||
354 (ProfDataName->getString() != MDProfLabels::BranchWeights &&
355 ProfDataName->getString() != MDProfLabels::ValueProfile))
356 return;
357
358 if (!hasCountTypeMD(I))
359 return;
360
361 LLVMContext &C = I.getContext();
362
363 MDBuilder MDB(C);
365 Vals.push_back(ProfileData->getOperand(0));
366 APInt APS(128, S), APT(128, T);
367 if (ProfDataName->getString() == MDProfLabels::BranchWeights &&
368 ProfileData->getNumOperands() > 0) {
369 // Using APInt::div may be expensive, but most cases should fit 64 bits.
370 APInt Val(128,
372 ProfileData->getOperand(getBranchWeightOffset(ProfileData)))
373 ->getValue()
374 .getZExtValue());
375 Val *= APS;
376 Vals.push_back(MDB.createConstant(ConstantInt::get(
377 Type::getInt32Ty(C), Val.udiv(APT).getLimitedValue(UINT32_MAX))));
378 } else if (ProfDataName->getString() == MDProfLabels::ValueProfile)
379 for (unsigned Idx = 1; Idx < ProfileData->getNumOperands(); Idx += 2) {
380 // The first value is the key of the value profile, which will not change.
381 Vals.push_back(ProfileData->getOperand(Idx));
383 mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(Idx + 1))
384 ->getValue()
385 .getZExtValue();
386 // Don't scale the magic number.
387 if (Count == NOMORE_ICP_MAGICNUM) {
388 Vals.push_back(ProfileData->getOperand(Idx + 1));
389 continue;
390 }
391 // Using APInt::div may be expensive, but most cases should fit 64 bits.
392 APInt Val(128, Count);
393 Val *= APS;
394 Vals.push_back(MDB.createConstant(ConstantInt::get(
395 Type::getInt64Ty(C), Val.udiv(APT).getLimitedValue())));
396 }
397 I.setMetadata(LLVMContext::MD_prof, MDNode::get(C, Vals));
398}
399
401 Value *V, llvm::function_ref<void(Instruction *)> setMetadataCallback) {
403 if (Instruction *Inst = dyn_cast<Instruction>(V)) {
404 setMetadataCallback(Inst);
405 }
406 }
407}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file contains the declarations for metadata subclasses.
#define T
static constexpr unsigned MinVPOps
static cl::opt< bool > ElideAllZeroBranchWeights("elide-all-zero-branch-weights", cl::init(true))
static bool isTargetMD(const MDNode *ProfData, const char *Name, unsigned MinOps)
static void extractFromBranchWeightMD(const MDNode *ProfileData, SmallVectorImpl< T > &Weights)
static bool hasCountTypeMD(const Instruction &I)
static constexpr unsigned MinBWOps
This file contains the declarations for profiling metadata utility functions.
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallVector class.
static const char PassName[]
Class for arbitrary precision integers.
Definition APInt.h:78
LLVM_ABI APInt udiv(const APInt &RHS) const
Unsigned division operation.
Definition APInt.cpp:1584
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition APInt.h:1521
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
Definition APInt.h:476
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
This is the shared class of boolean and integer constants.
Definition Constants.h:87
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition Constants.h:168
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
LLVM_ABI ConstantAsMetadata * createConstant(Constant *C)
Return the given constant as metadata.
Definition MDBuilder.cpp:25
LLVM_ABI MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
Definition MDBuilder.cpp:38
Metadata node.
Definition Metadata.h:1080
const MDOperand & getOperand(unsigned I) const
Definition Metadata.h:1444
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1572
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1450
bool equalsStr(StringRef Str) const
Definition Metadata.h:924
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:297
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:296
LLVM Value Representation.
Definition Value.h:75
An efficient, type-erasing, non-owning reference to a callable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract(Y &&MD)
Extract a Value from Metadata, if any.
Definition Metadata.h:696
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1737
LLVM_ABI bool extractProfTotalWeight(const MDNode *ProfileData, uint64_t &TotalWeights)
Retrieve the total of all weights from MD_prof data.
LLVM_ABI unsigned getBranchWeightOffset(const MDNode *ProfileData)
Return the offset to the first branch weight data.
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
LLVM_ABI bool isBranchWeightMD(const MDNode *ProfileData)
Checks if an MDNode contains Branch Weight Metadata.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI bool isExplicitlyUnknownProfileMetadata(const MDNode &MD)
LLVM_ABI MDNode * getBranchWeightMDNode(const Instruction &I)
Get the branch weights metadata node.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2198
LLVM_ABI void applyProfMetadataIfEnabled(Value *V, llvm::function_ref< void(Instruction *)> setMetadataCallback)
LLVM_ABI void setExplicitlyUnknownBranchWeights(Instruction &I, StringRef PassName)
Specify that the branch weights for this terminator cannot be known at compile time.
LLVM_ABI bool hasBranchWeightOrigin(const Instruction &I)
Check if Branch Weight Metadata has an "expected" field from an llvm.expect* intrinsic.
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
Definition STLExtras.h:2163
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...
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Definition bit.h:236
LLVM_ABI SmallVector< uint32_t > fitWeights(ArrayRef< uint64_t > Weights)
Push the weights right to fit in uint32_t.
LLVM_ABI MDNode * getValidBranchWeightMDNode(const Instruction &I)
Get the valid branch weights metadata node.
LLVM_ABI bool hasValidBranchWeightMD(const Instruction &I)
Checks if an instructions has valid Branch Weight Metadata.
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
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...
Definition Casting.h:547
LLVM_ABI void setExplicitlyUnknownFunctionEntryCount(Function &F, StringRef PassName)
Analogous to setExplicitlyUnknownBranchWeights, but for functions and their entry counts.
LLVM_ABI bool isValueProfileMD(const MDNode *ProfileData)
Checks if an MDNode contains value profiling Metadata.
LLVM_ABI unsigned getNumBranchWeights(const MDNode &ProfileData)
LLVM_ABI void extractFromBranchWeightMD32(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Faster version of extractBranchWeights() that skips checks and must only be called with "branch_weigh...
LLVM_ABI bool hasExplicitlyUnknownBranchWeights(const Instruction &I)
LLVM_ABI bool hasProfMD(const Instruction &I)
Checks if an Instruction has MD_prof Metadata.
auto max_element(R &&Range)
Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2078
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
LLVM_ABI const char * LLVMLoopEstimatedTripCount
Profile-based loop metadata that should be accessed only by using llvm::getLoopEstimatedTripCount and...
uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale)
Scale an individual branch count.
cl::opt< bool > ProfcheckDisableMetadataFixes("profcheck-disable-metadata-fixes", cl::Hidden, cl::init(false), cl::desc("Disable metadata propagation fixes discovered through Issue #147390"))
Definition Metadata.cpp:64
LLVM_ABI bool hasBranchWeightMD(const Instruction &I)
Checks if an instructions has Branch Weight Metadata.
LLVM_ABI void setFittedBranchWeights(Instruction &I, ArrayRef< uint64_t > Weights, bool IsExpected, bool ElideAllZero=false)
Variant of setBranchWeights where the Weights will be fit first to uint32_t by shifting right.
uint64_t calculateCountScale(uint64_t MaxCount)
Calculate what to divide by to scale counts.
LLVM_ABI SmallVector< uint32_t > downscaleWeights(ArrayRef< uint64_t > Weights, std::optional< uint64_t > KnownMaxCount=std::nullopt)
downscale the given weights preserving the ratio.
const uint64_t NOMORE_ICP_MAGICNUM
Magic number in the value profile metadata showing a target has been promoted for the instruction and...
Definition Metadata.h:59
LLVM_ABI void scaleProfData(Instruction &I, uint64_t S, uint64_t T)
Scaling the profile data attached to 'I' using the ratio of S/T.
LLVM_ABI void extractFromBranchWeightMD64(const MDNode *ProfileData, SmallVectorImpl< uint64_t > &Weights)
Faster version of extractBranchWeights() that skips checks and must only be called with "branch_weigh...
static LLVM_ABI const char * ExpectedBranchWeights
static LLVM_ABI const char * SyntheticFunctionEntryCount
static LLVM_ABI const char * UnknownBranchWeightsMarker
static LLVM_ABI const char * ValueProfile
static LLVM_ABI const char * FunctionEntryCount
static LLVM_ABI const char * BranchWeights