1eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendling//===- SjLjEHPrepare.cpp - Eliminate Invoke & Unwind instructions ---------===// 28b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach// 38b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach// The LLVM Compiler Infrastructure 48b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach// 58b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach// This file is distributed under the University of Illinois Open Source 68b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach// License. See LICENSE.TXT for details. 78b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach// 88b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach//===----------------------------------------------------------------------===// 98b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach// 108b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach// This transformation is designed for use by code generators which use SjLj 118b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach// based exception handling. 128b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach// 138b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach//===----------------------------------------------------------------------===// 148b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach 158b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach#define DEBUG_TYPE "sjljehprepare" 168b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach#include "llvm/Constants.h" 178b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach#include "llvm/DerivedTypes.h" 1806cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/IRBuilder.h" 198b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach#include "llvm/Instructions.h" 208b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach#include "llvm/Intrinsics.h" 218b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach#include "llvm/LLVMContext.h" 228b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach#include "llvm/Module.h" 238b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach#include "llvm/Pass.h" 24aef508dfc1d844bb3a4f7606f54bf4c616c10effBill Wendling#include "llvm/ADT/DenseMap.h" 25f1b41dd38d2b2713e3870f384525b020bbac05f6Bob Wilson#include "llvm/ADT/SetVector.h" 26d2dae0cfa00ca3c5164b2543ed712ace6c08386bBill Wendling#include "llvm/ADT/SmallPtrSet.h" 27d36b3e36811e8b50476076ee4986068481916f66Bill Wendling#include "llvm/ADT/SmallVector.h" 28d36b3e36811e8b50476076ee4986068481916f66Bill Wendling#include "llvm/ADT/Statistic.h" 2906cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/CodeGen/Passes.h" 3006cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/CommandLine.h" 3106cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/Debug.h" 3206cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/raw_ostream.h" 3306cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Target/TargetData.h" 3406cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Target/TargetLowering.h" 3506cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Transforms/Scalar.h" 3606cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Transforms/Utils/BasicBlockUtils.h" 3706cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Transforms/Utils/Local.h" 38f788854d20b12c60fd8b43c587adb3227b6b1bffBenjamin Kramer#include <set> 398b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbachusing namespace llvm; 408b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach 418b818d7e98309125c6058c4ea72a7dc73b031db2Jim GrosbachSTATISTIC(NumInvokes, "Number of invokes replaced"); 428b818d7e98309125c6058c4ea72a7dc73b031db2Jim GrosbachSTATISTIC(NumSpilled, "Number of registers live across unwind edges"); 438b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach 448b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbachnamespace { 45eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendling class SjLjEHPrepare : public FunctionPass { 468b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach const TargetLowering *TLI; 47db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *FunctionContextTy; 488b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach Constant *RegisterFn; 498b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach Constant *UnregisterFn; 508b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach Constant *BuiltinSetjmpFn; 518b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach Constant *FrameAddrFn; 520798eddd07b8dc827a4e6e9028c4c3a8d9444286Jim Grosbach Constant *StackAddrFn; 5320c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson Constant *StackRestoreFn; 548b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach Constant *LSDAAddrFn; 558b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach Value *PersonalityFn; 56ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach Constant *CallSiteFn; 57cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling Constant *FuncCtxFn; 584cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling AllocaInst *FuncCtx; 598b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach public: 608b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach static char ID; // Pass identification, replacement for typeid 61eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendling explicit SjLjEHPrepare(const TargetLowering *tli = NULL) 62bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier : FunctionPass(ID), TLI(tli) { } 638b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach bool doInitialization(Module &M); 648b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach bool runOnFunction(Function &F); 658b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach 66bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier virtual void getAnalysisUsage(AnalysisUsage &AU) const {} 678b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach const char *getPassName() const { 688b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach return "SJLJ Exception Handling preparation"; 698b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach } 708b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach 718b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach private: 722b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling bool setupEntryBlockAndCallSites(Function &F); 7369fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling void substituteLPadValues(LandingPadInst *LPI, Value *ExnVal, 7469fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling Value *SelVal); 75631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling Value *setupFunctionContext(Function &F, ArrayRef<LandingPadInst*> LPads); 76d5d170097241534401bbbebb4be59451d5c312caBill Wendling void lowerIncomingArguments(Function &F); 77d5d170097241534401bbbebb4be59451d5c312caBill Wendling void lowerAcrossUnwindEdges(Function &F, ArrayRef<InvokeInst*> Invokes); 784cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling void insertCallSiteStore(Instruction *I, int Number); 798b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach }; 808b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach} // end anonymous namespace 818b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach 82eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendlingchar SjLjEHPrepare::ID = 0; 838b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach 84eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendling// Public Interface To the SjLjEHPrepare pass. 85eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill WendlingFunctionPass *llvm::createSjLjEHPreparePass(const TargetLowering *TLI) { 86eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendling return new SjLjEHPrepare(TLI); 878b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach} 88a235d13217ff14621a88f3ea96a8a3b980c56d02Jim Grosbach// doInitialization - Set up decalarations and types needed to process 89a235d13217ff14621a88f3ea96a8a3b980c56d02Jim Grosbach// exceptions. 90eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendlingbool SjLjEHPrepare::doInitialization(Module &M) { 918b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach // Build the function context structure. 928b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach // builtin_setjmp uses a five word jbuf 935fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *VoidPtrTy = Type::getInt8PtrTy(M.getContext()); 945fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *Int32Ty = Type::getInt32Ty(M.getContext()); 958b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach FunctionContextTy = 96b2318662b6d2e6d9ea9917fd280dde0ba9a938adChris Lattner StructType::get(VoidPtrTy, // __prev 978b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach Int32Ty, // call_site 988b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach ArrayType::get(Int32Ty, 4), // __data 998b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach VoidPtrTy, // __personality 1008b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach VoidPtrTy, // __lsda 1018b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach ArrayType::get(VoidPtrTy, 5), // __jbuf 1028b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach NULL); 1038b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach RegisterFn = M.getOrInsertFunction("_Unwind_SjLj_Register", 1048b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach Type::getVoidTy(M.getContext()), 1058b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach PointerType::getUnqual(FunctionContextTy), 1068b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach (Type *)0); 1078b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach UnregisterFn = 1088b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach M.getOrInsertFunction("_Unwind_SjLj_Unregister", 1098b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach Type::getVoidTy(M.getContext()), 1108b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach PointerType::getUnqual(FunctionContextTy), 1118b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach (Type *)0); 1128b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach FrameAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::frameaddress); 1130798eddd07b8dc827a4e6e9028c4c3a8d9444286Jim Grosbach StackAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::stacksave); 11420c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson StackRestoreFn = Intrinsic::getDeclaration(&M, Intrinsic::stackrestore); 1158b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach BuiltinSetjmpFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_setjmp); 1168b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach LSDAAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_lsda); 117ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach CallSiteFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_callsite); 118cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling FuncCtxFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_functioncontext); 119a235d13217ff14621a88f3ea96a8a3b980c56d02Jim Grosbach PersonalityFn = 0; 1208b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach 1218b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach return true; 1228b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach} 1238b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach 124b58a59b3c1563ab5bd7225748e32933bf6d76c03Jim Grosbach/// insertCallSiteStore - Insert a store of the call-site value to the 125b58a59b3c1563ab5bd7225748e32933bf6d76c03Jim Grosbach/// function context 126eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendlingvoid SjLjEHPrepare::insertCallSiteStore(Instruction *I, int Number) { 1274cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling IRBuilder<> Builder(I); 1284cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling 1294cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling // Get a reference to the call_site field. 1304cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Type *Int32Ty = Type::getInt32Ty(I->getContext()); 1314cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Value *Zero = ConstantInt::get(Int32Ty, 0); 1324cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Value *One = ConstantInt::get(Int32Ty, 1); 1334cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Value *Idxs[2] = { Zero, One }; 1344cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Value *CallSite = Builder.CreateGEP(FuncCtx, Idxs, "call_site"); 1354cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling 1364cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling // Insert a store of the call-site number 137b58a59b3c1563ab5bd7225748e32933bf6d76c03Jim Grosbach ConstantInt *CallSiteNoC = ConstantInt::get(Type::getInt32Ty(I->getContext()), 138b58a59b3c1563ab5bd7225748e32933bf6d76c03Jim Grosbach Number); 1394cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Builder.CreateStore(CallSiteNoC, CallSite, true/*volatile*/); 140b58a59b3c1563ab5bd7225748e32933bf6d76c03Jim Grosbach} 141b58a59b3c1563ab5bd7225748e32933bf6d76c03Jim Grosbach 142bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier/// MarkBlocksLiveIn - Insert BB and all of its predescessors into LiveBBs until 1438b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach/// we reach blocks we've already seen. 144bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosierstatic void MarkBlocksLiveIn(BasicBlock *BB, 145bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier SmallPtrSet<BasicBlock*, 64> &LiveBBs) { 146bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier if (!LiveBBs.insert(BB)) return; // already been here. 1478b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach 148bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) 149bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier MarkBlocksLiveIn(*PI, LiveBBs); 1508b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach} 1518b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach 15269fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling/// substituteLPadValues - Substitute the values returned by the landingpad 15369fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling/// instruction with those returned by the personality function. 154eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendlingvoid SjLjEHPrepare::substituteLPadValues(LandingPadInst *LPI, Value *ExnVal, 155eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendling Value *SelVal) { 15669fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling SmallVector<Value*, 8> UseWorkList(LPI->use_begin(), LPI->use_end()); 15769fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling while (!UseWorkList.empty()) { 15869fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling Value *Val = UseWorkList.pop_back_val(); 15969fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(Val); 16069fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling if (!EVI) continue; 16169fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling if (EVI->getNumIndices() != 1) continue; 16269fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling if (*EVI->idx_begin() == 0) 16369fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling EVI->replaceAllUsesWith(ExnVal); 16469fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling else if (*EVI->idx_begin() == 1) 16569fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling EVI->replaceAllUsesWith(SelVal); 16669fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling if (EVI->getNumUses() == 0) 16769fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling EVI->eraseFromParent(); 16869fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling } 16969fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling 17069fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling if (LPI->getNumUses() == 0) return; 17169fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling 17269fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling // There are still some uses of LPI. Construct an aggregate with the exception 17369fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling // values and replace the LPI with that aggregate. 17469fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling Type *LPadType = LPI->getType(); 17569fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling Value *LPadVal = UndefValue::get(LPadType); 17669fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling IRBuilder<> 17769fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling Builder(llvm::next(BasicBlock::iterator(cast<Instruction>(SelVal)))); 17869fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0, "lpad.val"); 17969fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1, "lpad.val"); 18069fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling 18169fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling LPI->replaceAllUsesWith(LPadVal); 18269fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling} 18369fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling 1842b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling/// setupFunctionContext - Allocate the function context on the stack and fill 1852b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling/// it with all of the data that we know at this point. 186eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill WendlingValue *SjLjEHPrepare:: 187cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill WendlingsetupFunctionContext(Function &F, ArrayRef<LandingPadInst*> LPads) { 1882b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling BasicBlock *EntryBB = F.begin(); 1892b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 1902b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // Create an alloca for the incoming jump buffer ptr and the new jump buffer 1912b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // that needs to be restored on all exits from the function. This is an alloca 1922b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // because the value needs to be added to the global context list. 1932b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling unsigned Align = 1942b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling TLI->getTargetData()->getPrefTypeAlignment(FunctionContextTy); 1954cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling FuncCtx = 1962b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling new AllocaInst(FunctionContextTy, 0, Align, "fn_context", EntryBB->begin()); 1972b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 1982b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // Fill in the function context structure. 1992b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling for (unsigned I = 0, E = LPads.size(); I != E; ++I) { 2002b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling LandingPadInst *LPI = LPads[I]; 2012b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling IRBuilder<> Builder(LPI->getParent()->getFirstInsertionPt()); 2022b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 2034cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling // Reference the __data field. 204f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Value *FCData = Builder.CreateConstGEP2_32(FuncCtx, 0, 2, "__data"); 2054cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling 2064cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling // The exception values come back in context->__data[0]. 207f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Value *ExceptionAddr = Builder.CreateConstGEP2_32(FCData, 0, 0, 208f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer "exception_gep"); 2092b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling Value *ExnVal = Builder.CreateLoad(ExceptionAddr, true, "exn_val"); 210f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer ExnVal = Builder.CreateIntToPtr(ExnVal, Builder.getInt8PtrTy()); 2114cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling 212f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Value *SelectorAddr = Builder.CreateConstGEP2_32(FCData, 0, 1, 213f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer "exn_selector_gep"); 2142b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val"); 2152b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 21669fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling substituteLPadValues(LPI, ExnVal, SelVal); 2172b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling } 2182b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 2192b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // Personality function 220f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer IRBuilder<> Builder(EntryBB->getTerminator()); 2212b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling if (!PersonalityFn) 2222b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling PersonalityFn = LPads[0]->getPersonalityFn(); 223f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Value *PersonalityFieldPtr = Builder.CreateConstGEP2_32(FuncCtx, 0, 3, 224f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer "pers_fn_gep"); 225f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Builder.CreateStore(PersonalityFn, PersonalityFieldPtr, /*isVolatile=*/true); 2262b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 2272b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // LSDA address 228f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Value *LSDA = Builder.CreateCall(LSDAAddrFn, "lsda_addr"); 229f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Value *LSDAFieldPtr = Builder.CreateConstGEP2_32(FuncCtx, 0, 4, "lsda_gep"); 230f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Builder.CreateStore(LSDA, LSDAFieldPtr, /*isVolatile=*/true); 2312b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 232631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling return FuncCtx; 2332b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling} 2342b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 235d5d170097241534401bbbebb4be59451d5c312caBill Wendling/// lowerIncomingArguments - To avoid having to handle incoming arguments 236d5d170097241534401bbbebb4be59451d5c312caBill Wendling/// specially, we lower each arg to a copy instruction in the entry block. This 237d5d170097241534401bbbebb4be59451d5c312caBill Wendling/// ensures that the argument value itself cannot be live out of the entry 238d5d170097241534401bbbebb4be59451d5c312caBill Wendling/// block. 239eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendlingvoid SjLjEHPrepare::lowerIncomingArguments(Function &F) { 240d5d170097241534401bbbebb4be59451d5c312caBill Wendling BasicBlock::iterator AfterAllocaInsPt = F.begin()->begin(); 241d5d170097241534401bbbebb4be59451d5c312caBill Wendling while (isa<AllocaInst>(AfterAllocaInsPt) && 242d5d170097241534401bbbebb4be59451d5c312caBill Wendling isa<ConstantInt>(cast<AllocaInst>(AfterAllocaInsPt)->getArraySize())) 243d5d170097241534401bbbebb4be59451d5c312caBill Wendling ++AfterAllocaInsPt; 244d5d170097241534401bbbebb4be59451d5c312caBill Wendling 245d5d170097241534401bbbebb4be59451d5c312caBill Wendling for (Function::arg_iterator 246d5d170097241534401bbbebb4be59451d5c312caBill Wendling AI = F.arg_begin(), AE = F.arg_end(); AI != AE; ++AI) { 247d5d170097241534401bbbebb4be59451d5c312caBill Wendling Type *Ty = AI->getType(); 248d5d170097241534401bbbebb4be59451d5c312caBill Wendling 249d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Aggregate types can't be cast, but are legal argument types, so we have 250d5d170097241534401bbbebb4be59451d5c312caBill Wendling // to handle them differently. We use an extract/insert pair as a 251d5d170097241534401bbbebb4be59451d5c312caBill Wendling // lightweight method to achieve the same goal. 252d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) { 253d5d170097241534401bbbebb4be59451d5c312caBill Wendling Instruction *EI = ExtractValueInst::Create(AI, 0, "", AfterAllocaInsPt); 254d5d170097241534401bbbebb4be59451d5c312caBill Wendling Instruction *NI = InsertValueInst::Create(AI, EI, 0); 255d5d170097241534401bbbebb4be59451d5c312caBill Wendling NI->insertAfter(EI); 256d5d170097241534401bbbebb4be59451d5c312caBill Wendling AI->replaceAllUsesWith(NI); 257d5d170097241534401bbbebb4be59451d5c312caBill Wendling 258d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Set the operand of the instructions back to the AllocaInst. 259d5d170097241534401bbbebb4be59451d5c312caBill Wendling EI->setOperand(0, AI); 260d5d170097241534401bbbebb4be59451d5c312caBill Wendling NI->setOperand(0, AI); 261d5d170097241534401bbbebb4be59451d5c312caBill Wendling } else { 262d5d170097241534401bbbebb4be59451d5c312caBill Wendling // This is always a no-op cast because we're casting AI to AI->getType() 263d5d170097241534401bbbebb4be59451d5c312caBill Wendling // so src and destination types are identical. BitCast is the only 264d5d170097241534401bbbebb4be59451d5c312caBill Wendling // possibility. 265d5d170097241534401bbbebb4be59451d5c312caBill Wendling CastInst *NC = 266d5d170097241534401bbbebb4be59451d5c312caBill Wendling new BitCastInst(AI, AI->getType(), AI->getName() + ".tmp", 267d5d170097241534401bbbebb4be59451d5c312caBill Wendling AfterAllocaInsPt); 268d5d170097241534401bbbebb4be59451d5c312caBill Wendling AI->replaceAllUsesWith(NC); 269d5d170097241534401bbbebb4be59451d5c312caBill Wendling 270d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Set the operand of the cast instruction back to the AllocaInst. 271d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Normally it's forbidden to replace a CastInst's operand because it 272d5d170097241534401bbbebb4be59451d5c312caBill Wendling // could cause the opcode to reflect an illegal conversion. However, we're 273d5d170097241534401bbbebb4be59451d5c312caBill Wendling // replacing it here with the same value it was constructed with. We do 274d5d170097241534401bbbebb4be59451d5c312caBill Wendling // this because the above replaceAllUsesWith() clobbered the operand, but 275d5d170097241534401bbbebb4be59451d5c312caBill Wendling // we want this one to remain. 276d5d170097241534401bbbebb4be59451d5c312caBill Wendling NC->setOperand(0, AI); 277d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 278d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 279d5d170097241534401bbbebb4be59451d5c312caBill Wendling} 280d5d170097241534401bbbebb4be59451d5c312caBill Wendling 281d5d170097241534401bbbebb4be59451d5c312caBill Wendling/// lowerAcrossUnwindEdges - Find all variables which are alive across an unwind 282d5d170097241534401bbbebb4be59451d5c312caBill Wendling/// edge and spill them. 283eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendlingvoid SjLjEHPrepare::lowerAcrossUnwindEdges(Function &F, 284eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendling ArrayRef<InvokeInst*> Invokes) { 285d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Finally, scan the code looking for instructions with bad live ranges. 286d5d170097241534401bbbebb4be59451d5c312caBill Wendling for (Function::iterator 287d5d170097241534401bbbebb4be59451d5c312caBill Wendling BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) { 288d5d170097241534401bbbebb4be59451d5c312caBill Wendling for (BasicBlock::iterator 289d5d170097241534401bbbebb4be59451d5c312caBill Wendling II = BB->begin(), IIE = BB->end(); II != IIE; ++II) { 290d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Ignore obvious cases we don't have to handle. In particular, most 291d5d170097241534401bbbebb4be59451d5c312caBill Wendling // instructions either have no uses or only have a single use inside the 292d5d170097241534401bbbebb4be59451d5c312caBill Wendling // current block. Ignore them quickly. 293d5d170097241534401bbbebb4be59451d5c312caBill Wendling Instruction *Inst = II; 294d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (Inst->use_empty()) continue; 295d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (Inst->hasOneUse() && 296d5d170097241534401bbbebb4be59451d5c312caBill Wendling cast<Instruction>(Inst->use_back())->getParent() == BB && 297d5d170097241534401bbbebb4be59451d5c312caBill Wendling !isa<PHINode>(Inst->use_back())) continue; 298d5d170097241534401bbbebb4be59451d5c312caBill Wendling 299d5d170097241534401bbbebb4be59451d5c312caBill Wendling // If this is an alloca in the entry block, it's not a real register 300d5d170097241534401bbbebb4be59451d5c312caBill Wendling // value. 301d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (AllocaInst *AI = dyn_cast<AllocaInst>(Inst)) 302d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (isa<ConstantInt>(AI->getArraySize()) && BB == F.begin()) 303d5d170097241534401bbbebb4be59451d5c312caBill Wendling continue; 304d5d170097241534401bbbebb4be59451d5c312caBill Wendling 305d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Avoid iterator invalidation by copying users to a temporary vector. 306d5d170097241534401bbbebb4be59451d5c312caBill Wendling SmallVector<Instruction*, 16> Users; 307d5d170097241534401bbbebb4be59451d5c312caBill Wendling for (Value::use_iterator 308d5d170097241534401bbbebb4be59451d5c312caBill Wendling UI = Inst->use_begin(), E = Inst->use_end(); UI != E; ++UI) { 309d5d170097241534401bbbebb4be59451d5c312caBill Wendling Instruction *User = cast<Instruction>(*UI); 310d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (User->getParent() != BB || isa<PHINode>(User)) 311d5d170097241534401bbbebb4be59451d5c312caBill Wendling Users.push_back(User); 312d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 313d5d170097241534401bbbebb4be59451d5c312caBill Wendling 314d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Find all of the blocks that this value is live in. 315bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier SmallPtrSet<BasicBlock*, 64> LiveBBs; 316bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier LiveBBs.insert(Inst->getParent()); 317d5d170097241534401bbbebb4be59451d5c312caBill Wendling while (!Users.empty()) { 318bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier Instruction *U = Users.back(); 319bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier Users.pop_back(); 320d5d170097241534401bbbebb4be59451d5c312caBill Wendling 321bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier if (!isa<PHINode>(U)) { 322bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier MarkBlocksLiveIn(U->getParent(), LiveBBs); 323bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier } else { 324d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Uses for a PHI node occur in their predecessor block. 325bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier PHINode *PN = cast<PHINode>(U); 326d5d170097241534401bbbebb4be59451d5c312caBill Wendling for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 327d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (PN->getIncomingValue(i) == Inst) 328bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier MarkBlocksLiveIn(PN->getIncomingBlock(i), LiveBBs); 329d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 330d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 331d5d170097241534401bbbebb4be59451d5c312caBill Wendling 332bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier // Now that we know all of the blocks that this thing is live in, see if 333bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier // it includes any of the unwind locations. 334bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier bool NeedsSpill = false; 335bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { 336bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); 337bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier if (UnwindBlock != BB && LiveBBs.count(UnwindBlock)) { 338bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier DEBUG(dbgs() << "SJLJ Spill: " << *Inst << " around " 339bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier << UnwindBlock->getName() << "\n"); 340bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier NeedsSpill = true; 341bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier break; 342d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 343d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 344d5d170097241534401bbbebb4be59451d5c312caBill Wendling 345bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier // If we decided we need a spill, do it. 346bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier // FIXME: Spilling this way is overkill, as it forces all uses of 347bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier // the value to be reloaded from the stack slot, even those that aren't 348bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier // in the unwind blocks. We should be more selective. 349bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier if (NeedsSpill) { 350bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier DemoteRegToStack(*Inst, true); 351bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier ++NumSpilled; 3529eb5f170a219decc4ee07b57b0403d3836a8d946Bill Wendling } 353d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 354d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 3550ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling 3560ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling // Go through the landing pads and remove any PHIs there. 3570ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { 3580ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); 3590ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling LandingPadInst *LPI = UnwindBlock->getLandingPadInst(); 3600ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling 3610ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling // Place PHIs into a set to avoid invalidating the iterator. 3620ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling SmallPtrSet<PHINode*, 8> PHIsToDemote; 3630ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling for (BasicBlock::iterator 3640ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling PN = UnwindBlock->begin(); isa<PHINode>(PN); ++PN) 3650ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling PHIsToDemote.insert(cast<PHINode>(PN)); 3660ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling if (PHIsToDemote.empty()) continue; 3670ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling 3680ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling // Demote the PHIs to the stack. 3690ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling for (SmallPtrSet<PHINode*, 8>::iterator 3700ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling I = PHIsToDemote.begin(), E = PHIsToDemote.end(); I != E; ++I) 3710ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling DemotePHIToStack(*I); 3720ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling 3730ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling // Move the landingpad instruction back to the top of the landing pad block. 3740ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling LPI->moveBefore(UnwindBlock->begin()); 3750ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling } 376d5d170097241534401bbbebb4be59451d5c312caBill Wendling} 377d5d170097241534401bbbebb4be59451d5c312caBill Wendling 3782b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling/// setupEntryBlockAndCallSites - Setup the entry block by creating and filling 3792b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling/// the function context and marking the call sites with the appropriate 3802b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling/// values. These values are used by the DWARF EH emitter. 381eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendlingbool SjLjEHPrepare::setupEntryBlockAndCallSites(Function &F) { 382cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling SmallVector<ReturnInst*, 16> Returns; 3832b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling SmallVector<InvokeInst*, 16> Invokes; 384f1b41dd38d2b2713e3870f384525b020bbac05f6Bob Wilson SmallSetVector<LandingPadInst*, 16> LPads; 3852b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 3862b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // Look through the terminators of the basic blocks to find invokes. 3872b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 3882b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) { 3892b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling Invokes.push_back(II); 390f1b41dd38d2b2713e3870f384525b020bbac05f6Bob Wilson LPads.insert(II->getUnwindDest()->getLandingPadInst()); 391cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling } else if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) { 392cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling Returns.push_back(RI); 3932b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling } 3942b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 3952b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling if (Invokes.empty()) return false; 3962b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 397d2dae0cfa00ca3c5164b2543ed712ace6c08386bBill Wendling NumInvokes += Invokes.size(); 398d2dae0cfa00ca3c5164b2543ed712ace6c08386bBill Wendling 399d5d170097241534401bbbebb4be59451d5c312caBill Wendling lowerIncomingArguments(F); 400d5d170097241534401bbbebb4be59451d5c312caBill Wendling lowerAcrossUnwindEdges(F, Invokes); 401d5d170097241534401bbbebb4be59451d5c312caBill Wendling 402f1b41dd38d2b2713e3870f384525b020bbac05f6Bob Wilson Value *FuncCtx = 403f1b41dd38d2b2713e3870f384525b020bbac05f6Bob Wilson setupFunctionContext(F, makeArrayRef(LPads.begin(), LPads.end())); 404cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling BasicBlock *EntryBB = F.begin(); 405f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer IRBuilder<> Builder(EntryBB->getTerminator()); 406631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling 407631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling // Get a reference to the jump buffer. 408f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Value *JBufPtr = Builder.CreateConstGEP2_32(FuncCtx, 0, 5, "jbuf_gep"); 409631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling 410631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling // Save the frame pointer. 411f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Value *FramePtr = Builder.CreateConstGEP2_32(JBufPtr, 0, 0, "jbuf_fp_gep"); 412631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling 413f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Value *Val = Builder.CreateCall(FrameAddrFn, Builder.getInt32(0), "fp"); 414f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Builder.CreateStore(Val, FramePtr, /*isVolatile=*/true); 415631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling 416631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling // Save the stack pointer. 417f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Value *StackPtr = Builder.CreateConstGEP2_32(JBufPtr, 0, 2, "jbuf_sp_gep"); 418cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling 419f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Val = Builder.CreateCall(StackAddrFn, "sp"); 420f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Builder.CreateStore(Val, StackPtr, /*isVolatile=*/true); 421cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling 422cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling // Call the setjmp instrinsic. It fills in the rest of the jmpbuf. 423f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Value *SetjmpArg = Builder.CreateBitCast(JBufPtr, Builder.getInt8PtrTy()); 424f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Builder.CreateCall(BuiltinSetjmpFn, SetjmpArg); 425cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling 426cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling // Store a pointer to the function context so that the back-end will know 427cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling // where to look for it. 428f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Value *FuncCtxArg = Builder.CreateBitCast(FuncCtx, Builder.getInt8PtrTy()); 429f68b87f5fc1985c897e7a84ee040bcfff75b4959Benjamin Kramer Builder.CreateCall(FuncCtxFn, FuncCtxArg); 4302b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 4312b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // At this point, we are all set up, update the invoke instructions to mark 4322130ab0131ca0c0f5607937fe1f6ed48c28d39a2Bill Wendling // their call_site values. 4332b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling for (unsigned I = 0, E = Invokes.size(); I != E; ++I) { 4344cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling insertCallSiteStore(Invokes[I], I + 1); 4352b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 4362b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling ConstantInt *CallSiteNum = 4372b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling ConstantInt::get(Type::getInt32Ty(F.getContext()), I + 1); 4382b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 4392b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // Record the call site value for the back end so it stays associated with 4402b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // the invoke. 4412b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling CallInst::Create(CallSiteFn, CallSiteNum, "", Invokes[I]); 4422b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling } 4432b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 4442b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // Mark call instructions that aren't nounwind as no-action (call_site == 4452b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // -1). Skip the entry block, as prior to then, no function context has been 4462b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // created for this function and any unexpected exceptions thrown will go 4472b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // directly to the caller's context, which is what we want anyway, so no need 4482b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // to do anything here. 449da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling for (Function::iterator BB = F.begin(), E = F.end(); ++BB != E;) 4502b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling for (BasicBlock::iterator I = BB->begin(), end = BB->end(); I != end; ++I) 4512b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling if (CallInst *CI = dyn_cast<CallInst>(I)) { 4522b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling if (!CI->doesNotThrow()) 4534cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling insertCallSiteStore(CI, -1); 4542b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling } else if (ResumeInst *RI = dyn_cast<ResumeInst>(I)) { 4554cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling insertCallSiteStore(RI, -1); 4562b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling } 4572b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 458cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling // Register the function context and make sure it's known to not throw 459631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling CallInst *Register = CallInst::Create(RegisterFn, FuncCtx, "", 460cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling EntryBB->getTerminator()); 461cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling Register->setDoesNotThrow(); 462cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling 46320c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson // Following any allocas not in the entry block, update the saved SP in the 46420c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson // jmpbuf to the new value. 46520c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { 46620c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson if (BB == F.begin()) 46720c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson continue; 46820c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { 46920c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson if (CallInst *CI = dyn_cast<CallInst>(I)) { 47020c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson if (CI->getCalledFunction() != StackRestoreFn) 47120c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson continue; 47220c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson } else if (!isa<AllocaInst>(I)) { 47320c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson continue; 47420c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson } 47520c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson Instruction *StackAddr = CallInst::Create(StackAddrFn, "sp"); 47620c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson StackAddr->insertAfter(I); 47720c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson Instruction *StoreStackAddr = new StoreInst(StackAddr, StackPtr, true); 47820c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson StoreStackAddr->insertAfter(StackAddr); 47920c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson } 48020c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson } 48120c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson 482cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling // Finally, for any returns from this function, if this function contains an 483cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling // invoke, add a call to unregister the function context. 484cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling for (unsigned I = 0, E = Returns.size(); I != E; ++I) 485631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling CallInst::Create(UnregisterFn, FuncCtx, "", Returns[I]); 486cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling 4872b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling return true; 4882b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling} 4892b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 490eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendlingbool SjLjEHPrepare::runOnFunction(Function &F) { 491d2dae0cfa00ca3c5164b2543ed712ace6c08386bBill Wendling bool Res = setupEntryBlockAndCallSites(F); 4928b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach return Res; 4938b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach} 494