llvm.org GIT mirror llvm / c6f0aad
Fix a problem that lower invoke has with allocas (PR6694), and add a version of createLowerInvokePass that allows the client to specify whether it wants "expensive" or "cheap" lowering. Patch by Alex Mac! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102402 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 10 years ago
2 changed file(s) with 40 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
240240 // lowering pass.
241241 //
242242 FunctionPass *createLowerInvokePass(const TargetLowering *TLI = 0);
243 FunctionPass *createLowerInvokePass(const TargetLowering *TLI,
244 bool useExpensiveEHSupport);
243245 extern const PassInfo *const LowerInvokePassID;
244246
245247 //===----------------------------------------------------------------------===//
6969 // Used for expensive EH support.
7070 const Type *JBLinkTy;
7171 GlobalVariable *JBListHead;
72 Constant *SetJmpFn, *LongJmpFn;
72 Constant *SetJmpFn, *LongJmpFn, *StackSaveFn, *StackRestoreFn;
73 bool useExpensiveEHSupport;
7374
7475 // We peek in TLI to grab the target's jmp_buf size and alignment
7576 const TargetLowering *TLI;
7677
7778 public:
7879 static char ID; // Pass identification, replacement for typeid
79 explicit LowerInvoke(const TargetLowering *tli = NULL)
80 : FunctionPass(&ID), TLI(tli) { }
80 explicit LowerInvoke(const TargetLowering *tli = NULL,
81 bool useExpensiveEHSupport = ExpensiveEHSupport)
82 : FunctionPass(&ID), useExpensiveEHSupport(useExpensiveEHSupport),
83 TLI(tli) { }
8184 bool doInitialization(Module &M);
8285 bool runOnFunction(Function &F);
8386
9396 bool insertCheapEHSupport(Function &F);
9497 void splitLiveRangesLiveAcrossInvokes(std::vector &Invokes);
9598 void rewriteExpensiveInvoke(InvokeInst *II, unsigned InvokeNo,
96 AllocaInst *InvokeNum, SwitchInst *CatchSwitch);
99 AllocaInst *InvokeNum, AllocaInst *StackPtr,
100 SwitchInst *CatchSwitch);
97101 bool insertExpensiveEHSupport(Function &F);
98102 };
99103 }
106110
107111 // Public Interface To the LowerInvoke pass.
108112 FunctionPass *llvm::createLowerInvokePass(const TargetLowering *TLI) {
109 return new LowerInvoke(TLI);
113 return new LowerInvoke(TLI, ExpensiveEHSupport);
114 }
115 FunctionPass *llvm::createLowerInvokePass(const TargetLowering *TLI,
116 bool useExpensiveEHSupport) {
117 return new LowerInvoke(TLI, useExpensiveEHSupport);
110118 }
111119
112120 // doInitialization - Make sure that there is a prototype for abort in the
115123 const Type *VoidPtrTy =
116124 Type::getInt8PtrTy(M.getContext());
117125 AbortMessage = 0;
118 if (ExpensiveEHSupport) {
126 if (useExpensiveEHSupport) {
119127 // Insert a type for the linked list of jump buffers.
120128 unsigned JBSize = TLI ? TLI->getJumpBufSize() : 0;
121129 JBSize = JBSize ? JBSize : 200;
159167 #endif
160168
161169 LongJmpFn = Intrinsic::getDeclaration(&M, Intrinsic::longjmp);
170 StackSaveFn = Intrinsic::getDeclaration(&M, Intrinsic::stacksave);
171 StackRestoreFn = Intrinsic::getDeclaration(&M, Intrinsic::stackrestore);
162172 }
163173
164174 // We need the 'write' and 'abort' functions for both models.
174184 }
175185
176186 void LowerInvoke::createAbortMessage(Module *M) {
177 if (ExpensiveEHSupport) {
187 if (useExpensiveEHSupport) {
178188 // The abort message for expensive EH support tells the user that the
179189 // program 'unwound' without an 'invoke' instruction.
180190 Constant *Msg =
228238 std::vector CallArgs(II->op_begin(), II->op_end() - 3);
229239 // Insert a normal call instruction...
230240 CallInst *NewCall = CallInst::Create(II->getCalledValue(),
231 CallArgs.begin(), CallArgs.end(), "",II);
241 CallArgs.begin(), CallArgs.end(),
242 "",II);
232243 NewCall->takeName(II);
233244 NewCall->setCallingConv(II->getCallingConv());
234245 NewCall->setAttributes(II->getAttributes());
269280 /// specified invoke instruction with a call.
270281 void LowerInvoke::rewriteExpensiveInvoke(InvokeInst *II, unsigned InvokeNo,
271282 AllocaInst *InvokeNum,
283 AllocaInst *StackPtr,
272284 SwitchInst *CatchSwitch) {
273285 ConstantInt *InvokeNoC = ConstantInt::get(Type::getInt32Ty(II->getContext()),
274286 InvokeNo);
287299 // Insert a store of the invoke num before the invoke and store zero into the
288300 // location afterward.
289301 new StoreInst(InvokeNoC, InvokeNum, true, II); // volatile
302
303 // Insert a store of the stack ptr before the invoke, so we can restore it
304 // later in the exception case.
305 CallInst* StackSaveRet = CallInst::Create(StackSaveFn, "ssret", II);
306 new StoreInst(StackSaveRet, StackPtr, true, II); // volatile
290307
291308 BasicBlock::iterator NI = II->getNormalDest()->getFirstNonPHI();
292309 // nonvolatile.
293310 new StoreInst(Constant::getNullValue(Type::getInt32Ty(II->getContext())),
294311 InvokeNum, false, NI);
295312
313 Instruction* StackPtrLoad = new LoadInst(StackPtr, "stackptr.restore", true,
314 II->getUnwindDest()->getFirstNonPHI()
315 );
316 CallInst::Create(StackRestoreFn, StackPtrLoad, "")->insertAfter(StackPtrLoad);
317
296318 // Add a switch case to our unwind block.
297319 CatchSwitch->addCase(InvokeNoC, II->getUnwindDest());
298320
499521 BasicBlock *CatchBB =
500522 BasicBlock::Create(F.getContext(), "setjmp.catch", &F);
501523
524 // Create an alloca which keeps track of the stack pointer before every
525 // invoke, this allows us to properly restore the stack pointer after
526 // long jumping.
527 AllocaInst *StackPtr = new AllocaInst(Type::getInt8PtrTy(F.getContext()), 0,
528 "stackptr", EntryBB->begin());
529
502530 // Create an alloca which keeps track of which invoke is currently
503531 // executing. For normal calls it contains zero.
504532 AllocaInst *InvokeNum = new AllocaInst(Type::getInt32Ty(F.getContext()), 0,
545573
546574 // At this point, we are all set up, rewrite each invoke instruction.
547575 for (unsigned i = 0, e = Invokes.size(); i != e; ++i)
548 rewriteExpensiveInvoke(Invokes[i], i+1, InvokeNum, CatchSwitch);
576 rewriteExpensiveInvoke(Invokes[i], i+1, InvokeNum, StackPtr, CatchSwitch);
549577 }
550578
551579 // We know that there is at least one unwind.
621649 }
622650
623651 bool LowerInvoke::runOnFunction(Function &F) {
624 if (ExpensiveEHSupport)
652 if (useExpensiveEHSupport)
625653 return insertExpensiveEHSupport(F);
626654 else
627655 return insertCheapEHSupport(F);