LLVM  17.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 
13 #include "llvm/IR/ProfDataUtils.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/Twine.h"
16 #include "llvm/IR/Constants.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/IR/Instructions.h"
19 #include "llvm/IR/LLVMContext.h"
20 #include "llvm/IR/Metadata.h"
23 
24 using namespace llvm;
25 
26 namespace {
27 
28 // MD_prof nodes have the following layout
29 //
30 // In general:
31 // { String name, Array of i32 }
32 //
33 // In terms of Types:
34 // { MDString, [i32, i32, ...]}
35 //
36 // Concretely for Branch Weights
37 // { "branch_weights", [i32 1, i32 10000]}
38 //
39 // We maintain some constants here to ensure that we access the branch weights
40 // correctly, and can change the behavior in the future if the layout changes
41 
42 // The index at which the weights vector starts
43 constexpr unsigned WeightsIdx = 1;
44 
45 // the minimum number of operands for MD_prof nodes with branch weights
46 constexpr unsigned MinBWOps = 3;
47 
48 bool extractWeights(const MDNode *ProfileData,
49  SmallVectorImpl<uint32_t> &Weights) {
50  // Assume preconditions are already met (i.e. this is valid metadata)
51  assert(ProfileData && "ProfileData was nullptr in extractWeights");
52  unsigned NOps = ProfileData->getNumOperands();
53 
54  assert(WeightsIdx < NOps && "Weights Index must be less than NOps.");
55  Weights.resize(NOps - WeightsIdx);
56 
57  for (unsigned Idx = WeightsIdx, E = NOps; Idx != E; ++Idx) {
58  ConstantInt *Weight =
59  mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(Idx));
60  assert(Weight && "Malformed branch_weight in MD_prof node");
61  assert(Weight->getValue().getActiveBits() <= 32 &&
62  "Too many bits for uint32_t");
63  Weights[Idx - WeightsIdx] = Weight->getZExtValue();
64  }
65  return true;
66 }
67 
68 // We may want to add support for other MD_prof types, so provide an abstraction
69 // for checking the metadata type.
70 bool isTargetMD(const MDNode *ProfData, const char *Name, unsigned MinOps) {
71  // TODO: This routine may be simplified if MD_prof used an enum instead of a
72  // string to differentiate the types of MD_prof nodes.
73  if (!ProfData || !Name || MinOps < 2)
74  return false;
75 
76  unsigned NOps = ProfData->getNumOperands();
77  if (NOps < MinOps)
78  return false;
79 
80  auto *ProfDataName = dyn_cast<MDString>(ProfData->getOperand(0));
81  if (!ProfDataName)
82  return false;
83 
84  return ProfDataName->getString().equals(Name);
85 }
86 
87 } // namespace
88 
89 namespace llvm {
90 
91 bool hasProfMD(const Instruction &I) {
92  return nullptr != I.getMetadata(LLVMContext::MD_prof);
93 }
94 
95 bool isBranchWeightMD(const MDNode *ProfileData) {
96  return isTargetMD(ProfileData, "branch_weights", MinBWOps);
97 }
98 
100  auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
101  return isBranchWeightMD(ProfileData);
102 }
103 
106 }
107 
109  auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
110  if (!isBranchWeightMD(ProfileData))
111  return nullptr;
112  return ProfileData;
113 }
114 
116  auto *ProfileData = getBranchWeightMDNode(I);
117  if (ProfileData && ProfileData->getNumOperands() == 1 + I.getNumSuccessors())
118  return ProfileData;
119  return nullptr;
120 }
121 
122 bool extractBranchWeights(const MDNode *ProfileData,
123  SmallVectorImpl<uint32_t> &Weights) {
124  if (!isBranchWeightMD(ProfileData))
125  return false;
126  return extractWeights(ProfileData, Weights);
127 }
128 
130  SmallVectorImpl<uint32_t> &Weights) {
131  auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
132  return extractBranchWeights(ProfileData, Weights);
133 }
134 
136  uint64_t &FalseVal) {
137  assert((I.getOpcode() == Instruction::Br ||
138  I.getOpcode() == Instruction::Select) &&
139  "Looking for branch weights on something besides branch, select, or "
140  "switch");
141 
142  SmallVector<uint32_t, 2> Weights;
143  auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
144  if (!extractBranchWeights(ProfileData, Weights))
145  return false;
146 
147  if (Weights.size() > 2)
148  return false;
149 
150  TrueVal = Weights[0];
151  FalseVal = Weights[1];
152  return true;
153 }
154 
155 bool extractProfTotalWeight(const MDNode *ProfileData, uint64_t &TotalVal) {
156  TotalVal = 0;
157  if (!ProfileData)
158  return false;
159 
160  auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(0));
161  if (!ProfDataName)
162  return false;
163 
164  if (ProfDataName->getString().equals("branch_weights")) {
165  for (unsigned Idx = 1; Idx < ProfileData->getNumOperands(); Idx++) {
166  auto *V = mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(Idx));
167  assert(V && "Malformed branch_weight in MD_prof node");
168  TotalVal += V->getValue().getZExtValue();
169  }
170  return true;
171  }
172 
173  if (ProfDataName->getString().equals("VP") &&
174  ProfileData->getNumOperands() > 3) {
175  TotalVal = mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(2))
176  ->getValue()
177  .getZExtValue();
178  return true;
179  }
180  return false;
181 }
182 
183 bool extractProfTotalWeight(const Instruction &I, uint64_t &TotalVal) {
184  return extractProfTotalWeight(I.getMetadata(LLVMContext::MD_prof), TotalVal);
185 }
186 
187 } // namespace llvm
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::isBranchWeightMD
bool isBranchWeightMD(const MDNode *ProfileData)
Checks if an MDNode contains Branch Weight Metadata.
Definition: ProfDataUtils.cpp:95
Metadata.h
llvm::ConstantInt::getValue
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition: Constants.h:132
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::tgtok::FalseVal
@ FalseVal
Definition: TGLexer.h:62
llvm::MDNode::getNumOperands
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1297
CommandLine.h
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:78
llvm::hasValidBranchWeightMD
bool hasValidBranchWeightMD(const Instruction &I)
Checks if an instructions has valid Branch Weight Metadata.
Definition: ProfDataUtils.cpp:104
Constants.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Twine.h
llvm::Instruction
Definition: Instruction.h:41
llvm::SmallVectorImpl::resize
void resize(size_type N)
Definition: SmallVector.h:642
BranchProbability.h
llvm::hasBranchWeightMD
bool hasBranchWeightMD(const Instruction &I)
Checks if an instructions has Branch Weight Metadata.
Definition: ProfDataUtils.cpp:99
llvm::MDNode::getOperand
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1291
uint64_t
ProfDataUtils.h
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::hasProfMD
bool hasProfMD(const Instruction &I)
Checks if an Instruction has MD_prof Metadata.
Definition: ProfDataUtils.cpp:91
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::extractProfTotalWeight
bool extractProfTotalWeight(const MDNode *ProfileData, uint64_t &TotalWeights)
Retrieve the total of all weights from MD_prof data.
Definition: ProfDataUtils.cpp:155
llvm::MDNode
Metadata node.
Definition: Metadata.h:943
llvm::getValidBranchWeightMDNode
MDNode * getValidBranchWeightMDNode(const Instruction &I)
Get the valid branch weights metadata node.
Definition: ProfDataUtils.cpp:115
llvm::ConstantInt::getZExtValue
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:141
llvm::MCID::Select
@ Select
Definition: MCInstrDesc.h:165
llvm::getBranchWeightMDNode
MDNode * getBranchWeightMDNode(const Instruction &I)
Get the branch weights metadata node.
Definition: ProfDataUtils.cpp:108
Function.h
Instructions.h
SmallVector.h
llvm::APInt::getActiveBits
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition: APInt.h:1463
llvm::SmallVectorImpl< uint32_t >
llvm::extractBranchWeights
bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
Definition: ProfDataUtils.cpp:122
LLVMContext.h
llvm::tgtok::TrueVal
@ TrueVal
Definition: TGLexer.h:62