SjLjEHPrepare.cpp revision 288943
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; 53261991Sdim Constant *BuiltinSetjmpFn; 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); 115198090Srdivacky BuiltinSetjmpFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_setjmp); 116198090Srdivacky LSDAAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_lsda); 117203954Srdivacky CallSiteFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_callsite); 118226633Sdim FuncCtxFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_functioncontext); 119276479Sdim PersonalityFn = nullptr; 120198090Srdivacky 121198090Srdivacky return true; 122198090Srdivacky} 123198090Srdivacky 124204792Srdivacky/// insertCallSiteStore - Insert a store of the call-site value to the 125204792Srdivacky/// function context 126234353Sdimvoid SjLjEHPrepare::insertCallSiteStore(Instruction *I, int Number) { 127234353Sdim IRBuilder<> Builder(I); 128234353Sdim 129234353Sdim // Get a reference to the call_site field. 130234353Sdim Type *Int32Ty = Type::getInt32Ty(I->getContext()); 131234353Sdim Value *Zero = ConstantInt::get(Int32Ty, 0); 132234353Sdim Value *One = ConstantInt::get(Int32Ty, 1); 133234353Sdim Value *Idxs[2] = { Zero, One }; 134288943Sdim Value *CallSite = 135288943Sdim Builder.CreateGEP(FunctionContextTy, FuncCtx, Idxs, "call_site"); 136234353Sdim 137234353Sdim // Insert a store of the call-site number 138261991Sdim ConstantInt *CallSiteNoC = 139261991Sdim ConstantInt::get(Type::getInt32Ty(I->getContext()), Number); 140261991Sdim Builder.CreateStore(CallSiteNoC, CallSite, true /*volatile*/); 141204792Srdivacky} 142204792Srdivacky 143198090Srdivacky/// MarkBlocksLiveIn - Insert BB and all of its predescessors into LiveBBs until 144198090Srdivacky/// we reach blocks we've already seen. 145234353Sdimstatic void MarkBlocksLiveIn(BasicBlock *BB, 146280031Sdim SmallPtrSetImpl<BasicBlock *> &LiveBBs) { 147280031Sdim if (!LiveBBs.insert(BB).second) 148261991Sdim return; // already been here. 149198090Srdivacky 150198090Srdivacky for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) 151198090Srdivacky MarkBlocksLiveIn(*PI, LiveBBs); 152198090Srdivacky} 153198090Srdivacky 154234353Sdim/// substituteLPadValues - Substitute the values returned by the landingpad 155234353Sdim/// instruction with those returned by the personality function. 156234353Sdimvoid SjLjEHPrepare::substituteLPadValues(LandingPadInst *LPI, Value *ExnVal, 157234353Sdim Value *SelVal) { 158276479Sdim SmallVector<Value *, 8> UseWorkList(LPI->user_begin(), LPI->user_end()); 159234353Sdim while (!UseWorkList.empty()) { 160234353Sdim Value *Val = UseWorkList.pop_back_val(); 161234353Sdim ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(Val); 162261991Sdim if (!EVI) 163261991Sdim continue; 164261991Sdim if (EVI->getNumIndices() != 1) 165261991Sdim continue; 166234353Sdim if (*EVI->idx_begin() == 0) 167234353Sdim EVI->replaceAllUsesWith(ExnVal); 168234353Sdim else if (*EVI->idx_begin() == 1) 169234353Sdim EVI->replaceAllUsesWith(SelVal); 170234353Sdim if (EVI->getNumUses() == 0) 171234353Sdim EVI->eraseFromParent(); 172198090Srdivacky } 173198090Srdivacky 174261991Sdim if (LPI->getNumUses() == 0) 175261991Sdim return; 176198090Srdivacky 177234353Sdim // There are still some uses of LPI. Construct an aggregate with the exception 178234353Sdim // values and replace the LPI with that aggregate. 179234353Sdim Type *LPadType = LPI->getType(); 180234353Sdim Value *LPadVal = UndefValue::get(LPadType); 181261991Sdim IRBuilder<> Builder( 182276479Sdim std::next(BasicBlock::iterator(cast<Instruction>(SelVal)))); 183234353Sdim LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0, "lpad.val"); 184234353Sdim LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1, "lpad.val"); 185198090Srdivacky 186234353Sdim LPI->replaceAllUsesWith(LPadVal); 187198090Srdivacky} 188198090Srdivacky 189226633Sdim/// setupFunctionContext - Allocate the function context on the stack and fill 190226633Sdim/// it with all of the data that we know at this point. 191261991SdimValue *SjLjEHPrepare::setupFunctionContext(Function &F, 192261991Sdim ArrayRef<LandingPadInst *> LPads) { 193226633Sdim BasicBlock *EntryBB = F.begin(); 194226633Sdim 195226633Sdim // Create an alloca for the incoming jump buffer ptr and the new jump buffer 196226633Sdim // that needs to be restored on all exits from the function. This is an alloca 197226633Sdim // because the value needs to be added to the global context list. 198288943Sdim auto &DL = F.getParent()->getDataLayout(); 199288943Sdim unsigned Align = DL.getPrefTypeAlignment(FunctionContextTy); 200276479Sdim FuncCtx = new AllocaInst(FunctionContextTy, nullptr, Align, "fn_context", 201261991Sdim EntryBB->begin()); 202226633Sdim 203226633Sdim // Fill in the function context structure. 204226633Sdim for (unsigned I = 0, E = LPads.size(); I != E; ++I) { 205226633Sdim LandingPadInst *LPI = LPads[I]; 206226633Sdim IRBuilder<> Builder(LPI->getParent()->getFirstInsertionPt()); 207226633Sdim 208234353Sdim // Reference the __data field. 209288943Sdim Value *FCData = 210288943Sdim Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 2, "__data"); 211234353Sdim 212234353Sdim // The exception values come back in context->__data[0]. 213288943Sdim Value *ExceptionAddr = Builder.CreateConstGEP2_32(doubleUnderDataTy, FCData, 214288943Sdim 0, 0, "exception_gep"); 215226633Sdim Value *ExnVal = Builder.CreateLoad(ExceptionAddr, true, "exn_val"); 216243830Sdim ExnVal = Builder.CreateIntToPtr(ExnVal, Builder.getInt8PtrTy()); 217234353Sdim 218288943Sdim Value *SelectorAddr = Builder.CreateConstGEP2_32(doubleUnderDataTy, FCData, 219288943Sdim 0, 1, "exn_selector_gep"); 220226633Sdim Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val"); 221226633Sdim 222234353Sdim substituteLPadValues(LPI, ExnVal, SelVal); 223226633Sdim } 224226633Sdim 225226633Sdim // Personality function 226243830Sdim IRBuilder<> Builder(EntryBB->getTerminator()); 227226633Sdim if (!PersonalityFn) 228288943Sdim PersonalityFn = F.getPersonalityFn(); 229288943Sdim Value *PersonalityFieldPtr = Builder.CreateConstGEP2_32( 230288943Sdim FunctionContextTy, FuncCtx, 0, 3, "pers_fn_gep"); 231261991Sdim Builder.CreateStore( 232261991Sdim Builder.CreateBitCast(PersonalityFn, Builder.getInt8PtrTy()), 233261991Sdim PersonalityFieldPtr, /*isVolatile=*/true); 234226633Sdim 235226633Sdim // LSDA address 236288943Sdim Value *LSDA = Builder.CreateCall(LSDAAddrFn, {}, "lsda_addr"); 237288943Sdim Value *LSDAFieldPtr = 238288943Sdim Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 4, "lsda_gep"); 239243830Sdim Builder.CreateStore(LSDA, LSDAFieldPtr, /*isVolatile=*/true); 240226633Sdim 241226633Sdim return FuncCtx; 242226633Sdim} 243226633Sdim 244226633Sdim/// lowerIncomingArguments - To avoid having to handle incoming arguments 245226633Sdim/// specially, we lower each arg to a copy instruction in the entry block. This 246226633Sdim/// ensures that the argument value itself cannot be live out of the entry 247226633Sdim/// block. 248234353Sdimvoid SjLjEHPrepare::lowerIncomingArguments(Function &F) { 249226633Sdim BasicBlock::iterator AfterAllocaInsPt = F.begin()->begin(); 250226633Sdim while (isa<AllocaInst>(AfterAllocaInsPt) && 251226633Sdim isa<ConstantInt>(cast<AllocaInst>(AfterAllocaInsPt)->getArraySize())) 252226633Sdim ++AfterAllocaInsPt; 253226633Sdim 254261991Sdim for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end(); AI != AE; 255261991Sdim ++AI) { 256226633Sdim Type *Ty = AI->getType(); 257226633Sdim 258276479Sdim // Use 'select i8 true, %arg, undef' to simulate a 'no-op' instruction. 259276479Sdim Value *TrueValue = ConstantInt::getTrue(F.getContext()); 260276479Sdim Value *UndefValue = UndefValue::get(Ty); 261276479Sdim Instruction *SI = SelectInst::Create(TrueValue, AI, UndefValue, 262276479Sdim AI->getName() + ".tmp", 263276479Sdim AfterAllocaInsPt); 264276479Sdim AI->replaceAllUsesWith(SI); 265226633Sdim 266276479Sdim // Reset the operand, because it was clobbered by the RAUW above. 267276479Sdim SI->setOperand(1, AI); 268226633Sdim } 269226633Sdim} 270226633Sdim 271226633Sdim/// lowerAcrossUnwindEdges - Find all variables which are alive across an unwind 272226633Sdim/// edge and spill them. 273234353Sdimvoid SjLjEHPrepare::lowerAcrossUnwindEdges(Function &F, 274261991Sdim ArrayRef<InvokeInst *> Invokes) { 275226633Sdim // Finally, scan the code looking for instructions with bad live ranges. 276261991Sdim for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) { 277261991Sdim for (BasicBlock::iterator II = BB->begin(), IIE = BB->end(); II != IIE; 278261991Sdim ++II) { 279226633Sdim // Ignore obvious cases we don't have to handle. In particular, most 280226633Sdim // instructions either have no uses or only have a single use inside the 281226633Sdim // current block. Ignore them quickly. 282226633Sdim Instruction *Inst = II; 283261991Sdim if (Inst->use_empty()) 284261991Sdim continue; 285226633Sdim if (Inst->hasOneUse() && 286276479Sdim cast<Instruction>(Inst->user_back())->getParent() == BB && 287276479Sdim !isa<PHINode>(Inst->user_back())) 288261991Sdim continue; 289226633Sdim 290226633Sdim // If this is an alloca in the entry block, it's not a real register 291226633Sdim // value. 292226633Sdim if (AllocaInst *AI = dyn_cast<AllocaInst>(Inst)) 293226633Sdim if (isa<ConstantInt>(AI->getArraySize()) && BB == F.begin()) 294226633Sdim continue; 295226633Sdim 296226633Sdim // Avoid iterator invalidation by copying users to a temporary vector. 297261991Sdim SmallVector<Instruction *, 16> Users; 298276479Sdim for (User *U : Inst->users()) { 299276479Sdim Instruction *UI = cast<Instruction>(U); 300276479Sdim if (UI->getParent() != BB || isa<PHINode>(UI)) 301276479Sdim Users.push_back(UI); 302226633Sdim } 303226633Sdim 304226633Sdim // Find all of the blocks that this value is live in. 305261991Sdim SmallPtrSet<BasicBlock *, 64> LiveBBs; 306226633Sdim LiveBBs.insert(Inst->getParent()); 307226633Sdim while (!Users.empty()) { 308226633Sdim Instruction *U = Users.back(); 309226633Sdim Users.pop_back(); 310226633Sdim 311226633Sdim if (!isa<PHINode>(U)) { 312226633Sdim MarkBlocksLiveIn(U->getParent(), LiveBBs); 313226633Sdim } else { 314226633Sdim // Uses for a PHI node occur in their predecessor block. 315226633Sdim PHINode *PN = cast<PHINode>(U); 316226633Sdim for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 317226633Sdim if (PN->getIncomingValue(i) == Inst) 318226633Sdim MarkBlocksLiveIn(PN->getIncomingBlock(i), LiveBBs); 319226633Sdim } 320226633Sdim } 321226633Sdim 322226633Sdim // Now that we know all of the blocks that this thing is live in, see if 323226633Sdim // it includes any of the unwind locations. 324226633Sdim bool NeedsSpill = false; 325226633Sdim for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { 326226633Sdim BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); 327226633Sdim if (UnwindBlock != BB && LiveBBs.count(UnwindBlock)) { 328234353Sdim DEBUG(dbgs() << "SJLJ Spill: " << *Inst << " around " 329261991Sdim << UnwindBlock->getName() << "\n"); 330226633Sdim NeedsSpill = true; 331234353Sdim break; 332226633Sdim } 333226633Sdim } 334226633Sdim 335226633Sdim // If we decided we need a spill, do it. 336226633Sdim // FIXME: Spilling this way is overkill, as it forces all uses of 337226633Sdim // the value to be reloaded from the stack slot, even those that aren't 338226633Sdim // in the unwind blocks. We should be more selective. 339226633Sdim if (NeedsSpill) { 340234353Sdim DemoteRegToStack(*Inst, true); 341226633Sdim ++NumSpilled; 342226633Sdim } 343226633Sdim } 344226633Sdim } 345234353Sdim 346234353Sdim // Go through the landing pads and remove any PHIs there. 347234353Sdim for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { 348234353Sdim BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); 349234353Sdim LandingPadInst *LPI = UnwindBlock->getLandingPadInst(); 350234353Sdim 351234353Sdim // Place PHIs into a set to avoid invalidating the iterator. 352261991Sdim SmallPtrSet<PHINode *, 8> PHIsToDemote; 353261991Sdim for (BasicBlock::iterator PN = UnwindBlock->begin(); isa<PHINode>(PN); ++PN) 354234353Sdim PHIsToDemote.insert(cast<PHINode>(PN)); 355261991Sdim if (PHIsToDemote.empty()) 356261991Sdim continue; 357234353Sdim 358234353Sdim // Demote the PHIs to the stack. 359280031Sdim for (PHINode *PN : PHIsToDemote) 360280031Sdim DemotePHIToStack(PN); 361234353Sdim 362234353Sdim // Move the landingpad instruction back to the top of the landing pad block. 363234353Sdim LPI->moveBefore(UnwindBlock->begin()); 364234353Sdim } 365226633Sdim} 366226633Sdim 367226633Sdim/// setupEntryBlockAndCallSites - Setup the entry block by creating and filling 368226633Sdim/// the function context and marking the call sites with the appropriate 369226633Sdim/// values. These values are used by the DWARF EH emitter. 370234353Sdimbool SjLjEHPrepare::setupEntryBlockAndCallSites(Function &F) { 371261991Sdim SmallVector<ReturnInst *, 16> Returns; 372261991Sdim SmallVector<InvokeInst *, 16> Invokes; 373261991Sdim SmallSetVector<LandingPadInst *, 16> LPads; 374226633Sdim 375226633Sdim // Look through the terminators of the basic blocks to find invokes. 376226633Sdim for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 377226633Sdim if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) { 378249423Sdim if (Function *Callee = II->getCalledFunction()) 379249423Sdim if (Callee->isIntrinsic() && 380249423Sdim Callee->getIntrinsicID() == Intrinsic::donothing) { 381249423Sdim // Remove the NOP invoke. 382249423Sdim BranchInst::Create(II->getNormalDest(), II); 383249423Sdim II->eraseFromParent(); 384249423Sdim continue; 385249423Sdim } 386249423Sdim 387226633Sdim Invokes.push_back(II); 388234353Sdim LPads.insert(II->getUnwindDest()->getLandingPadInst()); 389226633Sdim } else if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) { 390226633Sdim Returns.push_back(RI); 391226633Sdim } 392226633Sdim 393261991Sdim if (Invokes.empty()) 394261991Sdim return false; 395226633Sdim 396234353Sdim NumInvokes += Invokes.size(); 397234353Sdim 398226633Sdim lowerIncomingArguments(F); 399226633Sdim lowerAcrossUnwindEdges(F, Invokes); 400226633Sdim 401234353Sdim Value *FuncCtx = 402261991Sdim setupFunctionContext(F, makeArrayRef(LPads.begin(), LPads.end())); 403226633Sdim BasicBlock *EntryBB = F.begin(); 404243830Sdim IRBuilder<> Builder(EntryBB->getTerminator()); 405226633Sdim 406226633Sdim // Get a reference to the jump buffer. 407288943Sdim Value *JBufPtr = 408288943Sdim Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 5, "jbuf_gep"); 409226633Sdim 410226633Sdim // Save the frame pointer. 411288943Sdim Value *FramePtr = Builder.CreateConstGEP2_32(doubleUnderJBufTy, JBufPtr, 0, 0, 412288943Sdim "jbuf_fp_gep"); 413226633Sdim 414243830Sdim Value *Val = Builder.CreateCall(FrameAddrFn, Builder.getInt32(0), "fp"); 415243830Sdim Builder.CreateStore(Val, FramePtr, /*isVolatile=*/true); 416226633Sdim 417226633Sdim // Save the stack pointer. 418288943Sdim Value *StackPtr = Builder.CreateConstGEP2_32(doubleUnderJBufTy, JBufPtr, 0, 2, 419288943Sdim "jbuf_sp_gep"); 420226633Sdim 421288943Sdim Val = Builder.CreateCall(StackAddrFn, {}, "sp"); 422243830Sdim Builder.CreateStore(Val, StackPtr, /*isVolatile=*/true); 423226633Sdim 424226633Sdim // Call the setjmp instrinsic. It fills in the rest of the jmpbuf. 425243830Sdim Value *SetjmpArg = Builder.CreateBitCast(JBufPtr, Builder.getInt8PtrTy()); 426243830Sdim Builder.CreateCall(BuiltinSetjmpFn, SetjmpArg); 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"); 478234353Sdim 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