DwarfEHPrepare.cpp revision 272461
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" 18#include "llvm/Analysis/Dominators.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" 26#include "llvm/Target/TargetLowering.h" 27#include "llvm/Transforms/Utils/BasicBlockUtils.h" 28#include "llvm/Transforms/Utils/SSAUpdater.h" 29using namespace llvm; 30 31STATISTIC(NumResumesLowered, "Number of resume calls lowered"); 32 33namespace { 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) { 47 initializeDominatorTreePass(*PassRegistry::getPassRegistry()); 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 60char DwarfEHPrepare::ID = 0; 61 62FunctionPass *llvm::createDwarfEHPass(const TargetMachine *TM) { 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. 69Value *DwarfEHPrepare::GetExceptionObject(ResumeInst *RI) { 70 Value *V = RI->getOperand(0); 71 Value *ExnObj = 0; 72 InsertValueInst *SelIVI = dyn_cast<InsertValueInst>(V); 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. 108bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) { 109 SmallVector<ResumeInst*, 16> Resumes; 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(); 123 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx), 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); 142 CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME)); 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. 155 for (SmallVectorImpl<ResumeInst*>::iterator 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); 169 CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME)); 170 171 // We never expect _Unwind_Resume to return. 172 new UnreachableInst(Ctx, UnwindBB); 173 return true; 174} 175 176bool DwarfEHPrepare::runOnFunction(Function &Fn) { 177 bool Changed = InsertUnwindResumeCalls(Fn); 178 return Changed; 179} 180