LLVM 23.0.0git
LowerExpectIntrinsic.cpp
Go to the documentation of this file.
1//===- LowerExpectIntrinsic.cpp - Lower expect intrinsic ------------------===//
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 pass lowers the 'expect' intrinsic to LLVM metadata.
10//
11//===----------------------------------------------------------------------===//
12
15#include "llvm/ADT/Statistic.h"
16#include "llvm/IR/BasicBlock.h"
17#include "llvm/IR/Constants.h"
18#include "llvm/IR/Function.h"
20#include "llvm/IR/Intrinsics.h"
21#include "llvm/IR/LLVMContext.h"
22#include "llvm/IR/MDBuilder.h"
26
27#include <cmath>
28
29using namespace llvm;
30
31#define DEBUG_TYPE "lower-expect-intrinsic"
32
33STATISTIC(ExpectIntrinsicsHandled,
34 "Number of 'expect' intrinsic instructions handled");
35
36// These default values are chosen to represent an extremely skewed outcome for
37// a condition, but they leave some room for interpretation by later passes.
38//
39// If the documentation for __builtin_expect() was made explicit that it should
40// only be used in extreme cases, we could make this ratio higher. As it stands,
41// programmers may be using __builtin_expect() / llvm.expect to annotate that a
42// branch is likely or unlikely to be taken.
43
44// WARNING: these values are internal implementation detail of the pass.
45// They should not be exposed to the outside of the pass, front-end codegen
46// should emit @llvm.expect intrinsics instead of using these weights directly.
47// Transforms should use TargetTransformInfo's getPredictableBranchThreshold().
49 "likely-branch-weight", cl::Hidden, cl::init(2000),
50 cl::desc("Weight of the branch likely to be taken (default = 2000)"));
52 "unlikely-branch-weight", cl::Hidden, cl::init(1),
53 cl::desc("Weight of the branch unlikely to be taken (default = 1)"));
54
55static std::tuple<uint32_t, uint32_t>
56getBranchWeight(Intrinsic::ID IntrinsicID, CallInst *CI, int BranchCount) {
57 if (IntrinsicID == Intrinsic::expect) {
58 // __builtin_expect
59 return std::make_tuple(LikelyBranchWeight.getValue(),
60 UnlikelyBranchWeight.getValue());
61 } else {
62 // __builtin_expect_with_probability
63 assert(CI->getNumOperands() >= 3 &&
64 "expect with probability must have 3 arguments");
65 auto *Confidence = cast<ConstantFP>(CI->getArgOperand(2));
66 double TrueProb = Confidence->getValueAPF().convertToDouble();
67 assert((TrueProb >= 0.0 && TrueProb <= 1.0) &&
68 "probability value must be in the range [0.0, 1.0]");
69 double FalseProb = (1.0 - TrueProb) / (BranchCount - 1);
70 uint32_t LikelyBW = ceil((TrueProb * (double)(INT32_MAX - 1)) + 1.0);
71 uint32_t UnlikelyBW = ceil((FalseProb * (double)(INT32_MAX - 1)) + 1.0);
72 return std::make_tuple(LikelyBW, UnlikelyBW);
73 }
74}
75
77 CallInst *CI = dyn_cast<CallInst>(SI.getCondition());
78 if (!CI)
79 return false;
80
81 Function *Fn = CI->getCalledFunction();
82 if (!Fn || (Fn->getIntrinsicID() != Intrinsic::expect &&
83 Fn->getIntrinsicID() != Intrinsic::expect_with_probability))
84 return false;
85
86 Value *ArgValue = CI->getArgOperand(0);
87 ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1));
88 if (!ExpectedValue)
89 return false;
90
91 SwitchInst::CaseHandle Case = *SI.findCaseValue(ExpectedValue);
92 unsigned n = SI.getNumCases(); // +1 for default case.
93 uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
94 std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
95 getBranchWeight(Fn->getIntrinsicID(), CI, n + 1);
96
97 SmallVector<uint32_t, 16> Weights(n + 1, UnlikelyBranchWeightVal);
98
99 uint64_t Index = (Case == *SI.case_default()) ? 0 : Case.getCaseIndex() + 1;
100 Weights[Index] = LikelyBranchWeightVal;
101
102 misexpect::checkExpectAnnotations(SI, Weights, /*IsFrontend=*/true);
103
104 SI.setCondition(ArgValue);
105 setBranchWeights(SI, Weights, /*IsExpected=*/true);
106 return true;
107}
108
109/// Handler for PHINodes that define the value argument to an
110/// @llvm.expect call.
111///
112/// If the operand of the phi has a constant value and it 'contradicts'
113/// with the expected value of phi def, then the corresponding incoming
114/// edge of the phi is unlikely to be taken. Using that information,
115/// the branch probability info for the originating branch can be inferred.
116static void handlePhiDef(CallInst *Expect) {
117 Value &Arg = *Expect->getArgOperand(0);
118 ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(Expect->getArgOperand(1));
119 if (!ExpectedValue)
120 return;
121 const APInt &ExpectedPhiValue = ExpectedValue->getValue();
122 bool ExpectedValueIsLikely = true;
123 Function *Fn = Expect->getCalledFunction();
124 // If the function is expect_with_probability, then we need to take the
125 // probability into consideration. For example, in
126 // expect.with.probability.i64(i64 %a, i64 1, double 0.0), the
127 // "ExpectedValue" 1 is unlikely. This affects probability propagation later.
128 if (Fn->getIntrinsicID() == Intrinsic::expect_with_probability) {
129 auto *Confidence = cast<ConstantFP>(Expect->getArgOperand(2));
130 double TrueProb = Confidence->getValueAPF().convertToDouble();
131 ExpectedValueIsLikely = (TrueProb > 0.5);
132 }
133
134 // Walk up in backward a list of instructions that
135 // have 'copy' semantics by 'stripping' the copies
136 // until a PHI node or an instruction of unknown kind
137 // is reached. Negation via xor is also handled.
138 //
139 // C = PHI(...);
140 // B = C;
141 // A = B;
142 // D = __builtin_expect(A, 0);
143 //
144 Value *V = &Arg;
146 while (!isa<PHINode>(V)) {
147 if (ZExtInst *ZExt = dyn_cast<ZExtInst>(V)) {
148 V = ZExt->getOperand(0);
149 Operations.push_back(ZExt);
150 continue;
151 }
152
153 if (SExtInst *SExt = dyn_cast<SExtInst>(V)) {
154 V = SExt->getOperand(0);
155 Operations.push_back(SExt);
156 continue;
157 }
158
160 if (!BinOp || BinOp->getOpcode() != Instruction::Xor)
161 return;
162
164 if (!CInt)
165 return;
166
167 V = BinOp->getOperand(0);
168 Operations.push_back(BinOp);
169 }
170
171 // Executes the recorded operations on input 'Value'.
172 auto ApplyOperations = [&](const APInt &Value) {
173 APInt Result = Value;
174 for (auto *Op : llvm::reverse(Operations)) {
175 switch (Op->getOpcode()) {
176 case Instruction::Xor:
177 Result ^= cast<ConstantInt>(Op->getOperand(1))->getValue();
178 break;
179 case Instruction::ZExt:
180 Result = Result.zext(Op->getType()->getIntegerBitWidth());
181 break;
182 case Instruction::SExt:
183 Result = Result.sext(Op->getType()->getIntegerBitWidth());
184 break;
185 default:
186 llvm_unreachable("Unexpected operation");
187 }
188 }
189 return Result;
190 };
191
192 auto *PhiDef = cast<PHINode>(V);
193
194 // Get the first dominating conditional branch of the operand
195 // i's incoming block.
196 auto GetDomConditional = [&](unsigned i) -> CondBrInst * {
197 BasicBlock *BB = PhiDef->getIncomingBlock(i);
199 return BI;
200 BB = BB->getSinglePredecessor();
201 if (!BB)
202 return nullptr;
204 };
205
206 // Now walk through all Phi operands to find phi oprerands with values
207 // conflicting with the expected phi output value. Any such operand
208 // indicates the incoming edge to that operand is unlikely.
209 for (unsigned i = 0, e = PhiDef->getNumIncomingValues(); i != e; ++i) {
210
211 Value *PhiOpnd = PhiDef->getIncomingValue(i);
212 ConstantInt *CI = dyn_cast<ConstantInt>(PhiOpnd);
213 if (!CI)
214 continue;
215
216 // Not an interesting case when IsUnlikely is false -- we can not infer
217 // anything useful when:
218 // (1) We expect some phi output and the operand value matches it, or
219 // (2) We don't expect some phi output (i.e. the "ExpectedValue" has low
220 // probability) and the operand value doesn't match that.
221 const APInt &CurrentPhiValue = ApplyOperations(CI->getValue());
222 if (ExpectedValueIsLikely == (ExpectedPhiValue == CurrentPhiValue))
223 continue;
224
225 CondBrInst *BI = GetDomConditional(i);
226 if (!BI)
227 continue;
228
229 MDBuilder MDB(PhiDef->getContext());
230
231 // There are two situations in which an operand of the PhiDef comes
232 // from a given successor of a branch instruction BI.
233 // 1) When the incoming block of the operand is the successor block;
234 // 2) When the incoming block is BI's enclosing block and the
235 // successor is the PhiDef's enclosing block.
236 //
237 // Returns true if the operand which comes from OpndIncomingBB
238 // comes from outgoing edge of BI that leads to Succ block.
239 auto *OpndIncomingBB = PhiDef->getIncomingBlock(i);
240 auto IsOpndComingFromSuccessor = [&](BasicBlock *Succ) {
241 if (OpndIncomingBB == Succ)
242 // If this successor is the incoming block for this
243 // Phi operand, then this successor does lead to the Phi.
244 return true;
245 if (OpndIncomingBB == BI->getParent() && Succ == PhiDef->getParent())
246 // Otherwise, if the edge is directly from the branch
247 // to the Phi, this successor is the one feeding this
248 // Phi operand.
249 return true;
250 return false;
251 };
252 uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
253 std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) = getBranchWeight(
254 Expect->getCalledFunction()->getIntrinsicID(), Expect, 2);
255 if (!ExpectedValueIsLikely)
256 std::swap(LikelyBranchWeightVal, UnlikelyBranchWeightVal);
257
258 if (IsOpndComingFromSuccessor(BI->getSuccessor(1)))
259 BI->setMetadata(LLVMContext::MD_prof,
260 MDB.createBranchWeights(LikelyBranchWeightVal,
261 UnlikelyBranchWeightVal,
262 /*IsExpected=*/true));
263 else if (IsOpndComingFromSuccessor(BI->getSuccessor(0)))
264 BI->setMetadata(LLVMContext::MD_prof,
265 MDB.createBranchWeights(UnlikelyBranchWeightVal,
266 LikelyBranchWeightVal,
267 /*IsExpected=*/true));
268 }
269}
270
271// Handle both CondBrInst and SelectInst.
272template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {
273
274 // Handle non-optimized IR code like:
275 // %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1)
276 // %tobool = icmp ne i64 %expval, 0
277 // br i1 %tobool, label %if.then, label %if.end
278 //
279 // Or the following simpler case:
280 // %expval = call i1 @llvm.expect.i1(i1 %cmp, i1 1)
281 // br i1 %expval, label %if.then, label %if.end
282
283 CallInst *CI;
284
285 ICmpInst *CmpI = dyn_cast<ICmpInst>(BSI.getCondition());
287 ConstantInt *CmpConstOperand = nullptr;
288 if (!CmpI) {
289 CI = dyn_cast<CallInst>(BSI.getCondition());
291 } else {
292 Predicate = CmpI->getPredicate();
294 return false;
295
296 CmpConstOperand = dyn_cast<ConstantInt>(CmpI->getOperand(1));
297 if (!CmpConstOperand)
298 return false;
299 CI = dyn_cast<CallInst>(CmpI->getOperand(0));
300 }
301
302 if (!CI)
303 return false;
304
305 uint64_t ValueComparedTo = 0;
306 if (CmpConstOperand) {
307 if (CmpConstOperand->getBitWidth() > 64)
308 return false;
309 ValueComparedTo = CmpConstOperand->getZExtValue();
310 }
311
312 Function *Fn = CI->getCalledFunction();
313 if (!Fn || (Fn->getIntrinsicID() != Intrinsic::expect &&
314 Fn->getIntrinsicID() != Intrinsic::expect_with_probability))
315 return false;
316
317 Value *ArgValue = CI->getArgOperand(0);
318 ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1));
319 if (!ExpectedValue)
320 return false;
321
322 MDBuilder MDB(CI->getContext());
323 MDNode *Node;
324
325 uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
326 std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
327 getBranchWeight(Fn->getIntrinsicID(), CI, 2);
328
329 SmallVector<uint32_t, 4> ExpectedWeights;
330 if ((ExpectedValue->getZExtValue() == ValueComparedTo) ==
333 LikelyBranchWeightVal, UnlikelyBranchWeightVal, /*IsExpected=*/true);
334 ExpectedWeights = {LikelyBranchWeightVal, UnlikelyBranchWeightVal};
335 } else {
336 Node = MDB.createBranchWeights(UnlikelyBranchWeightVal,
337 LikelyBranchWeightVal, /*IsExpected=*/true);
338 ExpectedWeights = {UnlikelyBranchWeightVal, LikelyBranchWeightVal};
339 }
340
341 if (CmpI)
342 CmpI->setOperand(0, ArgValue);
343 else
344 BSI.setCondition(ArgValue);
345
346 misexpect::checkFrontendInstrumentation(BSI, ExpectedWeights);
347
348 BSI.setMetadata(LLVMContext::MD_prof, Node);
349
350 return true;
351}
352
354 bool Changed = false;
355
356 for (BasicBlock &BB : F) {
357 // Create "block_weights" metadata.
358 if (CondBrInst *BI = dyn_cast<CondBrInst>(BB.getTerminator())) {
360 ExpectIntrinsicsHandled++;
361 } else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB.getTerminator())) {
363 ExpectIntrinsicsHandled++;
364 }
365
366 // Remove llvm.expect intrinsics. Iterate backwards in order
367 // to process select instructions before the intrinsic gets
368 // removed.
370 CallInst *CI = dyn_cast<CallInst>(&Inst);
371 if (!CI) {
372 if (SelectInst *SI = dyn_cast<SelectInst>(&Inst)) {
373 if (handleBrSelExpect(*SI))
374 ExpectIntrinsicsHandled++;
375 }
376 continue;
377 }
378
379 Function *Fn = CI->getCalledFunction();
380 if (Fn && (Fn->getIntrinsicID() == Intrinsic::expect ||
381 Fn->getIntrinsicID() == Intrinsic::expect_with_probability)) {
382 // Before erasing the llvm.expect, walk backward to find
383 // phi that define llvm.expect's first arg, and
384 // infer branch probability:
385 handlePhiDef(CI);
386 Value *Exp = CI->getArgOperand(0);
387 CI->replaceAllUsesWith(Exp);
388 CI->eraseFromParent();
389 Changed = true;
390 }
391 }
392 }
393
394 return Changed;
395}
396
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< uint32_t > UnlikelyBranchWeight("unlikely-branch-weight", cl::Hidden, cl::init(1), cl::desc("Weight of the branch unlikely to be taken (default = 1)"))
static std::tuple< uint32_t, uint32_t > getBranchWeight(Intrinsic::ID IntrinsicID, CallInst *CI, int BranchCount)
static bool handleBrSelExpect(BrSelInst &BSI)
static cl::opt< uint32_t > LikelyBranchWeight("likely-branch-weight", cl::Hidden, cl::init(2000), cl::desc("Weight of the branch likely to be taken (default = 2000)"))
static bool handleSwitchExpect(SwitchInst &SI)
static bool lowerExpectIntrinsic(Function &F)
static void handlePhiDef(CallInst *Expect)
Handler for PHINodes that define the value argument to an @llvm.expect call.
The header file for the LowerExpectIntrinsic pass as used by the new pass manager.
#define F(x, y, z)
Definition MD5.cpp:54
This file contains the declarations for profiling metadata utility functions.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
Class for arbitrary precision integers.
Definition APInt.h:78
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition BasicBlock.h:233
BinaryOps getOpcode() const
Definition InstrTypes.h:374
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:676
@ ICMP_NE
not equal
Definition InstrTypes.h:698
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:765
Conditional Branch instruction.
BasicBlock * getSuccessor(unsigned i) const
This is the shared class of boolean and integer constants.
Definition Constants.h:87
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
Definition Constants.h:162
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
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition Function.h:246
This instruction compares its operands according to the predicate given to the constructor.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
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
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
unsigned getCaseIndex() const
Returns number of current case.
Multiway switch.
void setOperand(unsigned i, Value *Val)
Definition User.h:212
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:259
This class represents zero extension of integer types.
const ParentTy * getParent() const
Definition ilist_node.h:34
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
void checkExpectAnnotations(const Instruction &I, ArrayRef< uint32_t > ExistingWeights, bool IsFrontend)
checkExpectAnnotations - compares PGO counters to the thresholds used for llvm.expect and warns if th...
void checkFrontendInstrumentation(const Instruction &I, ArrayRef< uint32_t > ExpectedWeights)
checkFrontendInstrumentation - compares PGO counters to the thresholds used for llvm....
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:634
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 reverse(ContainerTy &&C)
Definition STLExtras.h:408
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
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:872
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
Run the pass over the function.