33 #define DEBUG_TYPE "lower-expect-intrinsic" 36 "Number of 'expect' intrinsic instructions handled");
52 cl::desc(
"Weight of the branch likely to be taken (default = 2000)"));
55 cl::desc(
"Weight of the branch unlikely to be taken (default = 1)"));
79 LLVMContext::MD_misexpect,
118 while (!isa<PHINode>(V)) {
119 if (
ZExtInst *ZExt = dyn_cast<ZExtInst>(V)) {
120 V = ZExt->getOperand(0);
125 if (
SExtInst *SExt = dyn_cast<SExtInst>(V)) {
126 V = SExt->getOperand(0);
132 if (!BinOp || BinOp->
getOpcode() != Instruction::Xor)
144 auto ApplyOperations = [&](
const APInt &
Value) {
147 switch (
Op->getOpcode()) {
148 case Instruction::Xor:
149 Result ^= cast<ConstantInt>(
Op->getOperand(1))->getValue();
151 case Instruction::ZExt:
152 Result = Result.
zext(
Op->getType()->getIntegerBitWidth());
154 case Instruction::SExt:
155 Result = Result.
sext(
Op->getType()->getIntegerBitWidth());
164 auto *PhiDef = cast<PHINode>(V);
168 auto GetDomConditional = [&](
unsigned i) ->
BranchInst * {
185 for (
unsigned i = 0,
e = PhiDef->getNumIncomingValues(); i !=
e; ++i) {
187 Value *PhiOpnd = PhiDef->getIncomingValue(i);
195 if (ExpectedPhiValue == ApplyOperations(CI->
getValue()))
212 auto *OpndIncomingBB = PhiDef->getIncomingBlock(i);
213 auto IsOpndComingFromSuccessor = [&](
BasicBlock *Succ) {
214 if (OpndIncomingBB == Succ)
228 LLVMContext::MD_prof,
230 else if (IsOpndComingFromSuccessor(BI->
getSuccessor(0)))
232 LLVMContext::MD_prof,
263 if (!CmpConstOperand)
271 uint64_t ValueComparedTo = 0;
272 if (CmpConstOperand) {
291 if ((ExpectedValue->
getZExtValue() == ValueComparedTo) ==
300 BSI.setMetadata(LLVMContext::MD_misexpect, ExpNode);
305 BSI.setCondition(ArgValue);
309 BSI.setMetadata(LLVMContext::MD_prof, Node);
318 return handleBrSelExpect<BranchInst>(BI);
322 bool Changed =
false;
326 if (
BranchInst *BI = dyn_cast<BranchInst>(BB.getTerminator())) {
328 ExpectIntrinsicsHandled++;
329 }
else if (
SwitchInst *
SI = dyn_cast<SwitchInst>(BB.getTerminator())) {
331 ExpectIntrinsicsHandled++;
337 for (
auto BI = BB.rbegin(), BE = BB.rend(); BI != BE;) {
343 ExpectIntrinsicsHandled++;
393 "Lower 'expect' Intrinsics",
false,
false)
396 return new LowerExpectIntrinsic();
unsigned getNumCases() const
Return the number of 'cases' in this switch instruction, excluding the default case.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
APInt sext(unsigned width) const
Sign extend to a new width.
This class represents lattice values for constants.
BinaryOps getOpcode() const
This class represents zero extension of integer types.
void push_back(const T &Elt)
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
APInt zext(unsigned width) const
Zero extend to a new width.
This class represents a function call, abstracting a target machine's calling convention.
Value * getCondition() const
LLVMContext & getContext() const
All values hold a context through their type.
BasicBlock * getSuccessor(unsigned i) const
STATISTIC(NumFunctions, "Total number of functions")
This class represents a sign extension of integer types.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
Run the pass over the function.
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...
unsigned getBitWidth() const
getBitWidth - Return the bitwidth of this constant.
Value * getArgOperand(unsigned i) const
This class represents the LLVM 'select' instruction.
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
static bool lowerExpectIntrinsic(Function &F)
unsigned getCaseIndex() const
Returns number of current case.
const APInt & getValue() const
Return the constant as an APInt value reference.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Value * getOperand(unsigned i) const
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
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 runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
A set of analyses that are preserved following a run of a transformation pass.
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
void initializeLowerExpectIntrinsicPass(PassRegistry &)
LLVM Basic Block Representation.
Conditional or Unconditional Branch instruction.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This instruction compares its operands according to the predicate given to the constructor.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
FunctionPass class - This class is used to implement most global optimizations.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
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 PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
static bool handleBrSelExpect(BrSelInst &BSI)
This is the shared class of boolean and integer constants.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
INITIALIZE_PASS(LowerExpectIntrinsic, "lower-expect", "Lower 'expect' Intrinsics", false, false) FunctionPass *llvm
bool isConditional() const
CaseIt findCaseValue(const ConstantInt *C)
Search all of the case values for the specified constant.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
void setOperand(unsigned i, Value *Val)
Class for arbitrary precision integers.
static void handlePhiDef(CallInst *Expect)
Handler for PHINodes that define the value argument to an .expect call.
static bool handleBranchExpect(BranchInst &BI)
Predicate getPredicate() const
Return the predicate for this instruction.
void setCondition(Value *V)
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
const Function * getParent() const
Return the enclosing method, or null if none.
The header file for the LowerExpectIntrinsic pass as used by the new pass manager.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
CaseIt case_default()
Returns an iterator that points to the default case.
bool isUnconditional() const
LLVM Value Representation.
A container for analyses that lazily runs them and caches their results.
static bool handleSwitchExpect(SwitchInst &SI)
void checkFrontendInstrumentation(Instruction &I)
checkClangInstrumentation - verify if llvm.expect matches PGO profile This function checks the fronte...
FunctionPass * createLowerExpectIntrinsicPass()
const BasicBlock * getParent() const