SjLjEHPrepare.cpp revision 06cb8ed00696eb14d1b831921452e50ec0568ea2
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 Type *Int32Ty = Type::getInt32Ty(F.getContext()); 2002b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling Value *Zero = ConstantInt::get(Int32Ty, 0); 2012b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling Value *One = ConstantInt::get(Int32Ty, 1); 2024cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Value *Two = ConstantInt::get(Int32Ty, 2); 2034cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Value *Three = ConstantInt::get(Int32Ty, 3); 2044cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Value *Four = ConstantInt::get(Int32Ty, 4); 2052b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 2064cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Value *Idxs[2] = { Zero, 0 }; 2072b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 2082b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling for (unsigned I = 0, E = LPads.size(); I != E; ++I) { 2092b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling LandingPadInst *LPI = LPads[I]; 2102b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling IRBuilder<> Builder(LPI->getParent()->getFirstInsertionPt()); 2112b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 2124cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling // Reference the __data field. 2134cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Idxs[1] = Two; 2144cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Value *FCData = Builder.CreateGEP(FuncCtx, Idxs, "__data"); 2154cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling 2164cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling // The exception values come back in context->__data[0]. 2174cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Idxs[1] = Zero; 2184cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Value *ExceptionAddr = Builder.CreateGEP(FCData, Idxs, "exception_gep"); 2192b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling Value *ExnVal = Builder.CreateLoad(ExceptionAddr, true, "exn_val"); 2202b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling ExnVal = Builder.CreateIntToPtr(ExnVal, Type::getInt8PtrTy(F.getContext())); 2214cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling 2224cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Idxs[1] = One; 2234cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Value *SelectorAddr = Builder.CreateGEP(FCData, Idxs, "exn_selector_gep"); 2242b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val"); 2252b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 22669fdcd7f902256d6deec8f085f5bb12bd39f762eBill Wendling substituteLPadValues(LPI, ExnVal, SelVal); 2272b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling } 2282b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 2292b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // Personality function 2304cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Idxs[1] = Three; 2312b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling if (!PersonalityFn) 2322b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling PersonalityFn = LPads[0]->getPersonalityFn(); 2332b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling Value *PersonalityFieldPtr = 2342b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling GetElementPtrInst::Create(FuncCtx, Idxs, "pers_fn_gep", 2352b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling EntryBB->getTerminator()); 2362b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling new StoreInst(PersonalityFn, PersonalityFieldPtr, true, 2372b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling EntryBB->getTerminator()); 2382b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 2392b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // LSDA address 2402b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling Value *LSDA = CallInst::Create(LSDAAddrFn, "lsda_addr", 2412b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling EntryBB->getTerminator()); 2424cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Idxs[1] = Four; 2434cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling Value *LSDAFieldPtr = GetElementPtrInst::Create(FuncCtx, Idxs, "lsda_gep", 2444cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling EntryBB->getTerminator()); 2452b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling new StoreInst(LSDA, LSDAFieldPtr, true, EntryBB->getTerminator()); 2462b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 247631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling return FuncCtx; 2482b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling} 2492b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 250d5d170097241534401bbbebb4be59451d5c312caBill Wendling/// lowerIncomingArguments - To avoid having to handle incoming arguments 251d5d170097241534401bbbebb4be59451d5c312caBill Wendling/// specially, we lower each arg to a copy instruction in the entry block. This 252d5d170097241534401bbbebb4be59451d5c312caBill Wendling/// ensures that the argument value itself cannot be live out of the entry 253d5d170097241534401bbbebb4be59451d5c312caBill Wendling/// block. 254eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendlingvoid SjLjEHPrepare::lowerIncomingArguments(Function &F) { 255d5d170097241534401bbbebb4be59451d5c312caBill Wendling BasicBlock::iterator AfterAllocaInsPt = F.begin()->begin(); 256d5d170097241534401bbbebb4be59451d5c312caBill Wendling while (isa<AllocaInst>(AfterAllocaInsPt) && 257d5d170097241534401bbbebb4be59451d5c312caBill Wendling isa<ConstantInt>(cast<AllocaInst>(AfterAllocaInsPt)->getArraySize())) 258d5d170097241534401bbbebb4be59451d5c312caBill Wendling ++AfterAllocaInsPt; 259d5d170097241534401bbbebb4be59451d5c312caBill Wendling 260d5d170097241534401bbbebb4be59451d5c312caBill Wendling for (Function::arg_iterator 261d5d170097241534401bbbebb4be59451d5c312caBill Wendling AI = F.arg_begin(), AE = F.arg_end(); AI != AE; ++AI) { 262d5d170097241534401bbbebb4be59451d5c312caBill Wendling Type *Ty = AI->getType(); 263d5d170097241534401bbbebb4be59451d5c312caBill Wendling 264d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Aggregate types can't be cast, but are legal argument types, so we have 265d5d170097241534401bbbebb4be59451d5c312caBill Wendling // to handle them differently. We use an extract/insert pair as a 266d5d170097241534401bbbebb4be59451d5c312caBill Wendling // lightweight method to achieve the same goal. 267d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) { 268d5d170097241534401bbbebb4be59451d5c312caBill Wendling Instruction *EI = ExtractValueInst::Create(AI, 0, "", AfterAllocaInsPt); 269d5d170097241534401bbbebb4be59451d5c312caBill Wendling Instruction *NI = InsertValueInst::Create(AI, EI, 0); 270d5d170097241534401bbbebb4be59451d5c312caBill Wendling NI->insertAfter(EI); 271d5d170097241534401bbbebb4be59451d5c312caBill Wendling AI->replaceAllUsesWith(NI); 272d5d170097241534401bbbebb4be59451d5c312caBill Wendling 273d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Set the operand of the instructions back to the AllocaInst. 274d5d170097241534401bbbebb4be59451d5c312caBill Wendling EI->setOperand(0, AI); 275d5d170097241534401bbbebb4be59451d5c312caBill Wendling NI->setOperand(0, AI); 276d5d170097241534401bbbebb4be59451d5c312caBill Wendling } else { 277d5d170097241534401bbbebb4be59451d5c312caBill Wendling // This is always a no-op cast because we're casting AI to AI->getType() 278d5d170097241534401bbbebb4be59451d5c312caBill Wendling // so src and destination types are identical. BitCast is the only 279d5d170097241534401bbbebb4be59451d5c312caBill Wendling // possibility. 280d5d170097241534401bbbebb4be59451d5c312caBill Wendling CastInst *NC = 281d5d170097241534401bbbebb4be59451d5c312caBill Wendling new BitCastInst(AI, AI->getType(), AI->getName() + ".tmp", 282d5d170097241534401bbbebb4be59451d5c312caBill Wendling AfterAllocaInsPt); 283d5d170097241534401bbbebb4be59451d5c312caBill Wendling AI->replaceAllUsesWith(NC); 284d5d170097241534401bbbebb4be59451d5c312caBill Wendling 285d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Set the operand of the cast instruction back to the AllocaInst. 286d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Normally it's forbidden to replace a CastInst's operand because it 287d5d170097241534401bbbebb4be59451d5c312caBill Wendling // could cause the opcode to reflect an illegal conversion. However, we're 288d5d170097241534401bbbebb4be59451d5c312caBill Wendling // replacing it here with the same value it was constructed with. We do 289d5d170097241534401bbbebb4be59451d5c312caBill Wendling // this because the above replaceAllUsesWith() clobbered the operand, but 290d5d170097241534401bbbebb4be59451d5c312caBill Wendling // we want this one to remain. 291d5d170097241534401bbbebb4be59451d5c312caBill Wendling NC->setOperand(0, AI); 292d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 293d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 294d5d170097241534401bbbebb4be59451d5c312caBill Wendling} 295d5d170097241534401bbbebb4be59451d5c312caBill Wendling 296d5d170097241534401bbbebb4be59451d5c312caBill Wendling/// lowerAcrossUnwindEdges - Find all variables which are alive across an unwind 297d5d170097241534401bbbebb4be59451d5c312caBill Wendling/// edge and spill them. 298eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendlingvoid SjLjEHPrepare::lowerAcrossUnwindEdges(Function &F, 299eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendling ArrayRef<InvokeInst*> Invokes) { 300d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Finally, scan the code looking for instructions with bad live ranges. 301d5d170097241534401bbbebb4be59451d5c312caBill Wendling for (Function::iterator 302d5d170097241534401bbbebb4be59451d5c312caBill Wendling BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) { 303d5d170097241534401bbbebb4be59451d5c312caBill Wendling for (BasicBlock::iterator 304d5d170097241534401bbbebb4be59451d5c312caBill Wendling II = BB->begin(), IIE = BB->end(); II != IIE; ++II) { 305d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Ignore obvious cases we don't have to handle. In particular, most 306d5d170097241534401bbbebb4be59451d5c312caBill Wendling // instructions either have no uses or only have a single use inside the 307d5d170097241534401bbbebb4be59451d5c312caBill Wendling // current block. Ignore them quickly. 308d5d170097241534401bbbebb4be59451d5c312caBill Wendling Instruction *Inst = II; 309d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (Inst->use_empty()) continue; 310d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (Inst->hasOneUse() && 311d5d170097241534401bbbebb4be59451d5c312caBill Wendling cast<Instruction>(Inst->use_back())->getParent() == BB && 312d5d170097241534401bbbebb4be59451d5c312caBill Wendling !isa<PHINode>(Inst->use_back())) continue; 313d5d170097241534401bbbebb4be59451d5c312caBill Wendling 314d5d170097241534401bbbebb4be59451d5c312caBill Wendling // If this is an alloca in the entry block, it's not a real register 315d5d170097241534401bbbebb4be59451d5c312caBill Wendling // value. 316d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (AllocaInst *AI = dyn_cast<AllocaInst>(Inst)) 317d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (isa<ConstantInt>(AI->getArraySize()) && BB == F.begin()) 318d5d170097241534401bbbebb4be59451d5c312caBill Wendling continue; 319d5d170097241534401bbbebb4be59451d5c312caBill Wendling 320d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Avoid iterator invalidation by copying users to a temporary vector. 321d5d170097241534401bbbebb4be59451d5c312caBill Wendling SmallVector<Instruction*, 16> Users; 322d5d170097241534401bbbebb4be59451d5c312caBill Wendling for (Value::use_iterator 323d5d170097241534401bbbebb4be59451d5c312caBill Wendling UI = Inst->use_begin(), E = Inst->use_end(); UI != E; ++UI) { 324d5d170097241534401bbbebb4be59451d5c312caBill Wendling Instruction *User = cast<Instruction>(*UI); 325d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (User->getParent() != BB || isa<PHINode>(User)) 326d5d170097241534401bbbebb4be59451d5c312caBill Wendling Users.push_back(User); 327d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 328d5d170097241534401bbbebb4be59451d5c312caBill Wendling 329d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Find all of the blocks that this value is live in. 330bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier SmallPtrSet<BasicBlock*, 64> LiveBBs; 331bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier LiveBBs.insert(Inst->getParent()); 332d5d170097241534401bbbebb4be59451d5c312caBill Wendling while (!Users.empty()) { 333bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier Instruction *U = Users.back(); 334bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier Users.pop_back(); 335d5d170097241534401bbbebb4be59451d5c312caBill Wendling 336bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier if (!isa<PHINode>(U)) { 337bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier MarkBlocksLiveIn(U->getParent(), LiveBBs); 338bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier } else { 339d5d170097241534401bbbebb4be59451d5c312caBill Wendling // Uses for a PHI node occur in their predecessor block. 340bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier PHINode *PN = cast<PHINode>(U); 341d5d170097241534401bbbebb4be59451d5c312caBill Wendling for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 342d5d170097241534401bbbebb4be59451d5c312caBill Wendling if (PN->getIncomingValue(i) == Inst) 343bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier MarkBlocksLiveIn(PN->getIncomingBlock(i), LiveBBs); 344d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 345d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 346d5d170097241534401bbbebb4be59451d5c312caBill Wendling 347bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier // Now that we know all of the blocks that this thing is live in, see if 348bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier // it includes any of the unwind locations. 349bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier bool NeedsSpill = false; 350bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { 351bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); 352bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier if (UnwindBlock != BB && LiveBBs.count(UnwindBlock)) { 353bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier DEBUG(dbgs() << "SJLJ Spill: " << *Inst << " around " 354bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier << UnwindBlock->getName() << "\n"); 355bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier NeedsSpill = true; 356bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier break; 357d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 358d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 359d5d170097241534401bbbebb4be59451d5c312caBill Wendling 360bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier // If we decided we need a spill, do it. 361bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier // FIXME: Spilling this way is overkill, as it forces all uses of 362bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier // the value to be reloaded from the stack slot, even those that aren't 363bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier // in the unwind blocks. We should be more selective. 364bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier if (NeedsSpill) { 365bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier DemoteRegToStack(*Inst, true); 366bace5da91dbfc15d04c0e9897805ed4c5c0461adChad Rosier ++NumSpilled; 3679eb5f170a219decc4ee07b57b0403d3836a8d946Bill Wendling } 368d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 369d5d170097241534401bbbebb4be59451d5c312caBill Wendling } 3700ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling 3710ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling // Go through the landing pads and remove any PHIs there. 3720ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { 3730ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); 3740ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling LandingPadInst *LPI = UnwindBlock->getLandingPadInst(); 3750ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling 3760ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling // Place PHIs into a set to avoid invalidating the iterator. 3770ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling SmallPtrSet<PHINode*, 8> PHIsToDemote; 3780ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling for (BasicBlock::iterator 3790ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling PN = UnwindBlock->begin(); isa<PHINode>(PN); ++PN) 3800ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling PHIsToDemote.insert(cast<PHINode>(PN)); 3810ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling if (PHIsToDemote.empty()) continue; 3820ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling 3830ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling // Demote the PHIs to the stack. 3840ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling for (SmallPtrSet<PHINode*, 8>::iterator 3850ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling I = PHIsToDemote.begin(), E = PHIsToDemote.end(); I != E; ++I) 3860ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling DemotePHIToStack(*I); 3870ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling 3880ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling // Move the landingpad instruction back to the top of the landing pad block. 3890ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling LPI->moveBefore(UnwindBlock->begin()); 3900ad56122e585d3d27ea852115390a9e53cabc9d5Bill Wendling } 391d5d170097241534401bbbebb4be59451d5c312caBill Wendling} 392d5d170097241534401bbbebb4be59451d5c312caBill Wendling 3932b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling/// setupEntryBlockAndCallSites - Setup the entry block by creating and filling 3942b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling/// the function context and marking the call sites with the appropriate 3952b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling/// values. These values are used by the DWARF EH emitter. 396eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendlingbool SjLjEHPrepare::setupEntryBlockAndCallSites(Function &F) { 397cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling SmallVector<ReturnInst*, 16> Returns; 3982b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling SmallVector<InvokeInst*, 16> Invokes; 399f1b41dd38d2b2713e3870f384525b020bbac05f6Bob Wilson SmallSetVector<LandingPadInst*, 16> LPads; 4002b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 4012b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // Look through the terminators of the basic blocks to find invokes. 4022b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 4032b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) { 4042b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling Invokes.push_back(II); 405f1b41dd38d2b2713e3870f384525b020bbac05f6Bob Wilson LPads.insert(II->getUnwindDest()->getLandingPadInst()); 406cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling } else if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) { 407cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling Returns.push_back(RI); 4082b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling } 4092b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 4102b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling if (Invokes.empty()) return false; 4112b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 412d2dae0cfa00ca3c5164b2543ed712ace6c08386bBill Wendling NumInvokes += Invokes.size(); 413d2dae0cfa00ca3c5164b2543ed712ace6c08386bBill Wendling 414d5d170097241534401bbbebb4be59451d5c312caBill Wendling lowerIncomingArguments(F); 415d5d170097241534401bbbebb4be59451d5c312caBill Wendling lowerAcrossUnwindEdges(F, Invokes); 416d5d170097241534401bbbebb4be59451d5c312caBill Wendling 417f1b41dd38d2b2713e3870f384525b020bbac05f6Bob Wilson Value *FuncCtx = 418f1b41dd38d2b2713e3870f384525b020bbac05f6Bob Wilson setupFunctionContext(F, makeArrayRef(LPads.begin(), LPads.end())); 419cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling BasicBlock *EntryBB = F.begin(); 420cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling Type *Int32Ty = Type::getInt32Ty(F.getContext()); 421631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling 422cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling Value *Idxs[2] = { 423631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling ConstantInt::get(Int32Ty, 0), 0 424cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling }; 425631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling 426631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling // Get a reference to the jump buffer. 427631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling Idxs[1] = ConstantInt::get(Int32Ty, 5); 428da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling Value *JBufPtr = GetElementPtrInst::Create(FuncCtx, Idxs, "jbuf_gep", 429da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling EntryBB->getTerminator()); 430631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling 431631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling // Save the frame pointer. 432631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling Idxs[1] = ConstantInt::get(Int32Ty, 0); 433da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling Value *FramePtr = GetElementPtrInst::Create(JBufPtr, Idxs, "jbuf_fp_gep", 434da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling EntryBB->getTerminator()); 435631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling 436631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling Value *Val = CallInst::Create(FrameAddrFn, 437631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling ConstantInt::get(Int32Ty, 0), 438631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling "fp", 439631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling EntryBB->getTerminator()); 440631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling new StoreInst(Val, FramePtr, true, EntryBB->getTerminator()); 441631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling 442631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling // Save the stack pointer. 443631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling Idxs[1] = ConstantInt::get(Int32Ty, 2); 444da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling Value *StackPtr = GetElementPtrInst::Create(JBufPtr, Idxs, "jbuf_sp_gep", 445da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling EntryBB->getTerminator()); 446cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling 447631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling Val = CallInst::Create(StackAddrFn, "sp", EntryBB->getTerminator()); 448cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling new StoreInst(Val, StackPtr, true, EntryBB->getTerminator()); 449cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling 450cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling // Call the setjmp instrinsic. It fills in the rest of the jmpbuf. 451da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling Value *SetjmpArg = CastInst::Create(Instruction::BitCast, JBufPtr, 452da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling Type::getInt8PtrTy(F.getContext()), "", 453da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling EntryBB->getTerminator()); 454f8520d564c095e3ee278090b605c4b827604c817Bill Wendling CallInst::Create(BuiltinSetjmpFn, SetjmpArg, "", EntryBB->getTerminator()); 455cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling 456cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling // Store a pointer to the function context so that the back-end will know 457cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling // where to look for it. 458da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling Value *FuncCtxArg = CastInst::Create(Instruction::BitCast, FuncCtx, 459da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling Type::getInt8PtrTy(F.getContext()), "", 460da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling EntryBB->getTerminator()); 461cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling CallInst::Create(FuncCtxFn, FuncCtxArg, "", EntryBB->getTerminator()); 4622b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 4632b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // At this point, we are all set up, update the invoke instructions to mark 4642130ab0131ca0c0f5607937fe1f6ed48c28d39a2Bill Wendling // their call_site values. 4652b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling for (unsigned I = 0, E = Invokes.size(); I != E; ++I) { 4664cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling insertCallSiteStore(Invokes[I], I + 1); 4672b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 4682b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling ConstantInt *CallSiteNum = 4692b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling ConstantInt::get(Type::getInt32Ty(F.getContext()), I + 1); 4702b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 4712b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // Record the call site value for the back end so it stays associated with 4722b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // the invoke. 4732b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling CallInst::Create(CallSiteFn, CallSiteNum, "", Invokes[I]); 4742b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling } 4752b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 4762b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // Mark call instructions that aren't nounwind as no-action (call_site == 4772b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // -1). Skip the entry block, as prior to then, no function context has been 4782b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // created for this function and any unexpected exceptions thrown will go 4792b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // directly to the caller's context, which is what we want anyway, so no need 4802b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling // to do anything here. 481da7e6a9c8888fe9c4198214cc19f6f55e21e72e4Bill Wendling for (Function::iterator BB = F.begin(), E = F.end(); ++BB != E;) 4822b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling for (BasicBlock::iterator I = BB->begin(), end = BB->end(); I != end; ++I) 4832b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling if (CallInst *CI = dyn_cast<CallInst>(I)) { 4842b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling if (!CI->doesNotThrow()) 4854cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling insertCallSiteStore(CI, -1); 4862b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling } else if (ResumeInst *RI = dyn_cast<ResumeInst>(I)) { 4874cc4666268c6c62de763c46fefe304adf08a01a1Bill Wendling insertCallSiteStore(RI, -1); 4882b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling } 4892b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 490cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling // Register the function context and make sure it's known to not throw 491631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling CallInst *Register = CallInst::Create(RegisterFn, FuncCtx, "", 492cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling EntryBB->getTerminator()); 493cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling Register->setDoesNotThrow(); 494cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling 49520c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson // Following any allocas not in the entry block, update the saved SP in the 49620c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson // jmpbuf to the new value. 49720c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { 49820c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson if (BB == F.begin()) 49920c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson continue; 50020c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { 50120c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson if (CallInst *CI = dyn_cast<CallInst>(I)) { 50220c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson if (CI->getCalledFunction() != StackRestoreFn) 50320c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson continue; 50420c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson } else if (!isa<AllocaInst>(I)) { 50520c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson continue; 50620c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson } 50720c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson Instruction *StackAddr = CallInst::Create(StackAddrFn, "sp"); 50820c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson StackAddr->insertAfter(I); 50920c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson Instruction *StoreStackAddr = new StoreInst(StackAddr, StackPtr, true); 51020c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson StoreStackAddr->insertAfter(StackAddr); 51120c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson } 51220c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson } 51320c918dfed5830f6d0c54c9c38817bd660cb6a13Bob Wilson 514cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling // Finally, for any returns from this function, if this function contains an 515cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling // invoke, add a call to unregister the function context. 516cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling for (unsigned I = 0, E = Returns.size(); I != E; ++I) 517631d11765b9f7ebdb49679c92bd41083fbab3f62Bill Wendling CallInst::Create(UnregisterFn, FuncCtx, "", Returns[I]); 518cc8cf97be434b4e2b9c0388db1bfb709f09098ebBill Wendling 5192b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling return true; 5202b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling} 5212b6bd7ba5819d8c73c89291c6de89a86dbbffe9cBill Wendling 522eabae1d07bffac60d9f4f2473cf6736d6a1c372dBill Wendlingbool SjLjEHPrepare::runOnFunction(Function &F) { 523d2dae0cfa00ca3c5164b2543ed712ace6c08386bBill Wendling bool Res = setupEntryBlockAndCallSites(F); 5248b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach return Res; 5258b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach} 526