LLVM 24.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
14#include "ScalarOptions.h"
16#include "llvm/ADT/Statistic.h"
17#include "llvm/IR/BasicBlock.h"
18#include "llvm/IR/Constants.h"
19#include "llvm/IR/Function.h"
21#include "llvm/IR/Intrinsics.h"
22#include "llvm/IR/LLVMContext.h"
23#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
44static std::tuple<uint32_t, uint32_t>
45getBranchWeight(Intrinsic::ID IntrinsicID, CallInst *CI, int BranchCount) {
46 const ScalarOptions &Opts = ScalarOptions::Global;
47 if (IntrinsicID == Intrinsic::expect) {
48 // __builtin_expect
49 return std::make_tuple(Opts.likely_branch_weight,
50 Opts.unlikely_branch_weight);
51 } else {
52 // __builtin_expect_with_probability
53 assert(CI->getNumOperands() >= 3 &&
54 "expect with probability must have 3 arguments");
55 auto *Confidence = cast<ConstantFP>(CI->getArgOperand(2));
56 double TrueProb = Confidence->getValueAPF().convertToDouble();
57 assert((TrueProb >= 0.0 && TrueProb <= 1.0) &&
58 "probability value must be in the range [0.0, 1.0]");
59 double FalseProb = (1.0 - TrueProb) / (BranchCount - 1);
60 uint32_t LikelyBW = ceil((TrueProb * (double)(INT32_MAX - 1)) + 1.0);
61 uint32_t UnlikelyBW = ceil((FalseProb * (double)(INT32_MAX - 1)) + 1.0);
62 return std::make_tuple(LikelyBW, UnlikelyBW);
63 }
64}
65
67 CallInst *CI = dyn_cast<CallInst>(SI.getCondition());
68 if (!CI)
69 return false;
70
71 Function *Fn = CI->getCalledFunction();
72 if (!Fn || (Fn->getIntrinsicID() != Intrinsic::expect &&
73 Fn->getIntrinsicID() != Intrinsic::expect_with_probability))
74 return false;
75
76 Value *ArgValue = CI->getArgOperand(0);
77 ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1));
78 if (!ExpectedValue)
79 return false;
80
81 SwitchInst::CaseHandle Case = *SI.findCaseValue(ExpectedValue);
82 unsigned n = SI.getNumCases(); // +1 for default case.
83 uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
84 std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
85 getBranchWeight(Fn->getIntrinsicID(), CI, n + 1);
86
87 SmallVector<uint32_t, 16> Weights(n + 1, UnlikelyBranchWeightVal);
88
89 uint64_t Index = (Case == *SI.case_default()) ? 0 : Case.getCaseIndex() + 1;
90 Weights[Index] = LikelyBranchWeightVal;
91
92 misexpect::checkExpectAnnotations(SI, Weights, /*IsFrontend=*/true);
93
94 SI.setCondition(ArgValue);
95 setBranchWeights(SI, Weights, /*IsExpected=*/true);
96 return true;
97}
98
99/// Handler for PHINodes that define the value argument to an
100/// @llvm.expect call.
101///
102/// If the operand of the phi has a constant value and it 'contradicts'
103/// with the expected value of phi def, then the corresponding incoming
104/// edge of the phi is unlikely to be taken. Using that information,
105/// the branch probability info for the originating branch can be inferred.
106static void handlePhiDef(CallInst *Expect) {
107 Value &Arg = *Expect->getArgOperand(0);
108 ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(Expect->getArgOperand(1));
109 if (!ExpectedValue)
110 return;
111 const APInt &ExpectedPhiValue = ExpectedValue->getValue();
112 bool ExpectedValueIsLikely = true;
113 Function *Fn = Expect->getCalledFunction();
114 // If the function is expect_with_probability, then we need to take the
115 // probability into consideration. For example, in
116 // expect.with.probability.i64(i64 %a, i64 1, double 0.0), the
117 // "ExpectedValue" 1 is unlikely. This affects probability propagation later.
118 if (Fn->getIntrinsicID() == Intrinsic::expect_with_probability) {
119 auto *Confidence = cast<ConstantFP>(Expect->getArgOperand(2));
120 double TrueProb = Confidence->getValueAPF().convertToDouble();
121 ExpectedValueIsLikely = (TrueProb > 0.5);
122 }
123
124 // Walk up in backward a list of instructions that
125 // have 'copy' semantics by 'stripping' the copies
126 // until a PHI node or an instruction of unknown kind
127 // is reached. Negation via xor is also handled.
128 //
129 // C = PHI(...);
130 // B = C;
131 // A = B;
132 // D = __builtin_expect(A, 0);
133 //
134 Value *V = &Arg;
136 while (!isa<PHINode>(V)) {
137 if (ZExtInst *ZExt = dyn_cast<ZExtInst>(V)) {
138 V = ZExt->getOperand(0);
139 Operations.push_back(ZExt);
140 continue;
141 }
142
143 if (SExtInst *SExt = dyn_cast<SExtInst>(V)) {
144 V = SExt->getOperand(0);
145 Operations.push_back(SExt);
146 continue;
147 }
148
150 if (!BinOp || BinOp->getOpcode() != Instruction::Xor)
151 return;
152
154 if (!CInt)
155 return;
156
157 V = BinOp->getOperand(0);
158 Operations.push_back(BinOp);
159 }
160
161 // Executes the recorded operations on input 'Value'.
162 auto ApplyOperations = [&](const APInt &Value) {
163 APInt Result = Value;
164 for (auto *Op : llvm::reverse(Operations)) {
165 switch (Op->getOpcode()) {
166 case Instruction::Xor:
167 Result ^= cast<ConstantInt>(Op->getOperand(1))->getValue();
168 break;
169 case Instruction::ZExt:
170 Result = Result.zext(Op->getType()->getIntegerBitWidth());
171 break;
172 case Instruction::SExt:
173 Result = Result.sext(Op->getType()->getIntegerBitWidth());
174 break;
175 default:
176 llvm_unreachable("Unexpected operation");
177 }
178 }
179 return Result;
180 };
181
182 auto *PhiDef = cast<PHINode>(V);
183
184 // Get the first dominating conditional branch of the operand
185 // i's incoming block.
186 auto GetDomConditional = [&](unsigned i) -> CondBrInst * {
187 BasicBlock *BB = PhiDef->getIncomingBlock(i);
189 return BI;
190 BB = BB->getSinglePredecessor();
191 if (!BB)
192 return nullptr;
194 };
195
196 // Now walk through all Phi operands to find phi oprerands with values
197 // conflicting with the expected phi output value. Any such operand
198 // indicates the incoming edge to that operand is unlikely.
199 for (unsigned i = 0, e = PhiDef->getNumIncomingValues(); i != e; ++i) {
200
201 Value *PhiOpnd = PhiDef->getIncomingValue(i);
202 ConstantInt *CI = dyn_cast<ConstantInt>(PhiOpnd);
203 if (!CI)
204 continue;
205
206 // Not an interesting case when IsUnlikely is false -- we can not infer
207 // anything useful when:
208 // (1) We expect some phi output and the operand value matches it, or
209 // (2) We don't expect some phi output (i.e. the "ExpectedValue" has low
210 // probability) and the operand value doesn't match that.
211 const APInt &CurrentPhiValue = ApplyOperations(CI->getValue());
212 if (ExpectedValueIsLikely == (ExpectedPhiValue == CurrentPhiValue))
213 continue;
214
215 CondBrInst *BI = GetDomConditional(i);
216 if (!BI)
217 continue;
218
219 MDBuilder MDB(PhiDef->getContext());
220
221 // There are two situations in which an operand of the PhiDef comes
222 // from a given successor of a branch instruction BI.
223 // 1) When the incoming block of the operand is the successor block;
224 // 2) When the incoming block is BI's enclosing block and the
225 // successor is the PhiDef's enclosing block.
226 //
227 // Returns true if the operand which comes from OpndIncomingBB
228 // comes from outgoing edge of BI that leads to Succ block.
229 auto *OpndIncomingBB = PhiDef->getIncomingBlock(i);
230 auto IsOpndComingFromSuccessor = [&](BasicBlock *Succ) {
231 if (OpndIncomingBB == Succ)
232 // If this successor is the incoming block for this
233 // Phi operand, then this successor does lead to the Phi.
234 return true;
235 if (OpndIncomingBB == BI->getParent() && Succ == PhiDef->getParent())
236 // Otherwise, if the edge is directly from the branch
237 // to the Phi, this successor is the one feeding this
238 // Phi operand.
239 return true;
240 return false;
241 };
242 uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
243 std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) = getBranchWeight(
244 Expect->getCalledFunction()->getIntrinsicID(), Expect, 2);
245 if (!ExpectedValueIsLikely)
246 std::swap(LikelyBranchWeightVal, UnlikelyBranchWeightVal);
247
248 if (IsOpndComingFromSuccessor(BI->getSuccessor(1)))
249 BI->setMetadata(LLVMContext::MD_prof,
250 MDB.createBranchWeights(LikelyBranchWeightVal,
251 UnlikelyBranchWeightVal,
252 /*IsExpected=*/true));
253 else if (IsOpndComingFromSuccessor(BI->getSuccessor(0)))
254 BI->setMetadata(LLVMContext::MD_prof,
255 MDB.createBranchWeights(UnlikelyBranchWeightVal,
256 LikelyBranchWeightVal,
257 /*IsExpected=*/true));
258 }
259}
260
261// Handle both CondBrInst and SelectInst.
262template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {
263
264 // Handle non-optimized IR code like:
265 // %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1)
266 // %tobool = icmp ne i64 %expval, 0
267 // br i1 %tobool, label %if.then, label %if.end
268 //
269 // Or the following simpler case:
270 // %expval = call i1 @llvm.expect.i1(i1 %cmp, i1 1)
271 // br i1 %expval, label %if.then, label %if.end
272
273 CallInst *CI;
274
275 ICmpInst *CmpI = dyn_cast<ICmpInst>(BSI.getCondition());
277 ConstantInt *CmpConstOperand = nullptr;
278 if (!CmpI) {
279 CI = dyn_cast<CallInst>(BSI.getCondition());
281 } else {
282 Predicate = CmpI->getPredicate();
284 return false;
285
286 CmpConstOperand = dyn_cast<ConstantInt>(CmpI->getOperand(1));
287 if (!CmpConstOperand)
288 return false;
289 CI = dyn_cast<CallInst>(CmpI->getOperand(0));
290 }
291
292 if (!CI)
293 return false;
294
295 uint64_t ValueComparedTo = 0;
296 if (CmpConstOperand) {
297 if (CmpConstOperand->getBitWidth() > 64)
298 return false;
299 ValueComparedTo = CmpConstOperand->getZExtValue();
300 }
301
302 Function *Fn = CI->getCalledFunction();
303 if (!Fn || (Fn->getIntrinsicID() != Intrinsic::expect &&
304 Fn->getIntrinsicID() != Intrinsic::expect_with_probability))
305 return false;
306
307 Value *ArgValue = CI->getArgOperand(0);
308 ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1));
309 if (!ExpectedValue)
310 return false;
311
312 MDBuilder MDB(CI->getContext());
313 MDNode *Node;
314
315 uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
316 std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
317 getBranchWeight(Fn->getIntrinsicID(), CI, 2);
318
319 SmallVector<uint32_t, 4> ExpectedWeights;
320 if ((ExpectedValue->getZExtValue() == ValueComparedTo) ==
323 LikelyBranchWeightVal, UnlikelyBranchWeightVal, /*IsExpected=*/true);
324 ExpectedWeights = {LikelyBranchWeightVal, UnlikelyBranchWeightVal};
325 } else {
326 Node = MDB.createBranchWeights(UnlikelyBranchWeightVal,
327 LikelyBranchWeightVal, /*IsExpected=*/true);
328 ExpectedWeights = {UnlikelyBranchWeightVal, LikelyBranchWeightVal};
329 }
330
331 if (CmpI)
332 CmpI->setOperand(0, ArgValue);
333 else
334 BSI.setCondition(ArgValue);
335
336 misexpect::checkFrontendInstrumentation(BSI, ExpectedWeights);
337
338 BSI.setMetadata(LLVMContext::MD_prof, Node);
339
340 return true;
341}
342
344 bool Changed = false;
345
346 for (BasicBlock &BB : F) {
347 // Create "block_weights" metadata.
348 if (CondBrInst *BI = dyn_cast<CondBrInst>(BB.getTerminator())) {
350 ExpectIntrinsicsHandled++;
351 } else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB.getTerminator())) {
353 ExpectIntrinsicsHandled++;
354 }
355
356 // Remove llvm.expect intrinsics. Iterate backwards in order
357 // to process select instructions before the intrinsic gets
358 // removed.
360 CallInst *CI = dyn_cast<CallInst>(&Inst);
361 if (!CI) {
362 if (SelectInst *SI = dyn_cast<SelectInst>(&Inst)) {
363 if (handleBrSelExpect(*SI))
364 ExpectIntrinsicsHandled++;
365 }
366 continue;
367 }
368
369 Function *Fn = CI->getCalledFunction();
370 if (Fn && (Fn->getIntrinsicID() == Intrinsic::expect ||
371 Fn->getIntrinsicID() == Intrinsic::expect_with_probability)) {
372 // Before erasing the llvm.expect, walk backward to find
373 // phi that define llvm.expect's first arg, and
374 // infer branch probability:
375 handlePhiDef(CI);
376 Value *Exp = CI->getArgOperand(0);
377 CI->replaceAllUsesWith(Exp);
378 CI->eraseFromParent();
379 Changed = true;
380 }
381 }
382 }
383
384 return Changed;
385}
386
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static std::tuple< uint32_t, uint32_t > getBranchWeight(Intrinsic::ID IntrinsicID, CallInst *CI, int BranchCount)
static bool handleBrSelExpect(BrSelInst &BSI)
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; assumes that the block is well-formed.
Definition BasicBlock.h:237
BinaryOps getOpcode() const
Definition InstrTypes.h:409
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:740
@ ICMP_NE
not equal
Definition InstrTypes.h:762
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:828
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:247
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:1081
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:260
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.
LLVM_ABI 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...
LLVM_ABI 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.
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:649
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:880
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
Run the pass over the function.