LLVM 22.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
16#include "llvm/IR/Constants.h"
17#include "llvm/IR/Function.h"
19#include "llvm/IR/LLVMContext.h"
20#include "llvm/IR/MDBuilder.h"
21#include "llvm/IR/Metadata.h"
22
23using namespace llvm;
24
25namespace {
26
27// MD_prof nodes have the following layout
28//
29// In general:
30// { String name, Array of i32 }
31//
32// In terms of Types:
33// { MDString, [i32, i32, ...]}
34//
35// Concretely for Branch Weights
36// { "branch_weights", [i32 1, i32 10000]}
37//
38// We maintain some constants here to ensure that we access the branch weights
39// correctly, and can change the behavior in the future if the layout changes
40
41// the minimum number of operands for MD_prof nodes with branch weights
42constexpr unsigned MinBWOps = 3;
43
44// the minimum number of operands for MD_prof nodes with value profiles
45constexpr unsigned MinVPOps = 5;
46
47// We may want to add support for other MD_prof types, so provide an abstraction
48// for checking the metadata type.
49bool isTargetMD(const MDNode *ProfData, const char *Name, unsigned MinOps) {
50 // TODO: This routine may be simplified if MD_prof used an enum instead of a
51 // string to differentiate the types of MD_prof nodes.
52 if (!ProfData || !Name || MinOps < 2)
53 return false;
54
55 unsigned NOps = ProfData->getNumOperands();
56 if (NOps < MinOps)
57 return false;
58
59 auto *ProfDataName = dyn_cast<MDString>(ProfData->getOperand(0));
60 if (!ProfDataName)
61 return false;
62
63 return ProfDataName->getString() == Name;
64}
65
66template <typename T,
67 typename = typename std::enable_if<std::is_arithmetic_v<T>>>
68static void extractFromBranchWeightMD(const MDNode *ProfileData,
69 SmallVectorImpl<T> &Weights) {
70 assert(isBranchWeightMD(ProfileData) && "wrong metadata");
71
72 unsigned NOps = ProfileData->getNumOperands();
73 unsigned WeightsIdx = getBranchWeightOffset(ProfileData);
74 assert(WeightsIdx < NOps && "Weights Index must be less than NOps.");
75 Weights.resize(NOps - WeightsIdx);
76
77 for (unsigned Idx = WeightsIdx, E = NOps; Idx != E; ++Idx) {
78 ConstantInt *Weight =
80 assert(Weight && "Malformed branch_weight in MD_prof node");
81 assert(Weight->getValue().getActiveBits() <= (sizeof(T) * 8) &&
82 "Too many bits for MD_prof branch_weight");
83 Weights[Idx - WeightsIdx] = Weight->getZExtValue();
84 }
85}
86
87} // namespace
88
89namespace llvm {
90
91const char *MDProfLabels::BranchWeights = "branch_weights";
92const char *MDProfLabels::ExpectedBranchWeights = "expected";
93const char *MDProfLabels::ValueProfile = "VP";
94const char *MDProfLabels::FunctionEntryCount = "function_entry_count";
96 "synthetic_function_entry_count";
97const char *MDProfLabels::UnknownBranchWeightsMarker = "unknown";
98const char *LLVMLoopEstimatedTripCount = "llvm.loop.estimated_trip_count";
99
100bool hasProfMD(const Instruction &I) {
101 return I.hasMetadata(LLVMContext::MD_prof);
102}
103
104bool isBranchWeightMD(const MDNode *ProfileData) {
105 return isTargetMD(ProfileData, MDProfLabels::BranchWeights, MinBWOps);
106}
107
108bool isValueProfileMD(const MDNode *ProfileData) {
109 return isTargetMD(ProfileData, MDProfLabels::ValueProfile, MinVPOps);
110}
111
113 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
114 return isBranchWeightMD(ProfileData);
115}
116
117static bool hasCountTypeMD(const Instruction &I) {
118 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
119 // Value profiles record count-type information.
120 if (isValueProfileMD(ProfileData))
121 return true;
122 // Conservatively assume non CallBase instruction only get taken/not-taken
123 // branch probability, so not interpret them as count.
124 return isa<CallBase>(I) && !isBranchWeightMD(ProfileData);
125}
126
130
132 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
133 return hasBranchWeightOrigin(ProfileData);
134}
135
136bool hasBranchWeightOrigin(const MDNode *ProfileData) {
137 if (!isBranchWeightMD(ProfileData))
138 return false;
139 auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(1));
140 // NOTE: if we ever have more types of branch weight provenance,
141 // we need to check the string value is "expected". For now, we
142 // supply a more generic API, and avoid the spurious comparisons.
143 assert(ProfDataName == nullptr ||
144 ProfDataName->getString() == MDProfLabels::ExpectedBranchWeights);
145 return ProfDataName != nullptr;
146}
147
148unsigned getBranchWeightOffset(const MDNode *ProfileData) {
149 return hasBranchWeightOrigin(ProfileData) ? 2 : 1;
150}
151
152unsigned getNumBranchWeights(const MDNode &ProfileData) {
153 return ProfileData.getNumOperands() - getBranchWeightOffset(&ProfileData);
154}
155
157 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
158 if (!isBranchWeightMD(ProfileData))
159 return nullptr;
160 return ProfileData;
161}
162
164 auto *ProfileData = getBranchWeightMDNode(I);
165 if (ProfileData && getNumBranchWeights(*ProfileData) == I.getNumSuccessors())
166 return ProfileData;
167 return nullptr;
168}
169
170void extractFromBranchWeightMD32(const MDNode *ProfileData,
171 SmallVectorImpl<uint32_t> &Weights) {
172 extractFromBranchWeightMD(ProfileData, Weights);
173}
174
175void extractFromBranchWeightMD64(const MDNode *ProfileData,
176 SmallVectorImpl<uint64_t> &Weights) {
177 extractFromBranchWeightMD(ProfileData, Weights);
178}
179
180bool extractBranchWeights(const MDNode *ProfileData,
181 SmallVectorImpl<uint32_t> &Weights) {
182 if (!isBranchWeightMD(ProfileData))
183 return false;
184 extractFromBranchWeightMD(ProfileData, Weights);
185 return true;
186}
187
189 SmallVectorImpl<uint32_t> &Weights) {
190 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
191 return extractBranchWeights(ProfileData, Weights);
192}
193
195 uint64_t &FalseVal) {
196 assert((I.getOpcode() == Instruction::Br ||
197 I.getOpcode() == Instruction::Select) &&
198 "Looking for branch weights on something besides branch, select, or "
199 "switch");
200
202 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
203 if (!extractBranchWeights(ProfileData, Weights))
204 return false;
205
206 if (Weights.size() > 2)
207 return false;
208
209 TrueVal = Weights[0];
210 FalseVal = Weights[1];
211 return true;
212}
213
214bool extractProfTotalWeight(const MDNode *ProfileData, uint64_t &TotalVal) {
215 TotalVal = 0;
216 if (!ProfileData)
217 return false;
218
219 auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(0));
220 if (!ProfDataName)
221 return false;
222
223 if (ProfDataName->getString() == MDProfLabels::BranchWeights) {
224 unsigned Offset = getBranchWeightOffset(ProfileData);
225 for (unsigned Idx = Offset; Idx < ProfileData->getNumOperands(); ++Idx) {
226 auto *V = mdconst::extract<ConstantInt>(ProfileData->getOperand(Idx));
227 TotalVal += V->getValue().getZExtValue();
228 }
229 return true;
230 }
231
232 if (ProfDataName->getString() == MDProfLabels::ValueProfile &&
233 ProfileData->getNumOperands() > 3) {
234 TotalVal = mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(2))
235 ->getValue()
236 .getZExtValue();
237 return true;
238 }
239 return false;
240}
241
243 return extractProfTotalWeight(I.getMetadata(LLVMContext::MD_prof), TotalVal);
244}
245
247 MDBuilder MDB(I.getContext());
248 I.setMetadata(
249 LLVMContext::MD_prof,
250 MDNode::get(I.getContext(),
251 {MDB.createString(MDProfLabels::UnknownBranchWeightsMarker),
252 MDB.createString(PassName)}));
253}
254
256 MDBuilder MDB(F.getContext());
257 F.setMetadata(
258 LLVMContext::MD_prof,
259 MDNode::get(F.getContext(),
260 {MDB.createString(MDProfLabels::UnknownBranchWeightsMarker),
261 MDB.createString(PassName)}));
262}
263
265 if (MD.getNumOperands() != 2)
266 return false;
268}
269
271 auto *MD = I.getMetadata(LLVMContext::MD_prof);
272 if (!MD)
273 return false;
275}
276
278 bool IsExpected) {
279 MDBuilder MDB(I.getContext());
280 MDNode *BranchWeights = MDB.createBranchWeights(Weights, IsExpected);
281 I.setMetadata(LLVMContext::MD_prof, BranchWeights);
282}
283
285 std::optional<uint64_t> KnownMaxCount) {
286 uint64_t MaxCount = KnownMaxCount.has_value() ? KnownMaxCount.value()
287 : *llvm::max_element(Weights);
288 assert(MaxCount > 0 && "Bad max count");
289 uint64_t Scale = calculateCountScale(MaxCount);
290 SmallVector<uint32_t> DownscaledWeights;
291 for (const auto &ECI : Weights)
292 DownscaledWeights.push_back(scaleBranchCount(ECI, Scale));
293 return DownscaledWeights;
294}
295
297 assert(T != 0 && "Caller should guarantee");
298 auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
299 if (ProfileData == nullptr)
300 return;
301
302 auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(0));
303 if (!ProfDataName ||
304 (ProfDataName->getString() != MDProfLabels::BranchWeights &&
305 ProfDataName->getString() != MDProfLabels::ValueProfile))
306 return;
307
308 if (!hasCountTypeMD(I))
309 return;
310
311 LLVMContext &C = I.getContext();
312
313 MDBuilder MDB(C);
315 Vals.push_back(ProfileData->getOperand(0));
316 APInt APS(128, S), APT(128, T);
317 if (ProfDataName->getString() == MDProfLabels::BranchWeights &&
318 ProfileData->getNumOperands() > 0) {
319 // Using APInt::div may be expensive, but most cases should fit 64 bits.
320 APInt Val(128,
322 ProfileData->getOperand(getBranchWeightOffset(ProfileData)))
323 ->getValue()
324 .getZExtValue());
325 Val *= APS;
326 Vals.push_back(MDB.createConstant(ConstantInt::get(
327 Type::getInt32Ty(C), Val.udiv(APT).getLimitedValue(UINT32_MAX))));
328 } else if (ProfDataName->getString() == MDProfLabels::ValueProfile)
329 for (unsigned Idx = 1; Idx < ProfileData->getNumOperands(); Idx += 2) {
330 // The first value is the key of the value profile, which will not change.
331 Vals.push_back(ProfileData->getOperand(Idx));
333 mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(Idx + 1))
334 ->getValue()
335 .getZExtValue();
336 // Don't scale the magic number.
337 if (Count == NOMORE_ICP_MAGICNUM) {
338 Vals.push_back(ProfileData->getOperand(Idx + 1));
339 continue;
340 }
341 // Using APInt::div may be expensive, but most cases should fit 64 bits.
342 APInt Val(128, Count);
343 Val *= APS;
344 Vals.push_back(MDB.createConstant(ConstantInt::get(
345 Type::getInt64Ty(C), Val.udiv(APT).getLimitedValue())));
346 }
347 I.setMetadata(LLVMContext::MD_prof, MDNode::get(C, Vals));
348}
349
350} // namespace llvm
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:55
#define I(x, y, z)
Definition MD5.cpp:58
This file contains the declarations for metadata subclasses.
#define T
This file contains the declarations for profiling metadata utility functions.
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:1573
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition APInt.h:1512
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:475
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
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:163
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:154
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:1077
const MDOperand & getOperand(unsigned I) const
Definition Metadata.h:1445
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1565
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1451
bool equalsStr(StringRef Str) const
Definition Metadata.h:921
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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:298
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:297
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract(Y &&MD)
Extract a Value from Metadata, if any.
Definition Metadata.h:694
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:666
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
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 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:649
LLVM_ABI bool isExplicitlyUnknownProfileMetadata(const MDNode &MD)
LLVM_ABI MDNode * getBranchWeightMDNode(const Instruction &I)
Get the branch weights metadata node.
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.
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...
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:548
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:2012
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.
LLVM_ABI bool hasBranchWeightMD(const Instruction &I)
Checks if an instructions has Branch Weight Metadata.
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:58
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.
static bool hasCountTypeMD(const Instruction &I)
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 * BranchWeights
static LLVM_ABI const char * FunctionEntryCount
static LLVM_ABI const char * UnknownBranchWeightsMarker
static LLVM_ABI const char * ValueProfile