1//===- ProfDataUtils.cpp - Utility functions for MD_prof Metadata ---------===// 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 7//===----------------------------------------------------------------------===// 9// This file implements utilities for working with Profiling Metadata. 11//===----------------------------------------------------------------------===// 27// MD_prof nodes have the following layout 30// { String name, Array of i32 } 33// { MDString, [i32, i32, ...]} 35// Concretely for Branch Weights 36// { "branch_weights", [i32 1, i32 10000]} 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 41// the minimum number of operands for MD_prof nodes with branch weights 42constexprunsigned MinBWOps = 3;
44// the minimum number of operands for MD_prof nodes with value profiles 45constexprunsigned MinVPOps = 5;
47// We may want to add support for other MD_prof types, so provide an abstraction 48// for checking the metadata type. 49bool isTargetMD(
constMDNode *ProfData,
constchar *
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. 52if (!ProfData || !
Name || MinOps < 2)
59auto *ProfDataName = dyn_cast<MDString>(ProfData->
getOperand(0));
63return ProfDataName->getString() ==
Name;
67typename =
typename std::enable_if<std::is_arithmetic_v<T>>>
68staticvoid extractFromBranchWeightMD(
constMDNode *ProfileData,
74assert(WeightsIdx < NOps &&
"Weights Index must be less than NOps.");
75 Weights.
resize(NOps - WeightsIdx);
77for (
unsignedIdx = WeightsIdx, E = NOps;
Idx != E; ++
Idx) {
79 mdconst::dyn_extract<ConstantInt>(ProfileData->
getOperand(
Idx));
80assert(Weight &&
"Malformed branch_weight in MD_prof node");
82"Too many bits for MD_prof branch_weight");
92returnI.hasMetadata(LLVMContext::MD_prof);
96return isTargetMD(ProfileData,
"branch_weights", MinBWOps);
100return isTargetMD(ProfileData,
"VP", MinVPOps);
104auto *ProfileData =
I.getMetadata(LLVMContext::MD_prof);
109auto *ProfileData =
I.getMetadata(LLVMContext::MD_prof);
110// Value profiles record count-type information. 113// Conservatively assume non CallBase instruction only get taken/not-taken 114// branch probability, so not interpret them as count. 123auto *ProfileData =
I.getMetadata(LLVMContext::MD_prof);
130auto *ProfDataName = dyn_cast<MDString>(ProfileData->
getOperand(1));
131// NOTE: if we ever have more types of branch weight provenance, 132// we need to check the string value is "expected". For now, we 133// supply a more generic API, and avoid the spurious comparisons. 134assert(ProfDataName ==
nullptr || ProfDataName->getString() ==
"expected");
135return ProfDataName !=
nullptr;
147auto *ProfileData =
I.getMetadata(LLVMContext::MD_prof);
162 extractFromBranchWeightMD(ProfileData, Weights);
167 extractFromBranchWeightMD(ProfileData, Weights);
174 extractFromBranchWeightMD(ProfileData, Weights);
180auto *ProfileData =
I.getMetadata(LLVMContext::MD_prof);
186assert((
I.getOpcode() == Instruction::Br ||
187I.getOpcode() == Instruction::Select) &&
188"Looking for branch weights on something besides branch, select, or " 192auto *ProfileData =
I.getMetadata(LLVMContext::MD_prof);
196if (Weights.
size() > 2)
199 TrueVal = Weights[0];
200 FalseVal = Weights[1];
209auto *ProfDataName = dyn_cast<MDString>(ProfileData->
getOperand(0));
213if (ProfDataName->getString() ==
"branch_weights") {
216auto *V = mdconst::extract<ConstantInt>(ProfileData->
getOperand(
Idx));
217 TotalVal += V->getValue().getZExtValue();
222if (ProfDataName->getString() ==
"VP" && ProfileData->
getNumOperands() > 3) {
223 TotalVal = mdconst::dyn_extract<ConstantInt>(ProfileData->
getOperand(2))
239I.setMetadata(LLVMContext::MD_prof, BranchWeights);
243assert(
T != 0 &&
"Caller should guarantee");
244auto *ProfileData =
I.getMetadata(LLVMContext::MD_prof);
245if (ProfileData ==
nullptr)
248auto *ProfDataName = dyn_cast<MDString>(ProfileData->
getOperand(0));
249if (!ProfDataName || (ProfDataName->getString() !=
"branch_weights" &&
250 ProfDataName->getString() !=
"VP"))
261APInt APS(128, S), APT(128,
T);
262if (ProfDataName->getString() ==
"branch_weights" &&
264// Using APInt::div may be expensive, but most cases should fit 64 bits. 266 mdconst::dyn_extract<ConstantInt>(
273 }
elseif (ProfDataName->getString() ==
"VP")
275// The first value is the key of the value profile, which will not change. 278 mdconst::dyn_extract<ConstantInt>(ProfileData->
getOperand(i + 1))
281// Don't scale the magic number. 286// Using APInt::div may be expensive, but most cases should fit 64 bits. 287APInt Val(128, Count);
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file contains the declarations for metadata subclasses.
This file contains the declarations for profiling metadata utility functions.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Class for arbitrary precision integers.
APInt udiv(const APInt &RHS) const
Unsigned division operation.
unsigned getActiveBits() const
Compute the number of active bits in the value.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
This is an important class for using LLVM in a threaded context.
ConstantAsMetadata * createConstant(Constant *C)
Return the given constant as metadata.
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
const MDOperand & getOperand(unsigned I) const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned getNumOperands() const
Return number of MDNode operands.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
bool extractProfTotalWeight(const MDNode *ProfileData, uint64_t &TotalWeights)
Retrieve the total of all weights from MD_prof data.
unsigned getBranchWeightOffset(const MDNode *ProfileData)
Return the offset to the first branch weight data.
bool isBranchWeightMD(const MDNode *ProfileData)
Checks if an MDNode contains Branch Weight Metadata.
MDNode * getBranchWeightMDNode(const Instruction &I)
Get the branch weights metadata node.
bool hasBranchWeightOrigin(const Instruction &I)
Check if Branch Weight Metadata has an "expected" field from an llvm.expect* intrinsic.
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...
MDNode * getValidBranchWeightMDNode(const Instruction &I)
Get the valid branch weights metadata node.
bool hasValidBranchWeightMD(const Instruction &I)
Checks if an instructions has valid Branch Weight Metadata.
bool isValueProfileMD(const MDNode *ProfileData)
bool hasCountTypeMD(const Instruction &I)
unsigned getNumBranchWeights(const MDNode &ProfileData)
void extractFromBranchWeightMD32(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Faster version of extractBranchWeights() that skips checks and must only be called with "branch_weigh...
bool hasProfMD(const Instruction &I)
Checks if an Instruction has MD_prof Metadata.
bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
bool hasBranchWeightMD(const Instruction &I)
Checks if an instructions has Branch Weight Metadata.
const uint64_t NOMORE_ICP_MAGICNUM
Magic number in the value profile metadata showing a target has been promoted for the instruction and...
void scaleProfData(Instruction &I, uint64_t S, uint64_t T)
Scaling the profile data attached to 'I' using the ratio of S/T.
void extractFromBranchWeightMD64(const MDNode *ProfileData, SmallVectorImpl< uint64_t > &Weights)
Faster version of extractBranchWeights() that skips checks and must only be called with "branch_weigh...