1234353Sdim//===- 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 15249423Sdim#include "llvm/CodeGen/Passes.h" 16239462Sdim#include "llvm/ADT/DenseMap.h" 17239462Sdim#include "llvm/ADT/SetVector.h" 18239462Sdim#include "llvm/ADT/SmallPtrSet.h" 19239462Sdim#include "llvm/ADT/SmallVector.h" 20239462Sdim#include "llvm/ADT/Statistic.h" 21249423Sdim#include "llvm/IR/Constants.h" 22249423Sdim#include "llvm/IR/DataLayout.h" 23249423Sdim#include "llvm/IR/DerivedTypes.h" 24249423Sdim#include "llvm/IR/IRBuilder.h" 25249423Sdim#include "llvm/IR/Instructions.h" 26249423Sdim#include "llvm/IR/Intrinsics.h" 27249423Sdim#include "llvm/IR/LLVMContext.h" 28249423Sdim#include "llvm/IR/Module.h" 29249423Sdim#include "llvm/Pass.h" 30239462Sdim#include "llvm/Support/CommandLine.h" 31239462Sdim#include "llvm/Support/Debug.h" 32239462Sdim#include "llvm/Support/raw_ostream.h" 33218893Sdim#include "llvm/Target/TargetLowering.h" 34280031Sdim#include "llvm/Target/TargetSubtargetInfo.h" 35239462Sdim#include "llvm/Transforms/Scalar.h" 36198090Srdivacky#include "llvm/Transforms/Utils/BasicBlockUtils.h" 37198090Srdivacky#include "llvm/Transforms/Utils/Local.h" 38218893Sdim#include <set> 39198090Srdivackyusing namespace llvm; 40198090Srdivacky 41276479Sdim#define DEBUG_TYPE "sjljehprepare" 42276479Sdim 43198090SrdivackySTATISTIC(NumInvokes, "Number of invokes replaced"); 44198090SrdivackySTATISTIC(NumSpilled, "Number of registers live across unwind edges"); 45198090Srdivacky 46198090Srdivackynamespace { 47261991Sdimclass SjLjEHPrepare : public FunctionPass { 48288943Sdim Type *doubleUnderDataTy; 49288943Sdim Type *doubleUnderJBufTy; 50261991Sdim Type *FunctionContextTy; 51261991Sdim Constant *RegisterFn; 52261991Sdim Constant *UnregisterFn; 53296417Sdim Constant *BuiltinSetupDispatchFn; 54261991Sdim Constant *FrameAddrFn; 55261991Sdim Constant *StackAddrFn; 56261991Sdim Constant *StackRestoreFn; 57261991Sdim Constant *LSDAAddrFn; 58261991Sdim Value *PersonalityFn; 59261991Sdim Constant *CallSiteFn; 60261991Sdim Constant *FuncCtxFn; 61261991Sdim AllocaInst *FuncCtx; 62198090Srdivacky 63261991Sdimpublic: 64261991Sdim static char ID; // Pass identification, replacement for typeid 65288943Sdim explicit SjLjEHPrepare() : FunctionPass(ID) {} 66276479Sdim bool doInitialization(Module &M) override; 67276479Sdim bool runOnFunction(Function &F) override; 68198090Srdivacky 69276479Sdim void getAnalysisUsage(AnalysisUsage &AU) const override {} 70276479Sdim const char *getPassName() const override { 71261991Sdim return "SJLJ Exception Handling preparation"; 72261991Sdim } 73261991Sdim 74261991Sdimprivate: 75261991Sdim bool setupEntryBlockAndCallSites(Function &F); 76261991Sdim void substituteLPadValues(LandingPadInst *LPI, Value *ExnVal, Value *SelVal); 77261991Sdim Value *setupFunctionContext(Function &F, ArrayRef<LandingPadInst *> LPads); 78261991Sdim void lowerIncomingArguments(Function &F); 79261991Sdim void lowerAcrossUnwindEdges(Function &F, ArrayRef<InvokeInst *> Invokes); 80261991Sdim void insertCallSiteStore(Instruction *I, int Number); 81261991Sdim}; 82198090Srdivacky} // end anonymous namespace 83198090Srdivacky 84234353Sdimchar SjLjEHPrepare::ID = 0; 85288943SdimINITIALIZE_PASS(SjLjEHPrepare, "sjljehprepare", "Prepare SjLj exceptions", 86288943Sdim false, false) 87198090Srdivacky 88234353Sdim// Public Interface To the SjLjEHPrepare pass. 89288943SdimFunctionPass *llvm::createSjLjEHPreparePass() { return new SjLjEHPrepare(); } 90198090Srdivacky// doInitialization - Set up decalarations and types needed to process 91198090Srdivacky// exceptions. 92234353Sdimbool SjLjEHPrepare::doInitialization(Module &M) { 93198090Srdivacky // Build the function context structure. 94198090Srdivacky // builtin_setjmp uses a five word jbuf 95224145Sdim Type *VoidPtrTy = Type::getInt8PtrTy(M.getContext()); 96224145Sdim Type *Int32Ty = Type::getInt32Ty(M.getContext()); 97288943Sdim doubleUnderDataTy = ArrayType::get(Int32Ty, 4); 98288943Sdim doubleUnderJBufTy = ArrayType::get(VoidPtrTy, 5); 99288943Sdim FunctionContextTy = StructType::get(VoidPtrTy, // __prev 100288943Sdim Int32Ty, // call_site 101288943Sdim doubleUnderDataTy, // __data 102288943Sdim VoidPtrTy, // __personality 103288943Sdim VoidPtrTy, // __lsda 104288943Sdim doubleUnderJBufTy, // __jbuf 105280031Sdim nullptr); 106261991Sdim RegisterFn = M.getOrInsertFunction( 107261991Sdim "_Unwind_SjLj_Register", Type::getVoidTy(M.getContext()), 108276479Sdim PointerType::getUnqual(FunctionContextTy), (Type *)nullptr); 109261991Sdim UnregisterFn = M.getOrInsertFunction( 110261991Sdim "_Unwind_SjLj_Unregister", Type::getVoidTy(M.getContext()), 111276479Sdim PointerType::getUnqual(FunctionContextTy), (Type *)nullptr); 112198090Srdivacky FrameAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::frameaddress); 113210299Sed StackAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::stacksave); 114210299Sed StackRestoreFn = Intrinsic::getDeclaration(&M, Intrinsic::stackrestore); 115296417Sdim BuiltinSetupDispatchFn = 116296417Sdim Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_setup_dispatch); 117198090Srdivacky LSDAAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_lsda); 118203954Srdivacky CallSiteFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_callsite); 119226633Sdim FuncCtxFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_functioncontext); 120276479Sdim PersonalityFn = nullptr; 121198090Srdivacky 122198090Srdivacky return true; 123198090Srdivacky} 124198090Srdivacky 125204792Srdivacky/// insertCallSiteStore - Insert a store of the call-site value to the 126204792Srdivacky/// function context 127234353Sdimvoid SjLjEHPrepare::insertCallSiteStore(Instruction *I, int Number) { 128234353Sdim IRBuilder<> Builder(I); 129234353Sdim 130234353Sdim // Get a reference to the call_site field. 131234353Sdim Type *Int32Ty = Type::getInt32Ty(I->getContext()); 132234353Sdim Value *Zero = ConstantInt::get(Int32Ty, 0); 133234353Sdim Value *One = ConstantInt::get(Int32Ty, 1); 134234353Sdim Value *Idxs[2] = { Zero, One }; 135288943Sdim Value *CallSite = 136288943Sdim Builder.CreateGEP(FunctionContextTy, FuncCtx, Idxs, "call_site"); 137234353Sdim 138234353Sdim // Insert a store of the call-site number 139261991Sdim ConstantInt *CallSiteNoC = 140261991Sdim ConstantInt::get(Type::getInt32Ty(I->getContext()), Number); 141261991Sdim Builder.CreateStore(CallSiteNoC, CallSite, true /*volatile*/); 142204792Srdivacky} 143204792Srdivacky 144198090Srdivacky/// MarkBlocksLiveIn - Insert BB and all of its predescessors into LiveBBs until 145198090Srdivacky/// we reach blocks we've already seen. 146234353Sdimstatic void MarkBlocksLiveIn(BasicBlock *BB, 147280031Sdim SmallPtrSetImpl<BasicBlock *> &LiveBBs) { 148280031Sdim if (!LiveBBs.insert(BB).second) 149261991Sdim return; // already been here. 150198090Srdivacky 151198090Srdivacky for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) 152198090Srdivacky MarkBlocksLiveIn(*PI, LiveBBs); 153198090Srdivacky} 154198090Srdivacky 155234353Sdim/// substituteLPadValues - Substitute the values returned by the landingpad 156234353Sdim/// instruction with those returned by the personality function. 157234353Sdimvoid SjLjEHPrepare::substituteLPadValues(LandingPadInst *LPI, Value *ExnVal, 158234353Sdim Value *SelVal) { 159276479Sdim SmallVector<Value *, 8> UseWorkList(LPI->user_begin(), LPI->user_end()); 160234353Sdim while (!UseWorkList.empty()) { 161234353Sdim Value *Val = UseWorkList.pop_back_val(); 162234353Sdim ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(Val); 163261991Sdim if (!EVI) 164261991Sdim continue; 165261991Sdim if (EVI->getNumIndices() != 1) 166261991Sdim continue; 167234353Sdim if (*EVI->idx_begin() == 0) 168234353Sdim EVI->replaceAllUsesWith(ExnVal); 169234353Sdim else if (*EVI->idx_begin() == 1) 170234353Sdim EVI->replaceAllUsesWith(SelVal); 171234353Sdim if (EVI->getNumUses() == 0) 172234353Sdim EVI->eraseFromParent(); 173198090Srdivacky } 174198090Srdivacky 175261991Sdim if (LPI->getNumUses() == 0) 176261991Sdim return; 177198090Srdivacky 178234353Sdim // There are still some uses of LPI. Construct an aggregate with the exception 179234353Sdim // values and replace the LPI with that aggregate. 180234353Sdim Type *LPadType = LPI->getType(); 181234353Sdim Value *LPadVal = UndefValue::get(LPadType); 182296417Sdim auto *SelI = cast<Instruction>(SelVal); 183296417Sdim IRBuilder<> Builder(SelI->getParent(), std::next(SelI->getIterator())); 184234353Sdim LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0, "lpad.val"); 185234353Sdim LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1, "lpad.val"); 186198090Srdivacky 187234353Sdim LPI->replaceAllUsesWith(LPadVal); 188198090Srdivacky} 189198090Srdivacky 190226633Sdim/// setupFunctionContext - Allocate the function context on the stack and fill 191226633Sdim/// it with all of the data that we know at this point. 192261991SdimValue *SjLjEHPrepare::setupFunctionContext(Function &F, 193261991Sdim ArrayRef<LandingPadInst *> LPads) { 194296417Sdim BasicBlock *EntryBB = &F.front(); 195226633Sdim 196226633Sdim // Create an alloca for the incoming jump buffer ptr and the new jump buffer 197226633Sdim // that needs to be restored on all exits from the function. This is an alloca 198226633Sdim // because the value needs to be added to the global context list. 199288943Sdim auto &DL = F.getParent()->getDataLayout(); 200288943Sdim unsigned Align = DL.getPrefTypeAlignment(FunctionContextTy); 201276479Sdim FuncCtx = new AllocaInst(FunctionContextTy, nullptr, Align, "fn_context", 202296417Sdim &EntryBB->front()); 203226633Sdim 204226633Sdim // Fill in the function context structure. 205226633Sdim for (unsigned I = 0, E = LPads.size(); I != E; ++I) { 206226633Sdim LandingPadInst *LPI = LPads[I]; 207296417Sdim IRBuilder<> Builder(LPI->getParent(), 208296417Sdim LPI->getParent()->getFirstInsertionPt()); 209226633Sdim 210234353Sdim // Reference the __data field. 211288943Sdim Value *FCData = 212288943Sdim Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 2, "__data"); 213234353Sdim 214234353Sdim // The exception values come back in context->__data[0]. 215288943Sdim Value *ExceptionAddr = Builder.CreateConstGEP2_32(doubleUnderDataTy, FCData, 216288943Sdim 0, 0, "exception_gep"); 217226633Sdim Value *ExnVal = Builder.CreateLoad(ExceptionAddr, true, "exn_val"); 218243830Sdim ExnVal = Builder.CreateIntToPtr(ExnVal, Builder.getInt8PtrTy()); 219234353Sdim 220288943Sdim Value *SelectorAddr = Builder.CreateConstGEP2_32(doubleUnderDataTy, FCData, 221288943Sdim 0, 1, "exn_selector_gep"); 222226633Sdim Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val"); 223226633Sdim 224234353Sdim substituteLPadValues(LPI, ExnVal, SelVal); 225226633Sdim } 226226633Sdim 227226633Sdim // Personality function 228243830Sdim IRBuilder<> Builder(EntryBB->getTerminator()); 229226633Sdim if (!PersonalityFn) 230288943Sdim PersonalityFn = F.getPersonalityFn(); 231288943Sdim Value *PersonalityFieldPtr = Builder.CreateConstGEP2_32( 232288943Sdim FunctionContextTy, FuncCtx, 0, 3, "pers_fn_gep"); 233261991Sdim Builder.CreateStore( 234261991Sdim Builder.CreateBitCast(PersonalityFn, Builder.getInt8PtrTy()), 235261991Sdim PersonalityFieldPtr, /*isVolatile=*/true); 236226633Sdim 237226633Sdim // LSDA address 238288943Sdim Value *LSDA = Builder.CreateCall(LSDAAddrFn, {}, "lsda_addr"); 239288943Sdim Value *LSDAFieldPtr = 240288943Sdim Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 4, "lsda_gep"); 241243830Sdim Builder.CreateStore(LSDA, LSDAFieldPtr, /*isVolatile=*/true); 242226633Sdim 243226633Sdim return FuncCtx; 244226633Sdim} 245226633Sdim 246226633Sdim/// lowerIncomingArguments - To avoid having to handle incoming arguments 247226633Sdim/// specially, we lower each arg to a copy instruction in the entry block. This 248226633Sdim/// ensures that the argument value itself cannot be live out of the entry 249226633Sdim/// block. 250234353Sdimvoid SjLjEHPrepare::lowerIncomingArguments(Function &F) { 251226633Sdim BasicBlock::iterator AfterAllocaInsPt = F.begin()->begin(); 252226633Sdim while (isa<AllocaInst>(AfterAllocaInsPt) && 253226633Sdim isa<ConstantInt>(cast<AllocaInst>(AfterAllocaInsPt)->getArraySize())) 254226633Sdim ++AfterAllocaInsPt; 255296417Sdim assert(AfterAllocaInsPt != F.front().end()); 256226633Sdim 257296417Sdim for (auto &AI : F.args()) { 258296417Sdim Type *Ty = AI.getType(); 259226633Sdim 260276479Sdim // Use 'select i8 true, %arg, undef' to simulate a 'no-op' instruction. 261276479Sdim Value *TrueValue = ConstantInt::getTrue(F.getContext()); 262276479Sdim Value *UndefValue = UndefValue::get(Ty); 263296417Sdim Instruction *SI = SelectInst::Create( 264296417Sdim TrueValue, &AI, UndefValue, AI.getName() + ".tmp", &*AfterAllocaInsPt); 265296417Sdim AI.replaceAllUsesWith(SI); 266226633Sdim 267276479Sdim // Reset the operand, because it was clobbered by the RAUW above. 268296417Sdim SI->setOperand(1, &AI); 269226633Sdim } 270226633Sdim} 271226633Sdim 272226633Sdim/// lowerAcrossUnwindEdges - Find all variables which are alive across an unwind 273226633Sdim/// edge and spill them. 274234353Sdimvoid SjLjEHPrepare::lowerAcrossUnwindEdges(Function &F, 275261991Sdim ArrayRef<InvokeInst *> Invokes) { 276226633Sdim // Finally, scan the code looking for instructions with bad live ranges. 277261991Sdim for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) { 278261991Sdim for (BasicBlock::iterator II = BB->begin(), IIE = BB->end(); II != IIE; 279261991Sdim ++II) { 280226633Sdim // Ignore obvious cases we don't have to handle. In particular, most 281226633Sdim // instructions either have no uses or only have a single use inside the 282226633Sdim // current block. Ignore them quickly. 283296417Sdim Instruction *Inst = &*II; 284261991Sdim if (Inst->use_empty()) 285261991Sdim continue; 286226633Sdim if (Inst->hasOneUse() && 287276479Sdim cast<Instruction>(Inst->user_back())->getParent() == BB && 288276479Sdim !isa<PHINode>(Inst->user_back())) 289261991Sdim continue; 290226633Sdim 291226633Sdim // If this is an alloca in the entry block, it's not a real register 292226633Sdim // value. 293226633Sdim if (AllocaInst *AI = dyn_cast<AllocaInst>(Inst)) 294226633Sdim if (isa<ConstantInt>(AI->getArraySize()) && BB == F.begin()) 295226633Sdim continue; 296226633Sdim 297226633Sdim // Avoid iterator invalidation by copying users to a temporary vector. 298261991Sdim SmallVector<Instruction *, 16> Users; 299276479Sdim for (User *U : Inst->users()) { 300276479Sdim Instruction *UI = cast<Instruction>(U); 301276479Sdim if (UI->getParent() != BB || isa<PHINode>(UI)) 302276479Sdim Users.push_back(UI); 303226633Sdim } 304226633Sdim 305226633Sdim // Find all of the blocks that this value is live in. 306261991Sdim SmallPtrSet<BasicBlock *, 64> LiveBBs; 307226633Sdim LiveBBs.insert(Inst->getParent()); 308226633Sdim while (!Users.empty()) { 309226633Sdim Instruction *U = Users.back(); 310226633Sdim Users.pop_back(); 311226633Sdim 312226633Sdim if (!isa<PHINode>(U)) { 313226633Sdim MarkBlocksLiveIn(U->getParent(), LiveBBs); 314226633Sdim } else { 315226633Sdim // Uses for a PHI node occur in their predecessor block. 316226633Sdim PHINode *PN = cast<PHINode>(U); 317226633Sdim for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 318226633Sdim if (PN->getIncomingValue(i) == Inst) 319226633Sdim MarkBlocksLiveIn(PN->getIncomingBlock(i), LiveBBs); 320226633Sdim } 321226633Sdim } 322226633Sdim 323226633Sdim // Now that we know all of the blocks that this thing is live in, see if 324226633Sdim // it includes any of the unwind locations. 325226633Sdim bool NeedsSpill = false; 326226633Sdim for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { 327226633Sdim BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); 328226633Sdim if (UnwindBlock != BB && LiveBBs.count(UnwindBlock)) { 329234353Sdim DEBUG(dbgs() << "SJLJ Spill: " << *Inst << " around " 330261991Sdim << UnwindBlock->getName() << "\n"); 331226633Sdim NeedsSpill = true; 332234353Sdim break; 333226633Sdim } 334226633Sdim } 335226633Sdim 336226633Sdim // If we decided we need a spill, do it. 337226633Sdim // FIXME: Spilling this way is overkill, as it forces all uses of 338226633Sdim // the value to be reloaded from the stack slot, even those that aren't 339226633Sdim // in the unwind blocks. We should be more selective. 340226633Sdim if (NeedsSpill) { 341234353Sdim DemoteRegToStack(*Inst, true); 342226633Sdim ++NumSpilled; 343226633Sdim } 344226633Sdim } 345226633Sdim } 346234353Sdim 347234353Sdim // Go through the landing pads and remove any PHIs there. 348234353Sdim for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { 349234353Sdim BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); 350234353Sdim LandingPadInst *LPI = UnwindBlock->getLandingPadInst(); 351234353Sdim 352234353Sdim // Place PHIs into a set to avoid invalidating the iterator. 353261991Sdim SmallPtrSet<PHINode *, 8> PHIsToDemote; 354261991Sdim for (BasicBlock::iterator PN = UnwindBlock->begin(); isa<PHINode>(PN); ++PN) 355234353Sdim PHIsToDemote.insert(cast<PHINode>(PN)); 356261991Sdim if (PHIsToDemote.empty()) 357261991Sdim continue; 358234353Sdim 359234353Sdim // Demote the PHIs to the stack. 360280031Sdim for (PHINode *PN : PHIsToDemote) 361280031Sdim DemotePHIToStack(PN); 362234353Sdim 363234353Sdim // Move the landingpad instruction back to the top of the landing pad block. 364296417Sdim LPI->moveBefore(&UnwindBlock->front()); 365234353Sdim } 366226633Sdim} 367226633Sdim 368226633Sdim/// setupEntryBlockAndCallSites - Setup the entry block by creating and filling 369226633Sdim/// the function context and marking the call sites with the appropriate 370226633Sdim/// values. These values are used by the DWARF EH emitter. 371234353Sdimbool SjLjEHPrepare::setupEntryBlockAndCallSites(Function &F) { 372261991Sdim SmallVector<ReturnInst *, 16> Returns; 373261991Sdim SmallVector<InvokeInst *, 16> Invokes; 374261991Sdim SmallSetVector<LandingPadInst *, 16> LPads; 375226633Sdim 376226633Sdim // Look through the terminators of the basic blocks to find invokes. 377226633Sdim for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 378226633Sdim if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) { 379249423Sdim if (Function *Callee = II->getCalledFunction()) 380249423Sdim if (Callee->isIntrinsic() && 381249423Sdim Callee->getIntrinsicID() == Intrinsic::donothing) { 382249423Sdim // Remove the NOP invoke. 383249423Sdim BranchInst::Create(II->getNormalDest(), II); 384249423Sdim II->eraseFromParent(); 385249423Sdim continue; 386249423Sdim } 387249423Sdim 388226633Sdim Invokes.push_back(II); 389234353Sdim LPads.insert(II->getUnwindDest()->getLandingPadInst()); 390226633Sdim } else if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) { 391226633Sdim Returns.push_back(RI); 392226633Sdim } 393226633Sdim 394261991Sdim if (Invokes.empty()) 395261991Sdim return false; 396226633Sdim 397234353Sdim NumInvokes += Invokes.size(); 398234353Sdim 399226633Sdim lowerIncomingArguments(F); 400226633Sdim lowerAcrossUnwindEdges(F, Invokes); 401226633Sdim 402234353Sdim Value *FuncCtx = 403261991Sdim setupFunctionContext(F, makeArrayRef(LPads.begin(), LPads.end())); 404296417Sdim BasicBlock *EntryBB = &F.front(); 405243830Sdim IRBuilder<> Builder(EntryBB->getTerminator()); 406226633Sdim 407226633Sdim // Get a reference to the jump buffer. 408288943Sdim Value *JBufPtr = 409288943Sdim Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 5, "jbuf_gep"); 410226633Sdim 411226633Sdim // Save the frame pointer. 412288943Sdim Value *FramePtr = Builder.CreateConstGEP2_32(doubleUnderJBufTy, JBufPtr, 0, 0, 413288943Sdim "jbuf_fp_gep"); 414226633Sdim 415243830Sdim Value *Val = Builder.CreateCall(FrameAddrFn, Builder.getInt32(0), "fp"); 416243830Sdim Builder.CreateStore(Val, FramePtr, /*isVolatile=*/true); 417226633Sdim 418226633Sdim // Save the stack pointer. 419288943Sdim Value *StackPtr = Builder.CreateConstGEP2_32(doubleUnderJBufTy, JBufPtr, 0, 2, 420288943Sdim "jbuf_sp_gep"); 421226633Sdim 422288943Sdim Val = Builder.CreateCall(StackAddrFn, {}, "sp"); 423243830Sdim Builder.CreateStore(Val, StackPtr, /*isVolatile=*/true); 424226633Sdim 425296417Sdim // Call the setup_dispatch instrinsic. It fills in the rest of the jmpbuf. 426296417Sdim Builder.CreateCall(BuiltinSetupDispatchFn, {}); 427226633Sdim 428226633Sdim // Store a pointer to the function context so that the back-end will know 429226633Sdim // where to look for it. 430243830Sdim Value *FuncCtxArg = Builder.CreateBitCast(FuncCtx, Builder.getInt8PtrTy()); 431243830Sdim Builder.CreateCall(FuncCtxFn, FuncCtxArg); 432226633Sdim 433226633Sdim // At this point, we are all set up, update the invoke instructions to mark 434226633Sdim // their call_site values. 435226633Sdim for (unsigned I = 0, E = Invokes.size(); I != E; ++I) { 436234353Sdim insertCallSiteStore(Invokes[I], I + 1); 437226633Sdim 438226633Sdim ConstantInt *CallSiteNum = 439261991Sdim ConstantInt::get(Type::getInt32Ty(F.getContext()), I + 1); 440226633Sdim 441226633Sdim // Record the call site value for the back end so it stays associated with 442226633Sdim // the invoke. 443226633Sdim CallInst::Create(CallSiteFn, CallSiteNum, "", Invokes[I]); 444226633Sdim } 445226633Sdim 446226633Sdim // Mark call instructions that aren't nounwind as no-action (call_site == 447226633Sdim // -1). Skip the entry block, as prior to then, no function context has been 448226633Sdim // created for this function and any unexpected exceptions thrown will go 449226633Sdim // directly to the caller's context, which is what we want anyway, so no need 450226633Sdim // to do anything here. 451226633Sdim for (Function::iterator BB = F.begin(), E = F.end(); ++BB != E;) 452226633Sdim for (BasicBlock::iterator I = BB->begin(), end = BB->end(); I != end; ++I) 453226633Sdim if (CallInst *CI = dyn_cast<CallInst>(I)) { 454226633Sdim if (!CI->doesNotThrow()) 455234353Sdim insertCallSiteStore(CI, -1); 456226633Sdim } else if (ResumeInst *RI = dyn_cast<ResumeInst>(I)) { 457234353Sdim insertCallSiteStore(RI, -1); 458226633Sdim } 459226633Sdim 460226633Sdim // Register the function context and make sure it's known to not throw 461261991Sdim CallInst *Register = 462261991Sdim CallInst::Create(RegisterFn, FuncCtx, "", EntryBB->getTerminator()); 463226633Sdim Register->setDoesNotThrow(); 464226633Sdim 465234353Sdim // Following any allocas not in the entry block, update the saved SP in the 466234353Sdim // jmpbuf to the new value. 467234353Sdim for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { 468234353Sdim if (BB == F.begin()) 469234353Sdim continue; 470234353Sdim for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { 471234353Sdim if (CallInst *CI = dyn_cast<CallInst>(I)) { 472234353Sdim if (CI->getCalledFunction() != StackRestoreFn) 473234353Sdim continue; 474234353Sdim } else if (!isa<AllocaInst>(I)) { 475234353Sdim continue; 476234353Sdim } 477234353Sdim Instruction *StackAddr = CallInst::Create(StackAddrFn, "sp"); 478296417Sdim StackAddr->insertAfter(&*I); 479234353Sdim Instruction *StoreStackAddr = new StoreInst(StackAddr, StackPtr, true); 480234353Sdim StoreStackAddr->insertAfter(StackAddr); 481234353Sdim } 482234353Sdim } 483234353Sdim 484226633Sdim // Finally, for any returns from this function, if this function contains an 485226633Sdim // invoke, add a call to unregister the function context. 486226633Sdim for (unsigned I = 0, E = Returns.size(); I != E; ++I) 487226633Sdim CallInst::Create(UnregisterFn, FuncCtx, "", Returns[I]); 488226633Sdim 489226633Sdim return true; 490226633Sdim} 491226633Sdim 492234353Sdimbool SjLjEHPrepare::runOnFunction(Function &F) { 493234353Sdim bool Res = setupEntryBlockAndCallSites(F); 494198090Srdivacky return Res; 495198090Srdivacky} 496