LLVM: lib/Transforms/Scalar/LowerExpectIntrinsic.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
26
27#include
28
29using namespace llvm;
30
31#define DEBUG_TYPE "lower-expect-intrinsic"
32
34 "Number of 'expect' intrinsic instructions handled");
35
36
37
38
39
40
41
42
43
44
45
46
47
50 cl::desc("Weight of the branch likely to be taken (default = 2000)"));
53 cl::desc("Weight of the branch unlikely to be taken (default = 1)"));
54
55static std::tuple<uint32_t, uint32_t>
57 if (IntrinsicID == Intrinsic::expect) {
58
61 } else {
62
64 "expect with probability must have 3 arguments");
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
78 if (!CI)
79 return false;
80
82 if (!Fn || (Fn->getIntrinsicID() != Intrinsic::expect &&
83 Fn->getIntrinsicID() != Intrinsic::expect_with_probability))
84 return false;
85
88 if (!ExpectedValue)
89 return false;
90
92 unsigned n = SI.getNumCases();
93 uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
94 std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
96
98
100 Weights[Index] = LikelyBranchWeightVal;
101
103
104 SI.setCondition(ArgValue);
106 return true;
107}
108
109
110
111
112
113
114
115
119 if (!ExpectedValue)
120 return;
121 const APInt &ExpectedPhiValue = ExpectedValue->getValue();
122 bool ExpectedValueIsLikely = true;
124
125
126
127
128 if (Fn->getIntrinsicID() == Intrinsic::expect_with_probability) {
130 double TrueProb = Confidence->getValueAPF().convertToDouble();
131 ExpectedValueIsLikely = (TrueProb > 0.5);
132 }
133
134
135
136
137
138
139
140
141
142
143
148 V = ZExt->getOperand(0);
150 continue;
151 }
152
154 V = SExt->getOperand(0);
156 continue;
157 }
158
160 if (!BinOp || BinOp->getOpcode() != Instruction::Xor)
161 return;
162
164 if (!CInt)
165 return;
166
169 }
170
171
172 auto ApplyOperations = [&](const APInt &Value) {
175 switch (Op->getOpcode()) {
176 case Instruction::Xor:
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:
187 }
188 }
189 return Result;
190 };
191
193
194
195
196 auto GetDomConditional = [&](unsigned i) -> BranchInst * {
197 BasicBlock *BB = PhiDef->getIncomingBlock(i);
200 return BI;
202 if (!BB)
203 return nullptr;
206 return nullptr;
207 return BI;
208 };
209
210
211
212
213 for (unsigned i = 0, e = PhiDef->getNumIncomingValues(); i != e; ++i) {
214
215 Value *PhiOpnd = PhiDef->getIncomingValue(i);
217 if (!CI)
218 continue;
219
220
221
222
223
224
225 const APInt &CurrentPhiValue = ApplyOperations(CI->getValue());
226 if (ExpectedValueIsLikely == (ExpectedPhiValue == CurrentPhiValue))
227 continue;
228
229 BranchInst *BI = GetDomConditional(i);
230 if (!BI)
231 continue;
232
233 MDBuilder MDB(PhiDef->getContext());
234
235
236
237
238
239
240
241
242
243 auto *OpndIncomingBB = PhiDef->getIncomingBlock(i);
244 auto IsOpndComingFromSuccessor = [&](BasicBlock *Succ) {
245 if (OpndIncomingBB == Succ)
246
247
248 return true;
249 if (OpndIncomingBB == BI->getParent() && Succ == PhiDef->getParent())
250
251
252
253 return true;
254 return false;
255 };
256 uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
257 std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) = getBranchWeight(
259 if (!ExpectedValueIsLikely)
260 std::swap(LikelyBranchWeightVal, UnlikelyBranchWeightVal);
261
262 if (IsOpndComingFromSuccessor(BI->getSuccessor(1)))
265 UnlikelyBranchWeightVal,
266 true));
267 else if (IsOpndComingFromSuccessor(BI->getSuccessor(0)))
270 LikelyBranchWeightVal,
271 true));
272 }
273}
274
275
277
278
279
280
281
282
283
284
285
286
288
292 if (!CmpI) {
295 } else {
298 return false;
299
301 if (!CmpConstOperand)
302 return false;
304 }
305
306 if (!CI)
307 return false;
308
309 uint64_t ValueComparedTo = 0;
310 if (CmpConstOperand) {
312 return false;
313 ValueComparedTo = CmpConstOperand->getZExtValue();
314 }
315
317 if (!Fn || (Fn->getIntrinsicID() != Intrinsic::expect &&
318 Fn->getIntrinsicID() != Intrinsic::expect_with_probability))
319 return false;
320
323 if (!ExpectedValue)
324 return false;
325
328
329 uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
330 std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
332
334 if ((ExpectedValue->getZExtValue() == ValueComparedTo) ==
337 LikelyBranchWeightVal, UnlikelyBranchWeightVal, true);
338 ExpectedWeights = {LikelyBranchWeightVal, UnlikelyBranchWeightVal};
339 } else {
341 LikelyBranchWeightVal, true);
342 ExpectedWeights = {UnlikelyBranchWeightVal, LikelyBranchWeightVal};
343 }
344
345 if (CmpI)
347 else
348 BSI.setCondition(ArgValue);
349
351
352 BSI.setMetadata(LLVMContext::MD_prof, Node);
353
354 return true;
355}
356
359 return false;
360
362}
363
366
368
371 ExpectIntrinsicsHandled++;
374 ExpectIntrinsicsHandled++;
375 }
376
377
378
379
382 if (!CI) {
385 ExpectIntrinsicsHandled++;
386 }
387 continue;
388 }
389
391 if (Fn && (Fn->getIntrinsicID() == Intrinsic::expect ||
392 Fn->getIntrinsicID() == Intrinsic::expect_with_probability)) {
393
394
395
401 }
402 }
403 }
404
406}
407
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 bool handleBranchExpect(BranchInst &BI)
Definition LowerExpectIntrinsic.cpp:357
static std::tuple< uint32_t, uint32_t > getBranchWeight(Intrinsic::ID IntrinsicID, CallInst *CI, int BranchCount)
Definition LowerExpectIntrinsic.cpp:56
static bool handleBrSelExpect(BrSelInst &BSI)
Definition LowerExpectIntrinsic.cpp:276
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)
Definition LowerExpectIntrinsic.cpp:76
static bool lowerExpectIntrinsic(Function &F)
Definition LowerExpectIntrinsic.cpp:364
static void handlePhiDef(CallInst *Expect)
Handler for PHINodes that define the value argument to an @llvm.expect call.
Definition LowerExpectIntrinsic.cpp:116
The header file for the LowerExpectIntrinsic pass as used by the new pass manager.
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)
Class for arbitrary precision integers.
LLVM Basic Block Representation.
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...
BinaryOps getOpcode() const
Conditional or Unconditional Branch instruction.
bool isConditional() const
BasicBlock * getSuccessor(unsigned i) const
bool isUnconditional() const
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.
Predicate getPredicate() const
Return the predicate for this instruction.
This is the shared class of boolean and integer constants.
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
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.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
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.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
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.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
This class represents zero extension of integer types.
const ParentTy * getParent() const
#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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
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...
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)
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
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.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
Run the pass over the function.
Definition LowerExpectIntrinsic.cpp:408