LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 #define DEBUG_TYPE "dwarfehprepare"
16 #include "llvm/CodeGen/Passes.h"
17 #include "llvm/ADT/Statistic.h"
19 #include "llvm/IR/Function.h"
20 #include "llvm/IR/Instructions.h"
21 #include "llvm/IR/IntrinsicInst.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/MC/MCAsmInfo.h"
24 #include "llvm/Pass.h"
25 #include "llvm/Support/CallSite.h"
29 using namespace llvm;
30 
31 STATISTIC(NumResumesLowered, "Number of resume calls lowered");
32 
33 namespace {
34  class DwarfEHPrepare : public FunctionPass {
35  const TargetMachine *TM;
36 
37  // RewindFunction - _Unwind_Resume or the target equivalent.
38  Constant *RewindFunction;
39 
40  bool InsertUnwindResumeCalls(Function &Fn);
41  Value *GetExceptionObject(ResumeInst *RI);
42 
43  public:
44  static char ID; // Pass identification, replacement for typeid.
45  DwarfEHPrepare(const TargetMachine *TM) :
46  FunctionPass(ID), TM(TM), RewindFunction(0) {
48  }
49 
50  virtual bool runOnFunction(Function &Fn);
51 
52  virtual void getAnalysisUsage(AnalysisUsage &AU) const { }
53 
54  const char *getPassName() const {
55  return "Exception handling preparation";
56  }
57  };
58 } // end anonymous namespace
59 
60 char DwarfEHPrepare::ID = 0;
61 
63  return new DwarfEHPrepare(TM);
64 }
65 
66 /// GetExceptionObject - Return the exception object from the value passed into
67 /// the 'resume' instruction (typically an aggregate). Clean up any dead
68 /// instructions, including the 'resume' instruction.
69 Value *DwarfEHPrepare::GetExceptionObject(ResumeInst *RI) {
70  Value *V = RI->getOperand(0);
71  Value *ExnObj = 0;
73  LoadInst *SelLoad = 0;
74  InsertValueInst *ExcIVI = 0;
75  bool EraseIVIs = false;
76 
77  if (SelIVI) {
78  if (SelIVI->getNumIndices() == 1 && *SelIVI->idx_begin() == 1) {
79  ExcIVI = dyn_cast<InsertValueInst>(SelIVI->getOperand(0));
80  if (ExcIVI && isa<UndefValue>(ExcIVI->getOperand(0)) &&
81  ExcIVI->getNumIndices() == 1 && *ExcIVI->idx_begin() == 0) {
82  ExnObj = ExcIVI->getOperand(1);
83  SelLoad = dyn_cast<LoadInst>(SelIVI->getOperand(1));
84  EraseIVIs = true;
85  }
86  }
87  }
88 
89  if (!ExnObj)
90  ExnObj = ExtractValueInst::Create(RI->getOperand(0), 0, "exn.obj", RI);
91 
92  RI->eraseFromParent();
93 
94  if (EraseIVIs) {
95  if (SelIVI->getNumUses() == 0)
96  SelIVI->eraseFromParent();
97  if (ExcIVI->getNumUses() == 0)
98  ExcIVI->eraseFromParent();
99  if (SelLoad && SelLoad->getNumUses() == 0)
100  SelLoad->eraseFromParent();
101  }
102 
103  return ExnObj;
104 }
105 
106 /// InsertUnwindResumeCalls - Convert the ResumeInsts that are still present
107 /// into calls to the appropriate _Unwind_Resume function.
108 bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) {
110  for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
111  TerminatorInst *TI = I->getTerminator();
112  if (ResumeInst *RI = dyn_cast<ResumeInst>(TI))
113  Resumes.push_back(RI);
114  }
115 
116  if (Resumes.empty())
117  return false;
118 
119  // Find the rewind function if we didn't already.
120  const TargetLowering *TLI = TM->getTargetLowering();
121  if (!RewindFunction) {
122  LLVMContext &Ctx = Resumes[0]->getContext();
124  Type::getInt8PtrTy(Ctx), false);
125  const char *RewindName = TLI->getLibcallName(RTLIB::UNWIND_RESUME);
126  RewindFunction = Fn.getParent()->getOrInsertFunction(RewindName, FTy);
127  }
128 
129  // Create the basic block where the _Unwind_Resume call will live.
130  LLVMContext &Ctx = Fn.getContext();
131  unsigned ResumesSize = Resumes.size();
132 
133  if (ResumesSize == 1) {
134  // Instead of creating a new BB and PHI node, just append the call to
135  // _Unwind_Resume to the end of the single resume block.
136  ResumeInst *RI = Resumes.front();
137  BasicBlock *UnwindBB = RI->getParent();
138  Value *ExnObj = GetExceptionObject(RI);
139 
140  // Call the _Unwind_Resume function.
141  CallInst *CI = CallInst::Create(RewindFunction, ExnObj, "", UnwindBB);
143 
144  // We never expect _Unwind_Resume to return.
145  new UnreachableInst(Ctx, UnwindBB);
146  return true;
147  }
148 
149  BasicBlock *UnwindBB = BasicBlock::Create(Ctx, "unwind_resume", &Fn);
150  PHINode *PN = PHINode::Create(Type::getInt8PtrTy(Ctx), ResumesSize,
151  "exn.obj", UnwindBB);
152 
153  // Extract the exception object from the ResumeInst and add it to the PHI node
154  // that feeds the _Unwind_Resume call.
156  I = Resumes.begin(), E = Resumes.end(); I != E; ++I) {
157  ResumeInst *RI = *I;
158  BasicBlock *Parent = RI->getParent();
159  BranchInst::Create(UnwindBB, Parent);
160 
161  Value *ExnObj = GetExceptionObject(RI);
162  PN->addIncoming(ExnObj, Parent);
163 
164  ++NumResumesLowered;
165  }
166 
167  // Call the function.
168  CallInst *CI = CallInst::Create(RewindFunction, PN, "", UnwindBB);
170 
171  // We never expect _Unwind_Resume to return.
172  new UnreachableInst(Ctx, UnwindBB);
173  return true;
174 }
175 
176 bool DwarfEHPrepare::runOnFunction(Function &Fn) {
177  bool Changed = InsertUnwindResumeCalls(Fn);
178  return Changed;
179 }
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const
Get the CallingConv that should be used for the specified libcall.
void addIncoming(Value *V, BasicBlock *BB)
static PassRegistry * getPassRegistry()
LLVMContext & getContext() const
Definition: Function.cpp:167
iterator end()
Definition: Function.h:397
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:266
FunctionPass * createDwarfEHPass(const TargetMachine *TM)
unsigned getNumIndices() const
static ExtractValueInst * Create(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &NameStr="", Instruction *InsertBefore=0)
void initializeDominatorTreePass(PassRegistry &)
void setCallingConv(CallingConv::ID CC)
STATISTIC(NumResumesLowered,"Number of resume calls lowered")
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=0)
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:56
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
Definition: Type.cpp:361
iterator begin()
Definition: Function.h:395
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
Definition: Module.cpp:138
LLVM Basic Block Representation.
Definition: BasicBlock.h:72
LLVM Constant Representation.
Definition: Constant.h:41
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=0)
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:227
Value * getOperand(unsigned i) const
Definition: User.h:88
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:284
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=0)
idx_iterator idx_begin() const
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
#define I(x, y, z)
Definition: MD5.cpp:54
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=0, BasicBlock *InsertBefore=0)
Creates a new BasicBlock.
Definition: BasicBlock.h:109
Module * getParent()
Definition: GlobalValue.h:286
LLVM Value Representation.
Definition: Value.h:66
unsigned getNumUses() const
Definition: Value.cpp:139
const BasicBlock * getParent() const
Definition: Instruction.h:52