LLVM  6.0.0svn
LowerGuardIntrinsic.cpp
Go to the documentation of this file.
1 //===- LowerGuardIntrinsic.cpp - Lower the guard intrinsic ---------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This pass lowers the llvm.experimental.guard intrinsic to a conditional call
11 // to @llvm.experimental.deoptimize. Once this happens, the guard can no longer
12 // be widened.
13 //
14 //===----------------------------------------------------------------------===//
15 
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/IR/BasicBlock.h"
19 #include "llvm/IR/Function.h"
20 #include "llvm/IR/IRBuilder.h"
21 #include "llvm/IR/InstIterator.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/Intrinsics.h"
24 #include "llvm/IR/MDBuilder.h"
25 #include "llvm/IR/Module.h"
26 #include "llvm/Pass.h"
27 #include "llvm/Transforms/Scalar.h"
29 
30 using namespace llvm;
31 
33  "guards-predicate-pass-branch-weight", cl::Hidden, cl::init(1 << 20),
34  cl::desc("The probability of a guard failing is assumed to be the "
35  "reciprocal of this value (default = 1 << 20)"));
36 
37 namespace {
38 struct LowerGuardIntrinsicLegacyPass : public FunctionPass {
39  static char ID;
40  LowerGuardIntrinsicLegacyPass() : FunctionPass(ID) {
43  }
44 
45  bool runOnFunction(Function &F) override;
46 };
47 }
48 
49 static void MakeGuardControlFlowExplicit(Function *DeoptIntrinsic,
50  CallInst *CI) {
52  SmallVector<Value *, 4> Args(std::next(CI->arg_begin()), CI->arg_end());
53 
54  auto *CheckBB = CI->getParent();
55  auto *DeoptBlockTerm =
56  SplitBlockAndInsertIfThen(CI->getArgOperand(0), CI, true);
57 
58  auto *CheckBI = cast<BranchInst>(CheckBB->getTerminator());
59 
60  // SplitBlockAndInsertIfThen inserts control flow that branches to
61  // DeoptBlockTerm if the condition is true. We want the opposite.
62  CheckBI->swapSuccessors();
63 
64  CheckBI->getSuccessor(0)->setName("guarded");
65  CheckBI->getSuccessor(1)->setName("deopt");
66 
67  if (auto *MD = CI->getMetadata(LLVMContext::MD_make_implicit))
68  CheckBI->setMetadata(LLVMContext::MD_make_implicit, MD);
69 
70  MDBuilder MDB(CI->getContext());
71  CheckBI->setMetadata(LLVMContext::MD_prof,
72  MDB.createBranchWeights(PredicatePassBranchWeight, 1));
73 
74  IRBuilder<> B(DeoptBlockTerm);
75  auto *DeoptCall = B.CreateCall(DeoptIntrinsic, Args, {DeoptOB}, "");
76 
77  if (DeoptIntrinsic->getReturnType()->isVoidTy()) {
78  B.CreateRetVoid();
79  } else {
80  DeoptCall->setName("deoptcall");
81  B.CreateRet(DeoptCall);
82  }
83 
84  DeoptCall->setCallingConv(CI->getCallingConv());
85  DeoptBlockTerm->eraseFromParent();
86 }
87 
89  // Check if we can cheaply rule out the possibility of not having any work to
90  // do.
91  auto *GuardDecl = F.getParent()->getFunction(
92  Intrinsic::getName(Intrinsic::experimental_guard));
93  if (!GuardDecl || GuardDecl->use_empty())
94  return false;
95 
97  for (auto &I : instructions(F))
98  if (auto *CI = dyn_cast<CallInst>(&I))
99  if (auto *F = CI->getCalledFunction())
100  if (F->getIntrinsicID() == Intrinsic::experimental_guard)
101  ToLower.push_back(CI);
102 
103  if (ToLower.empty())
104  return false;
105 
106  auto *DeoptIntrinsic = Intrinsic::getDeclaration(
107  F.getParent(), Intrinsic::experimental_deoptimize, {F.getReturnType()});
108  DeoptIntrinsic->setCallingConv(GuardDecl->getCallingConv());
109 
110  for (auto *CI : ToLower) {
111  MakeGuardControlFlowExplicit(DeoptIntrinsic, CI);
112  CI->eraseFromParent();
113  }
114 
115  return true;
116 }
117 
119  return lowerGuardIntrinsic(F);
120 }
121 
123 INITIALIZE_PASS(LowerGuardIntrinsicLegacyPass, "lower-guard-intrinsic",
124  "Lower the guard intrinsic to normal control flow", false,
125  false)
126 
128  return new LowerGuardIntrinsicLegacyPass();
129 }
130 
133  if (lowerGuardIntrinsic(F))
134  return PreservedAnalyses::none();
135 
136  return PreservedAnalyses::all();
137 }
Pass interface - Implemented by all &#39;passes&#39;.
Definition: Pass.h:81
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks &#39;this&#39; from the containing basic block and deletes it.
Definition: Instruction.cpp:69
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
BasicBlock * getSuccessor(unsigned idx) const
Return the specified successor.
This class represents a function call, abstracting a target machine&#39;s calling convention.
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:728
F(f)
static bool lowerGuardIntrinsic(Function &F)
CallingConv::ID getCallingConv() const
getCallingConv/setCallingConv - Get or set the calling convention of this function call...
INITIALIZE_PASS(LowerGuardIntrinsicLegacyPass, "lower-guard-intrinsic", "Lower the guard intrinsic to normal control flow", false, false) Pass *llvm
StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
Definition: Function.cpp:591
ReturnInst * CreateRet(Value *V)
Create a &#39;ret <val>&#39; instruction.
Definition: IRBuilder.h:754
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:668
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:286
op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:194
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:980
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:156
static cl::opt< uint32_t > PredicatePassBranchWeight("guards-predicate-pass-branch-weight", cl::Hidden, cl::init(1<< 20), cl::desc("The probability of a guard failing is assumed to be the " "reciprocal of this value (default = 1 << 20)"))
bool isVoidTy() const
Return true if this is &#39;void&#39;.
Definition: Type.h:141
static bool runOnFunction(Function &F, bool PostInlining)
void setCallingConv(CallingConv::ID CC)
Definition: Function.h:198
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:406
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:150
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:153
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
static void MakeGuardControlFlowExplicit(Function *DeoptIntrinsic, CallInst *CI)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:159
Pass * createLowerGuardIntrinsicPass()
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
Module.h This file contains the declarations for the Module class.
TerminatorInst * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition: Function.h:175
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
Definition: Module.cpp:172
ReturnInst * CreateRetVoid()
Create a &#39;ret void&#39; instruction.
Definition: IRBuilder.h:749
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:61
Optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Definition: InstrTypes.h:1363
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
#define I(x, y, z)
Definition: MD5.cpp:58
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:556
A container for an operand bundle being viewed as a set of values rather than a set of uses...
Definition: InstrTypes.h:1215
inst_range instructions(Function *F)
Definition: InstIterator.h:134
A container for analyses that lazily runs them and caches their results.
void initializeLowerGuardIntrinsicLegacyPassPass(PassRegistry &)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
const BasicBlock * getParent() const
Definition: Instruction.h:66
CallInst * CreateCall(Value *Callee, ArrayRef< Value *> Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:1663