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