1235633Sdim//===- SjLjEHPrepare.cpp - Eliminate Invoke & Unwind instructions ---------===// 2198090Srdivacky// 3198090Srdivacky// The LLVM Compiler Infrastructure 4198090Srdivacky// 5198090Srdivacky// This file is distributed under the University of Illinois Open Source 6198090Srdivacky// License. See LICENSE.TXT for details. 7198090Srdivacky// 8198090Srdivacky//===----------------------------------------------------------------------===// 9198090Srdivacky// 10198090Srdivacky// This transformation is designed for use by code generators which use SjLj 11198090Srdivacky// based exception handling. 12198090Srdivacky// 13198090Srdivacky//===----------------------------------------------------------------------===// 14198090Srdivacky 15198090Srdivacky#define DEBUG_TYPE "sjljehprepare" 16252723Sdim#include "llvm/CodeGen/Passes.h" 17226890Sdim#include "llvm/ADT/DenseMap.h" 18235633Sdim#include "llvm/ADT/SetVector.h" 19235633Sdim#include "llvm/ADT/SmallPtrSet.h" 20226890Sdim#include "llvm/ADT/SmallVector.h" 21226890Sdim#include "llvm/ADT/Statistic.h" 22252723Sdim#include "llvm/IR/Constants.h" 23252723Sdim#include "llvm/IR/DataLayout.h" 24252723Sdim#include "llvm/IR/DerivedTypes.h" 25252723Sdim#include "llvm/IR/IRBuilder.h" 26252723Sdim#include "llvm/IR/Instructions.h" 27252723Sdim#include "llvm/IR/Intrinsics.h" 28252723Sdim#include "llvm/IR/LLVMContext.h" 29252723Sdim#include "llvm/IR/Module.h" 30252723Sdim#include "llvm/Pass.h" 31245431Sdim#include "llvm/Support/CommandLine.h" 32245431Sdim#include "llvm/Support/Debug.h" 33245431Sdim#include "llvm/Support/raw_ostream.h" 34245431Sdim#include "llvm/Target/TargetLowering.h" 35245431Sdim#include "llvm/Transforms/Scalar.h" 36245431Sdim#include "llvm/Transforms/Utils/BasicBlockUtils.h" 37245431Sdim#include "llvm/Transforms/Utils/Local.h" 38218893Sdim#include <set> 39198090Srdivackyusing namespace llvm; 40198090Srdivacky 41198090SrdivackySTATISTIC(NumInvokes, "Number of invokes replaced"); 42198090SrdivackySTATISTIC(NumSpilled, "Number of registers live across unwind edges"); 43198090Srdivacky 44198090Srdivackynamespace { 45263509Sdimclass SjLjEHPrepare : public FunctionPass { 46263509Sdim const TargetMachine *TM; 47263509Sdim Type *FunctionContextTy; 48263509Sdim Constant *RegisterFn; 49263509Sdim Constant *UnregisterFn; 50263509Sdim Constant *BuiltinSetjmpFn; 51263509Sdim Constant *FrameAddrFn; 52263509Sdim Constant *StackAddrFn; 53263509Sdim Constant *StackRestoreFn; 54263509Sdim Constant *LSDAAddrFn; 55263509Sdim Value *PersonalityFn; 56263509Sdim Constant *CallSiteFn; 57263509Sdim Constant *FuncCtxFn; 58263509Sdim AllocaInst *FuncCtx; 59198090Srdivacky 60263509Sdimpublic: 61263509Sdim static char ID; // Pass identification, replacement for typeid 62263509Sdim explicit SjLjEHPrepare(const TargetMachine *TM) : FunctionPass(ID), TM(TM) {} 63263509Sdim bool doInitialization(Module &M); 64263509Sdim bool runOnFunction(Function &F); 65198090Srdivacky 66263509Sdim virtual void getAnalysisUsage(AnalysisUsage &AU) const {} 67263509Sdim const char *getPassName() const { 68263509Sdim return "SJLJ Exception Handling preparation"; 69263509Sdim } 70263509Sdim 71263509Sdimprivate: 72263509Sdim bool setupEntryBlockAndCallSites(Function &F); 73263509Sdim void substituteLPadValues(LandingPadInst *LPI, Value *ExnVal, Value *SelVal); 74263509Sdim Value *setupFunctionContext(Function &F, ArrayRef<LandingPadInst *> LPads); 75263509Sdim void lowerIncomingArguments(Function &F); 76263509Sdim void lowerAcrossUnwindEdges(Function &F, ArrayRef<InvokeInst *> Invokes); 77263509Sdim void insertCallSiteStore(Instruction *I, int Number); 78263509Sdim}; 79198090Srdivacky} // end anonymous namespace 80198090Srdivacky 81235633Sdimchar SjLjEHPrepare::ID = 0; 82198090Srdivacky 83235633Sdim// Public Interface To the SjLjEHPrepare pass. 84263509SdimFunctionPass *llvm::createSjLjEHPreparePass(const TargetMachine *TM) { 85263509Sdim return new SjLjEHPrepare(TM); 86198090Srdivacky} 87198090Srdivacky// doInitialization - Set up decalarations and types needed to process 88198090Srdivacky// exceptions. 89235633Sdimbool SjLjEHPrepare::doInitialization(Module &M) { 90198090Srdivacky // Build the function context structure. 91198090Srdivacky // builtin_setjmp uses a five word jbuf 92224145Sdim Type *VoidPtrTy = Type::getInt8PtrTy(M.getContext()); 93224145Sdim Type *Int32Ty = Type::getInt32Ty(M.getContext()); 94263509Sdim FunctionContextTy = StructType::get(VoidPtrTy, // __prev 95263509Sdim Int32Ty, // call_site 96263509Sdim ArrayType::get(Int32Ty, 4), // __data 97263509Sdim VoidPtrTy, // __personality 98263509Sdim VoidPtrTy, // __lsda 99263509Sdim ArrayType::get(VoidPtrTy, 5), // __jbuf 100263509Sdim NULL); 101263509Sdim RegisterFn = M.getOrInsertFunction( 102263509Sdim "_Unwind_SjLj_Register", Type::getVoidTy(M.getContext()), 103263509Sdim PointerType::getUnqual(FunctionContextTy), (Type *)0); 104263509Sdim UnregisterFn = M.getOrInsertFunction( 105263509Sdim "_Unwind_SjLj_Unregister", Type::getVoidTy(M.getContext()), 106263509Sdim PointerType::getUnqual(FunctionContextTy), (Type *)0); 107198090Srdivacky FrameAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::frameaddress); 108210299Sed StackAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::stacksave); 109210299Sed StackRestoreFn = Intrinsic::getDeclaration(&M, Intrinsic::stackrestore); 110198090Srdivacky BuiltinSetjmpFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_setjmp); 111198090Srdivacky LSDAAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_lsda); 112203954Srdivacky CallSiteFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_callsite); 113226890Sdim FuncCtxFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_functioncontext); 114198090Srdivacky PersonalityFn = 0; 115198090Srdivacky 116198090Srdivacky return true; 117198090Srdivacky} 118198090Srdivacky 119204792Srdivacky/// insertCallSiteStore - Insert a store of the call-site value to the 120204792Srdivacky/// function context 121235633Sdimvoid SjLjEHPrepare::insertCallSiteStore(Instruction *I, int Number) { 122235633Sdim IRBuilder<> Builder(I); 123235633Sdim 124235633Sdim // Get a reference to the call_site field. 125235633Sdim Type *Int32Ty = Type::getInt32Ty(I->getContext()); 126235633Sdim Value *Zero = ConstantInt::get(Int32Ty, 0); 127235633Sdim Value *One = ConstantInt::get(Int32Ty, 1); 128235633Sdim Value *Idxs[2] = { Zero, One }; 129235633Sdim Value *CallSite = Builder.CreateGEP(FuncCtx, Idxs, "call_site"); 130235633Sdim 131235633Sdim // Insert a store of the call-site number 132263509Sdim ConstantInt *CallSiteNoC = 133263509Sdim ConstantInt::get(Type::getInt32Ty(I->getContext()), Number); 134263509Sdim Builder.CreateStore(CallSiteNoC, CallSite, true /*volatile*/); 135204792Srdivacky} 136204792Srdivacky 137198090Srdivacky/// MarkBlocksLiveIn - Insert BB and all of its predescessors into LiveBBs until 138198090Srdivacky/// we reach blocks we've already seen. 139235633Sdimstatic void MarkBlocksLiveIn(BasicBlock *BB, 140263509Sdim SmallPtrSet<BasicBlock *, 64> &LiveBBs) { 141263509Sdim if (!LiveBBs.insert(BB)) 142263509Sdim return; // already been here. 143198090Srdivacky 144198090Srdivacky for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) 145198090Srdivacky MarkBlocksLiveIn(*PI, LiveBBs); 146198090Srdivacky} 147198090Srdivacky 148235633Sdim/// substituteLPadValues - Substitute the values returned by the landingpad 149235633Sdim/// instruction with those returned by the personality function. 150235633Sdimvoid SjLjEHPrepare::substituteLPadValues(LandingPadInst *LPI, Value *ExnVal, 151235633Sdim Value *SelVal) { 152263509Sdim SmallVector<Value *, 8> UseWorkList(LPI->use_begin(), LPI->use_end()); 153235633Sdim while (!UseWorkList.empty()) { 154235633Sdim Value *Val = UseWorkList.pop_back_val(); 155235633Sdim ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(Val); 156263509Sdim if (!EVI) 157263509Sdim continue; 158263509Sdim if (EVI->getNumIndices() != 1) 159263509Sdim continue; 160235633Sdim if (*EVI->idx_begin() == 0) 161235633Sdim EVI->replaceAllUsesWith(ExnVal); 162235633Sdim else if (*EVI->idx_begin() == 1) 163235633Sdim EVI->replaceAllUsesWith(SelVal); 164235633Sdim if (EVI->getNumUses() == 0) 165235633Sdim EVI->eraseFromParent(); 166198090Srdivacky } 167198090Srdivacky 168263509Sdim if (LPI->getNumUses() == 0) 169263509Sdim return; 170198090Srdivacky 171235633Sdim // There are still some uses of LPI. Construct an aggregate with the exception 172235633Sdim // values and replace the LPI with that aggregate. 173235633Sdim Type *LPadType = LPI->getType(); 174235633Sdim Value *LPadVal = UndefValue::get(LPadType); 175263509Sdim IRBuilder<> Builder( 176263509Sdim llvm::next(BasicBlock::iterator(cast<Instruction>(SelVal)))); 177235633Sdim LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0, "lpad.val"); 178235633Sdim LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1, "lpad.val"); 179198090Srdivacky 180235633Sdim LPI->replaceAllUsesWith(LPadVal); 181198090Srdivacky} 182198090Srdivacky 183226890Sdim/// setupFunctionContext - Allocate the function context on the stack and fill 184226890Sdim/// it with all of the data that we know at this point. 185263509SdimValue *SjLjEHPrepare::setupFunctionContext(Function &F, 186263509Sdim ArrayRef<LandingPadInst *> LPads) { 187226890Sdim BasicBlock *EntryBB = F.begin(); 188226890Sdim 189226890Sdim // Create an alloca for the incoming jump buffer ptr and the new jump buffer 190226890Sdim // that needs to be restored on all exits from the function. This is an alloca 191226890Sdim // because the value needs to be added to the global context list. 192263509Sdim const TargetLowering *TLI = TM->getTargetLowering(); 193226890Sdim unsigned Align = 194263509Sdim TLI->getDataLayout()->getPrefTypeAlignment(FunctionContextTy); 195263509Sdim FuncCtx = new AllocaInst(FunctionContextTy, 0, Align, "fn_context", 196263509Sdim EntryBB->begin()); 197226890Sdim 198226890Sdim // Fill in the function context structure. 199226890Sdim for (unsigned I = 0, E = LPads.size(); I != E; ++I) { 200226890Sdim LandingPadInst *LPI = LPads[I]; 201226890Sdim IRBuilder<> Builder(LPI->getParent()->getFirstInsertionPt()); 202226890Sdim 203235633Sdim // Reference the __data field. 204245431Sdim Value *FCData = Builder.CreateConstGEP2_32(FuncCtx, 0, 2, "__data"); 205235633Sdim 206235633Sdim // The exception values come back in context->__data[0]. 207263509Sdim Value *ExceptionAddr = 208263509Sdim Builder.CreateConstGEP2_32(FCData, 0, 0, "exception_gep"); 209226890Sdim Value *ExnVal = Builder.CreateLoad(ExceptionAddr, true, "exn_val"); 210245431Sdim ExnVal = Builder.CreateIntToPtr(ExnVal, Builder.getInt8PtrTy()); 211235633Sdim 212263509Sdim Value *SelectorAddr = 213263509Sdim Builder.CreateConstGEP2_32(FCData, 0, 1, "exn_selector_gep"); 214226890Sdim Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val"); 215226890Sdim 216235633Sdim substituteLPadValues(LPI, ExnVal, SelVal); 217226890Sdim } 218226890Sdim 219226890Sdim // Personality function 220245431Sdim IRBuilder<> Builder(EntryBB->getTerminator()); 221226890Sdim if (!PersonalityFn) 222226890Sdim PersonalityFn = LPads[0]->getPersonalityFn(); 223263509Sdim Value *PersonalityFieldPtr = 224263509Sdim Builder.CreateConstGEP2_32(FuncCtx, 0, 3, "pers_fn_gep"); 225263509Sdim Builder.CreateStore( 226263509Sdim Builder.CreateBitCast(PersonalityFn, Builder.getInt8PtrTy()), 227263509Sdim PersonalityFieldPtr, /*isVolatile=*/true); 228226890Sdim 229226890Sdim // LSDA address 230245431Sdim Value *LSDA = Builder.CreateCall(LSDAAddrFn, "lsda_addr"); 231245431Sdim Value *LSDAFieldPtr = Builder.CreateConstGEP2_32(FuncCtx, 0, 4, "lsda_gep"); 232245431Sdim Builder.CreateStore(LSDA, LSDAFieldPtr, /*isVolatile=*/true); 233226890Sdim 234226890Sdim return FuncCtx; 235226890Sdim} 236226890Sdim 237226890Sdim/// lowerIncomingArguments - To avoid having to handle incoming arguments 238226890Sdim/// specially, we lower each arg to a copy instruction in the entry block. This 239226890Sdim/// ensures that the argument value itself cannot be live out of the entry 240226890Sdim/// block. 241235633Sdimvoid SjLjEHPrepare::lowerIncomingArguments(Function &F) { 242226890Sdim BasicBlock::iterator AfterAllocaInsPt = F.begin()->begin(); 243226890Sdim while (isa<AllocaInst>(AfterAllocaInsPt) && 244226890Sdim isa<ConstantInt>(cast<AllocaInst>(AfterAllocaInsPt)->getArraySize())) 245226890Sdim ++AfterAllocaInsPt; 246226890Sdim 247263509Sdim for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end(); AI != AE; 248263509Sdim ++AI) { 249226890Sdim Type *Ty = AI->getType(); 250226890Sdim 251226890Sdim // Aggregate types can't be cast, but are legal argument types, so we have 252226890Sdim // to handle them differently. We use an extract/insert pair as a 253226890Sdim // lightweight method to achieve the same goal. 254226890Sdim if (isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) { 255226890Sdim Instruction *EI = ExtractValueInst::Create(AI, 0, "", AfterAllocaInsPt); 256226890Sdim Instruction *NI = InsertValueInst::Create(AI, EI, 0); 257226890Sdim NI->insertAfter(EI); 258226890Sdim AI->replaceAllUsesWith(NI); 259226890Sdim 260226890Sdim // Set the operand of the instructions back to the AllocaInst. 261226890Sdim EI->setOperand(0, AI); 262226890Sdim NI->setOperand(0, AI); 263226890Sdim } else { 264226890Sdim // This is always a no-op cast because we're casting AI to AI->getType() 265226890Sdim // so src and destination types are identical. BitCast is the only 266226890Sdim // possibility. 267263509Sdim CastInst *NC = new BitCastInst(AI, AI->getType(), AI->getName() + ".tmp", 268263509Sdim AfterAllocaInsPt); 269226890Sdim AI->replaceAllUsesWith(NC); 270226890Sdim 271226890Sdim // Set the operand of the cast instruction back to the AllocaInst. 272226890Sdim // Normally it's forbidden to replace a CastInst's operand because it 273226890Sdim // could cause the opcode to reflect an illegal conversion. However, we're 274226890Sdim // replacing it here with the same value it was constructed with. We do 275226890Sdim // this because the above replaceAllUsesWith() clobbered the operand, but 276226890Sdim // we want this one to remain. 277226890Sdim NC->setOperand(0, AI); 278226890Sdim } 279226890Sdim } 280226890Sdim} 281226890Sdim 282226890Sdim/// lowerAcrossUnwindEdges - Find all variables which are alive across an unwind 283226890Sdim/// edge and spill them. 284235633Sdimvoid SjLjEHPrepare::lowerAcrossUnwindEdges(Function &F, 285263509Sdim ArrayRef<InvokeInst *> Invokes) { 286226890Sdim // Finally, scan the code looking for instructions with bad live ranges. 287263509Sdim for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) { 288263509Sdim for (BasicBlock::iterator II = BB->begin(), IIE = BB->end(); II != IIE; 289263509Sdim ++II) { 290226890Sdim // Ignore obvious cases we don't have to handle. In particular, most 291226890Sdim // instructions either have no uses or only have a single use inside the 292226890Sdim // current block. Ignore them quickly. 293226890Sdim Instruction *Inst = II; 294263509Sdim if (Inst->use_empty()) 295263509Sdim continue; 296226890Sdim if (Inst->hasOneUse() && 297226890Sdim cast<Instruction>(Inst->use_back())->getParent() == BB && 298263509Sdim !isa<PHINode>(Inst->use_back())) 299263509Sdim continue; 300226890Sdim 301226890Sdim // If this is an alloca in the entry block, it's not a real register 302226890Sdim // value. 303226890Sdim if (AllocaInst *AI = dyn_cast<AllocaInst>(Inst)) 304226890Sdim if (isa<ConstantInt>(AI->getArraySize()) && BB == F.begin()) 305226890Sdim continue; 306226890Sdim 307226890Sdim // Avoid iterator invalidation by copying users to a temporary vector. 308263509Sdim SmallVector<Instruction *, 16> Users; 309263509Sdim for (Value::use_iterator UI = Inst->use_begin(), E = Inst->use_end(); 310263509Sdim UI != E; ++UI) { 311226890Sdim Instruction *User = cast<Instruction>(*UI); 312226890Sdim if (User->getParent() != BB || isa<PHINode>(User)) 313226890Sdim Users.push_back(User); 314226890Sdim } 315226890Sdim 316226890Sdim // Find all of the blocks that this value is live in. 317263509Sdim SmallPtrSet<BasicBlock *, 64> LiveBBs; 318226890Sdim LiveBBs.insert(Inst->getParent()); 319226890Sdim while (!Users.empty()) { 320226890Sdim Instruction *U = Users.back(); 321226890Sdim Users.pop_back(); 322226890Sdim 323226890Sdim if (!isa<PHINode>(U)) { 324226890Sdim MarkBlocksLiveIn(U->getParent(), LiveBBs); 325226890Sdim } else { 326226890Sdim // Uses for a PHI node occur in their predecessor block. 327226890Sdim PHINode *PN = cast<PHINode>(U); 328226890Sdim for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 329226890Sdim if (PN->getIncomingValue(i) == Inst) 330226890Sdim MarkBlocksLiveIn(PN->getIncomingBlock(i), LiveBBs); 331226890Sdim } 332226890Sdim } 333226890Sdim 334226890Sdim // Now that we know all of the blocks that this thing is live in, see if 335226890Sdim // it includes any of the unwind locations. 336226890Sdim bool NeedsSpill = false; 337226890Sdim for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { 338226890Sdim BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); 339226890Sdim if (UnwindBlock != BB && LiveBBs.count(UnwindBlock)) { 340235633Sdim DEBUG(dbgs() << "SJLJ Spill: " << *Inst << " around " 341263509Sdim << UnwindBlock->getName() << "\n"); 342226890Sdim NeedsSpill = true; 343235633Sdim break; 344226890Sdim } 345226890Sdim } 346226890Sdim 347226890Sdim // If we decided we need a spill, do it. 348226890Sdim // FIXME: Spilling this way is overkill, as it forces all uses of 349226890Sdim // the value to be reloaded from the stack slot, even those that aren't 350226890Sdim // in the unwind blocks. We should be more selective. 351226890Sdim if (NeedsSpill) { 352235633Sdim DemoteRegToStack(*Inst, true); 353226890Sdim ++NumSpilled; 354226890Sdim } 355226890Sdim } 356226890Sdim } 357235633Sdim 358235633Sdim // Go through the landing pads and remove any PHIs there. 359235633Sdim for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { 360235633Sdim BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); 361235633Sdim LandingPadInst *LPI = UnwindBlock->getLandingPadInst(); 362235633Sdim 363235633Sdim // Place PHIs into a set to avoid invalidating the iterator. 364263509Sdim SmallPtrSet<PHINode *, 8> PHIsToDemote; 365263509Sdim for (BasicBlock::iterator PN = UnwindBlock->begin(); isa<PHINode>(PN); ++PN) 366235633Sdim PHIsToDemote.insert(cast<PHINode>(PN)); 367263509Sdim if (PHIsToDemote.empty()) 368263509Sdim continue; 369235633Sdim 370235633Sdim // Demote the PHIs to the stack. 371263509Sdim for (SmallPtrSet<PHINode *, 8>::iterator I = PHIsToDemote.begin(), 372263509Sdim E = PHIsToDemote.end(); 373263509Sdim I != E; ++I) 374235633Sdim DemotePHIToStack(*I); 375235633Sdim 376235633Sdim // Move the landingpad instruction back to the top of the landing pad block. 377235633Sdim LPI->moveBefore(UnwindBlock->begin()); 378235633Sdim } 379226890Sdim} 380226890Sdim 381226890Sdim/// setupEntryBlockAndCallSites - Setup the entry block by creating and filling 382226890Sdim/// the function context and marking the call sites with the appropriate 383226890Sdim/// values. These values are used by the DWARF EH emitter. 384235633Sdimbool SjLjEHPrepare::setupEntryBlockAndCallSites(Function &F) { 385263509Sdim SmallVector<ReturnInst *, 16> Returns; 386263509Sdim SmallVector<InvokeInst *, 16> Invokes; 387263509Sdim SmallSetVector<LandingPadInst *, 16> LPads; 388226890Sdim 389226890Sdim // Look through the terminators of the basic blocks to find invokes. 390226890Sdim for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 391226890Sdim if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) { 392252723Sdim if (Function *Callee = II->getCalledFunction()) 393252723Sdim if (Callee->isIntrinsic() && 394252723Sdim Callee->getIntrinsicID() == Intrinsic::donothing) { 395252723Sdim // Remove the NOP invoke. 396252723Sdim BranchInst::Create(II->getNormalDest(), II); 397252723Sdim II->eraseFromParent(); 398252723Sdim continue; 399252723Sdim } 400252723Sdim 401226890Sdim Invokes.push_back(II); 402235633Sdim LPads.insert(II->getUnwindDest()->getLandingPadInst()); 403226890Sdim } else if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) { 404226890Sdim Returns.push_back(RI); 405226890Sdim } 406226890Sdim 407263509Sdim if (Invokes.empty()) 408263509Sdim return false; 409226890Sdim 410235633Sdim NumInvokes += Invokes.size(); 411235633Sdim 412226890Sdim lowerIncomingArguments(F); 413226890Sdim lowerAcrossUnwindEdges(F, Invokes); 414226890Sdim 415235633Sdim Value *FuncCtx = 416263509Sdim setupFunctionContext(F, makeArrayRef(LPads.begin(), LPads.end())); 417226890Sdim BasicBlock *EntryBB = F.begin(); 418245431Sdim IRBuilder<> Builder(EntryBB->getTerminator()); 419226890Sdim 420226890Sdim // Get a reference to the jump buffer. 421245431Sdim Value *JBufPtr = Builder.CreateConstGEP2_32(FuncCtx, 0, 5, "jbuf_gep"); 422226890Sdim 423226890Sdim // Save the frame pointer. 424245431Sdim Value *FramePtr = Builder.CreateConstGEP2_32(JBufPtr, 0, 0, "jbuf_fp_gep"); 425226890Sdim 426245431Sdim Value *Val = Builder.CreateCall(FrameAddrFn, Builder.getInt32(0), "fp"); 427245431Sdim Builder.CreateStore(Val, FramePtr, /*isVolatile=*/true); 428226890Sdim 429226890Sdim // Save the stack pointer. 430245431Sdim Value *StackPtr = Builder.CreateConstGEP2_32(JBufPtr, 0, 2, "jbuf_sp_gep"); 431226890Sdim 432245431Sdim Val = Builder.CreateCall(StackAddrFn, "sp"); 433245431Sdim Builder.CreateStore(Val, StackPtr, /*isVolatile=*/true); 434226890Sdim 435226890Sdim // Call the setjmp instrinsic. It fills in the rest of the jmpbuf. 436245431Sdim Value *SetjmpArg = Builder.CreateBitCast(JBufPtr, Builder.getInt8PtrTy()); 437245431Sdim Builder.CreateCall(BuiltinSetjmpFn, SetjmpArg); 438226890Sdim 439226890Sdim // Store a pointer to the function context so that the back-end will know 440226890Sdim // where to look for it. 441245431Sdim Value *FuncCtxArg = Builder.CreateBitCast(FuncCtx, Builder.getInt8PtrTy()); 442245431Sdim Builder.CreateCall(FuncCtxFn, FuncCtxArg); 443226890Sdim 444226890Sdim // At this point, we are all set up, update the invoke instructions to mark 445226890Sdim // their call_site values. 446226890Sdim for (unsigned I = 0, E = Invokes.size(); I != E; ++I) { 447235633Sdim insertCallSiteStore(Invokes[I], I + 1); 448226890Sdim 449226890Sdim ConstantInt *CallSiteNum = 450263509Sdim ConstantInt::get(Type::getInt32Ty(F.getContext()), I + 1); 451226890Sdim 452226890Sdim // Record the call site value for the back end so it stays associated with 453226890Sdim // the invoke. 454226890Sdim CallInst::Create(CallSiteFn, CallSiteNum, "", Invokes[I]); 455226890Sdim } 456226890Sdim 457226890Sdim // Mark call instructions that aren't nounwind as no-action (call_site == 458226890Sdim // -1). Skip the entry block, as prior to then, no function context has been 459226890Sdim // created for this function and any unexpected exceptions thrown will go 460226890Sdim // directly to the caller's context, which is what we want anyway, so no need 461226890Sdim // to do anything here. 462226890Sdim for (Function::iterator BB = F.begin(), E = F.end(); ++BB != E;) 463226890Sdim for (BasicBlock::iterator I = BB->begin(), end = BB->end(); I != end; ++I) 464226890Sdim if (CallInst *CI = dyn_cast<CallInst>(I)) { 465226890Sdim if (!CI->doesNotThrow()) 466235633Sdim insertCallSiteStore(CI, -1); 467226890Sdim } else if (ResumeInst *RI = dyn_cast<ResumeInst>(I)) { 468235633Sdim insertCallSiteStore(RI, -1); 469226890Sdim } 470226890Sdim 471226890Sdim // Register the function context and make sure it's known to not throw 472263509Sdim CallInst *Register = 473263509Sdim CallInst::Create(RegisterFn, FuncCtx, "", EntryBB->getTerminator()); 474226890Sdim Register->setDoesNotThrow(); 475226890Sdim 476235633Sdim // Following any allocas not in the entry block, update the saved SP in the 477235633Sdim // jmpbuf to the new value. 478235633Sdim for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { 479235633Sdim if (BB == F.begin()) 480235633Sdim continue; 481235633Sdim for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { 482235633Sdim if (CallInst *CI = dyn_cast<CallInst>(I)) { 483235633Sdim if (CI->getCalledFunction() != StackRestoreFn) 484235633Sdim continue; 485235633Sdim } else if (!isa<AllocaInst>(I)) { 486235633Sdim continue; 487235633Sdim } 488235633Sdim Instruction *StackAddr = CallInst::Create(StackAddrFn, "sp"); 489235633Sdim StackAddr->insertAfter(I); 490235633Sdim Instruction *StoreStackAddr = new StoreInst(StackAddr, StackPtr, true); 491235633Sdim StoreStackAddr->insertAfter(StackAddr); 492235633Sdim } 493235633Sdim } 494235633Sdim 495226890Sdim // Finally, for any returns from this function, if this function contains an 496226890Sdim // invoke, add a call to unregister the function context. 497226890Sdim for (unsigned I = 0, E = Returns.size(); I != E; ++I) 498226890Sdim CallInst::Create(UnregisterFn, FuncCtx, "", Returns[I]); 499226890Sdim 500226890Sdim return true; 501226890Sdim} 502226890Sdim 503235633Sdimbool SjLjEHPrepare::runOnFunction(Function &F) { 504235633Sdim bool Res = setupEntryBlockAndCallSites(F); 505198090Srdivacky return Res; 506198090Srdivacky} 507