31#define DEBUG_TYPE "lower-expect-intrinsic"
34 "Number of 'expect' intrinsic instructions handled");
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)"));
55static std::tuple<uint32_t, uint32_t>
57 if (IntrinsicID == Intrinsic::expect) {
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);
92 unsigned n =
SI.getNumCases();
93 uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
94 std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
100 Weights[Index] = LikelyBranchWeightVal;
104 SI.setCondition(ArgValue);
122 bool ExpectedValueIsLikely =
true;
130 double TrueProb = Confidence->getValueAPF().convertToDouble();
131 ExpectedValueIsLikely = (TrueProb > 0.5);
148 V = ZExt->getOperand(0);
154 V = SExt->getOperand(0);
160 if (!BinOp || BinOp->
getOpcode() != Instruction::Xor)
172 auto ApplyOperations = [&](
const APInt &
Value) {
175 switch (
Op->getOpcode()) {
176 case Instruction::Xor:
179 case Instruction::ZExt:
180 Result = Result.zext(
Op->getType()->getIntegerBitWidth());
182 case Instruction::SExt:
183 Result = Result.sext(
Op->getType()->getIntegerBitWidth());
196 auto GetDomConditional = [&](
unsigned i) ->
CondBrInst * {
209 for (
unsigned i = 0, e = PhiDef->getNumIncomingValues(); i != e; ++i) {
211 Value *PhiOpnd = PhiDef->getIncomingValue(i);
221 const APInt &CurrentPhiValue = ApplyOperations(CI->
getValue());
222 if (ExpectedValueIsLikely == (ExpectedPhiValue == CurrentPhiValue))
239 auto *OpndIncomingBB = PhiDef->getIncomingBlock(i);
240 auto IsOpndComingFromSuccessor = [&](
BasicBlock *Succ) {
241 if (OpndIncomingBB == Succ)
245 if (OpndIncomingBB == BI->
getParent() && Succ == PhiDef->getParent())
252 uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
253 std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
getBranchWeight(
255 if (!ExpectedValueIsLikely)
256 std::swap(LikelyBranchWeightVal, UnlikelyBranchWeightVal);
261 UnlikelyBranchWeightVal,
263 else if (IsOpndComingFromSuccessor(BI->
getSuccessor(0)))
266 LikelyBranchWeightVal,
297 if (!CmpConstOperand)
306 if (CmpConstOperand) {
325 uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
326 std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
330 if ((ExpectedValue->
getZExtValue() == ValueComparedTo) ==
333 LikelyBranchWeightVal, UnlikelyBranchWeightVal,
true);
334 ExpectedWeights = {LikelyBranchWeightVal, UnlikelyBranchWeightVal};
337 LikelyBranchWeightVal,
true);
338 ExpectedWeights = {UnlikelyBranchWeightVal, LikelyBranchWeightVal};
344 BSI.setCondition(ArgValue);
348 BSI.setMetadata(LLVMContext::MD_prof,
Node);
360 ExpectIntrinsicsHandled++;
363 ExpectIntrinsicsHandled++;
374 ExpectIntrinsicsHandled++;
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.
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
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.
Conditional Branch instruction.
BasicBlock * getSuccessor(unsigned i) const
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.
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<X> - 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<X> - 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<X> - 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.