LLVM  3.7.0
DwarfEHPrepare.cpp
Go to the documentation of this file.
1 //===-- DwarfEHPrepare - Prepare exception handling for code generation ---===//
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 mulches exception handling code into a form adapted to code
11 // generation. Required if using dwarf exception handling.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/CodeGen/Passes.h"
16 #include "llvm/ADT/BitVector.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/Analysis/CFG.h"
21 #include "llvm/IR/Dominators.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/Instructions.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/Pass.h"
29 using namespace llvm;
30 
31 #define DEBUG_TYPE "dwarfehprepare"
32 
33 STATISTIC(NumResumesLowered, "Number of resume calls lowered");
34 
35 namespace {
36  class DwarfEHPrepare : public FunctionPass {
37  const TargetMachine *TM;
38 
39  // RewindFunction - _Unwind_Resume or the target equivalent.
40  Constant *RewindFunction;
41 
42  DominatorTree *DT;
43  const TargetLowering *TLI;
44 
45  bool InsertUnwindResumeCalls(Function &Fn);
46  Value *GetExceptionObject(ResumeInst *RI);
47  size_t
48  pruneUnreachableResumes(Function &Fn,
50  SmallVectorImpl<LandingPadInst *> &CleanupLPads);
51 
52  public:
53  static char ID; // Pass identification, replacement for typeid.
54 
55  // INITIALIZE_TM_PASS requires a default constructor, but it isn't used in
56  // practice.
57  DwarfEHPrepare()
58  : FunctionPass(ID), TM(nullptr), RewindFunction(nullptr), DT(nullptr),
59  TLI(nullptr) {}
60 
61  DwarfEHPrepare(const TargetMachine *TM)
62  : FunctionPass(ID), TM(TM), RewindFunction(nullptr), DT(nullptr),
63  TLI(nullptr) {}
64 
65  bool runOnFunction(Function &Fn) override;
66 
67  bool doFinalization(Module &M) override {
68  RewindFunction = nullptr;
69  return false;
70  }
71 
72  void getAnalysisUsage(AnalysisUsage &AU) const override;
73 
74  const char *getPassName() const override {
75  return "Exception handling preparation";
76  }
77  };
78 } // end anonymous namespace
79 
80 char DwarfEHPrepare::ID = 0;
81 INITIALIZE_TM_PASS_BEGIN(DwarfEHPrepare, "dwarfehprepare",
82  "Prepare DWARF exceptions", false, false)
86  "Prepare DWARF exceptions", false, false)
87 
89  return new DwarfEHPrepare(TM);
90 }
91 
92 void DwarfEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {
95 }
96 
97 /// GetExceptionObject - Return the exception object from the value passed into
98 /// the 'resume' instruction (typically an aggregate). Clean up any dead
99 /// instructions, including the 'resume' instruction.
100 Value *DwarfEHPrepare::GetExceptionObject(ResumeInst *RI) {
101  Value *V = RI->getOperand(0);
102  Value *ExnObj = nullptr;
104  LoadInst *SelLoad = nullptr;
105  InsertValueInst *ExcIVI = nullptr;
106  bool EraseIVIs = false;
107 
108  if (SelIVI) {
109  if (SelIVI->getNumIndices() == 1 && *SelIVI->idx_begin() == 1) {
110  ExcIVI = dyn_cast<InsertValueInst>(SelIVI->getOperand(0));
111  if (ExcIVI && isa<UndefValue>(ExcIVI->getOperand(0)) &&
112  ExcIVI->getNumIndices() == 1 && *ExcIVI->idx_begin() == 0) {
113  ExnObj = ExcIVI->getOperand(1);
114  SelLoad = dyn_cast<LoadInst>(SelIVI->getOperand(1));
115  EraseIVIs = true;
116  }
117  }
118  }
119 
120  if (!ExnObj)
121  ExnObj = ExtractValueInst::Create(RI->getOperand(0), 0, "exn.obj", RI);
122 
123  RI->eraseFromParent();
124 
125  if (EraseIVIs) {
126  if (SelIVI->use_empty())
127  SelIVI->eraseFromParent();
128  if (ExcIVI->use_empty())
129  ExcIVI->eraseFromParent();
130  if (SelLoad && SelLoad->use_empty())
131  SelLoad->eraseFromParent();
132  }
133 
134  return ExnObj;
135 }
136 
137 /// Replace resumes that are not reachable from a cleanup landing pad with
138 /// unreachable and then simplify those blocks.
139 size_t DwarfEHPrepare::pruneUnreachableResumes(
141  SmallVectorImpl<LandingPadInst *> &CleanupLPads) {
142  BitVector ResumeReachable(Resumes.size());
143  size_t ResumeIndex = 0;
144  for (auto *RI : Resumes) {
145  for (auto *LP : CleanupLPads) {
146  if (isPotentiallyReachable(LP, RI, DT)) {
147  ResumeReachable.set(ResumeIndex);
148  break;
149  }
150  }
151  ++ResumeIndex;
152  }
153 
154  // If everything is reachable, there is no change.
155  if (ResumeReachable.all())
156  return Resumes.size();
157 
158  const TargetTransformInfo &TTI =
159  getAnalysis<TargetTransformInfoWrapperPass>().getTTI(Fn);
160  LLVMContext &Ctx = Fn.getContext();
161 
162  // Otherwise, insert unreachable instructions and call simplifycfg.
163  size_t ResumesLeft = 0;
164  for (size_t I = 0, E = Resumes.size(); I < E; ++I) {
165  ResumeInst *RI = Resumes[I];
166  if (ResumeReachable[I]) {
167  Resumes[ResumesLeft++] = RI;
168  } else {
169  BasicBlock *BB = RI->getParent();
170  new UnreachableInst(Ctx, RI);
171  RI->eraseFromParent();
172  SimplifyCFG(BB, TTI, 1);
173  }
174  }
175  Resumes.resize(ResumesLeft);
176  return ResumesLeft;
177 }
178 
179 /// InsertUnwindResumeCalls - Convert the ResumeInsts that are still present
180 /// into calls to the appropriate _Unwind_Resume function.
181 bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) {
184  for (BasicBlock &BB : Fn) {
185  if (auto *RI = dyn_cast<ResumeInst>(BB.getTerminator()))
186  Resumes.push_back(RI);
187  if (auto *LP = BB.getLandingPadInst())
188  if (LP->isCleanup())
189  CleanupLPads.push_back(LP);
190  }
191 
192  if (Resumes.empty())
193  return false;
194 
195  // Check the personality, don't do anything if it's for MSVC.
196  EHPersonality Pers = classifyEHPersonality(Fn.getPersonalityFn());
197  if (isMSVCEHPersonality(Pers))
198  return false;
199 
200  LLVMContext &Ctx = Fn.getContext();
201 
202  size_t ResumesLeft = pruneUnreachableResumes(Fn, Resumes, CleanupLPads);
203  if (ResumesLeft == 0)
204  return true; // We pruned them all.
205 
206  // Find the rewind function if we didn't already.
207  if (!RewindFunction) {
209  Type::getInt8PtrTy(Ctx), false);
210  const char *RewindName = TLI->getLibcallName(RTLIB::UNWIND_RESUME);
211  RewindFunction = Fn.getParent()->getOrInsertFunction(RewindName, FTy);
212  }
213 
214  // Create the basic block where the _Unwind_Resume call will live.
215  if (ResumesLeft == 1) {
216  // Instead of creating a new BB and PHI node, just append the call to
217  // _Unwind_Resume to the end of the single resume block.
218  ResumeInst *RI = Resumes.front();
219  BasicBlock *UnwindBB = RI->getParent();
220  Value *ExnObj = GetExceptionObject(RI);
221 
222  // Call the _Unwind_Resume function.
223  CallInst *CI = CallInst::Create(RewindFunction, ExnObj, "", UnwindBB);
224  CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME));
225 
226  // We never expect _Unwind_Resume to return.
227  new UnreachableInst(Ctx, UnwindBB);
228  return true;
229  }
230 
231  BasicBlock *UnwindBB = BasicBlock::Create(Ctx, "unwind_resume", &Fn);
232  PHINode *PN = PHINode::Create(Type::getInt8PtrTy(Ctx), ResumesLeft,
233  "exn.obj", UnwindBB);
234 
235  // Extract the exception object from the ResumeInst and add it to the PHI node
236  // that feeds the _Unwind_Resume call.
237  for (ResumeInst *RI : Resumes) {
238  BasicBlock *Parent = RI->getParent();
239  BranchInst::Create(UnwindBB, Parent);
240 
241  Value *ExnObj = GetExceptionObject(RI);
242  PN->addIncoming(ExnObj, Parent);
243 
244  ++NumResumesLowered;
245  }
246 
247  // Call the function.
248  CallInst *CI = CallInst::Create(RewindFunction, PN, "", UnwindBB);
249  CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME));
250 
251  // We never expect _Unwind_Resume to return.
252  new UnreachableInst(Ctx, UnwindBB);
253  return true;
254 }
255 
256 bool DwarfEHPrepare::runOnFunction(Function &Fn) {
257  assert(TM && "DWARF EH preparation requires a target machine");
258  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
259  TLI = TM->getSubtargetImpl(Fn)->getTargetLowering();
260  bool Changed = InsertUnwindResumeCalls(Fn);
261  DT = nullptr;
262  TLI = nullptr;
263  return Changed;
264 }
INITIALIZE_TM_PASS_BEGIN(DwarfEHPrepare,"dwarfehprepare","Prepare DWARF exceptions", false, false) INITIALIZE_TM_PASS_END(DwarfEHPrepare
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
Definition: Instruction.cpp:70
BitVector & set()
Definition: BitVector.h:218
size_type size() const
size - Returns the number of bits in this bitvector.
Definition: BitVector.h:118
void addIncoming(Value *V, BasicBlock *BB)
addIncoming - Add an incoming value to the end of the PHI list
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:223
STATISTIC(NumFunctions,"Total number of functions")
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:114
CallInst - This class represents a function call, abstracting a target machine's calling convention...
unsigned getNumIndices() const
LoadInst - an instruction for reading from memory.
Definition: Instructions.h:177
void setCallingConv(CallingConv::ID CC)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:70
dwarfehprepare
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APInt.h:33
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
FunctionType - Class to represent function types.
Definition: DerivedTypes.h:96
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:57
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
FunctionType::get - This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:361
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Definition: Dominators.h:67
Wrapper pass for TargetTransformInfo.
LLVM Basic Block Representation.
Definition: BasicBlock.h:65
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:41
static ExtractValueInst * Create(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
UnreachableInst - This function has undefined behavior.
This is an important base class in LLVM.
Definition: Constant.h:41
ResumeInst - Resume the propagation of an exception.
LandingPadInst * getLandingPadInst()
Return the landingpad instruction associated with the landing pad.
Definition: BasicBlock.cpp:418
#define INITIALIZE_TM_PASS_END(passName, arg, name, cfg, analysis)
Target machine pass initializer for passes with dependencies.
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:225
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:294
Value * getOperand(unsigned i) const
Definition: User.h:118
bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI, unsigned BonusInstThreshold, AssumptionCache *AC=nullptr)
SimplifyCFG - This function is used to do simplification of a CFG.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:103
bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether instruction 'To' is reachable from 'From', returning true if uncertain.
Definition: CFG.cpp:185
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:283
idx_iterator idx_begin() const
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
Module.h This file contains the declarations for the Module class.
Prepare DWARF exceptions
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:285
FunctionPass * createDwarfEHPass(const TargetMachine *TM)
createDwarfEHPass - This pass mulches exception handling code into a form adapted to code generation...
#define I(x, y, z)
Definition: MD5.cpp:54
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:124
bool use_empty() const
Definition: Value.h:275
Prepare DWARF false
aarch64 promote const
LLVM Value Representation.
Definition: Value.h:69
Primary interface to the complete machine description for the target machine.
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:203
This pass exposes codegen information to IR-level passes.
const BasicBlock * getParent() const
Definition: Instruction.h:72
bool isMSVCEHPersonality(EHPersonality Pers)
Returns true if this is an MSVC personality function.
This file describes how to lower LLVM code to machine code.
InsertValueInst - This instruction inserts a struct field of array element value into an aggregate va...