15 #define DEBUG_TYPE "sjljehprepare"
41 STATISTIC(NumInvokes,
"Number of invokes replaced");
42 STATISTIC(NumSpilled,
"Number of registers live across unwind edges");
47 Type *FunctionContextTy;
63 bool doInitialization(
Module &M);
67 const char *getPassName()
const {
68 return "SJLJ Exception Handling preparation";
72 bool setupEntryBlockAndCallSites(
Function &
F);
85 return new SjLjEHPrepare(TM);
89 bool SjLjEHPrepare::doInitialization(
Module &M) {
121 void SjLjEHPrepare::insertCallSiteStore(
Instruction *
I,
int Number) {
128 Value *Idxs[2] = { Zero, One };
129 Value *
CallSite = Builder.CreateGEP(FuncCtx, Idxs,
"call_site");
134 Builder.CreateStore(CallSiteNoC, CallSite,
true );
153 while (!UseWorkList.empty()) {
154 Value *Val = UseWorkList.pop_back_val();
177 LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0,
"lpad.val");
178 LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1,
"lpad.val");
195 FuncCtx =
new AllocaInst(FunctionContextTy, 0, Align,
"fn_context",
199 for (
unsigned I = 0, E = LPads.
size(); I != E; ++
I) {
204 Value *FCData = Builder.CreateConstGEP2_32(FuncCtx, 0, 2,
"__data");
207 Value *ExceptionAddr =
208 Builder.CreateConstGEP2_32(FCData, 0, 0,
"exception_gep");
209 Value *ExnVal = Builder.CreateLoad(ExceptionAddr,
true,
"exn_val");
210 ExnVal = Builder.CreateIntToPtr(ExnVal, Builder.getInt8PtrTy());
212 Value *SelectorAddr =
213 Builder.CreateConstGEP2_32(FCData, 0, 1,
"exn_selector_gep");
214 Value *SelVal = Builder.CreateLoad(SelectorAddr,
true,
"exn_selector_val");
216 substituteLPadValues(LPI, ExnVal, SelVal);
222 PersonalityFn = LPads[0]->getPersonalityFn();
223 Value *PersonalityFieldPtr =
224 Builder.CreateConstGEP2_32(FuncCtx, 0, 3,
"pers_fn_gep");
226 Builder.CreateBitCast(PersonalityFn, Builder.getInt8PtrTy()),
227 PersonalityFieldPtr,
true);
230 Value *LSDA = Builder.CreateCall(LSDAAddrFn,
"lsda_addr");
231 Value *LSDAFieldPtr = Builder.CreateConstGEP2_32(FuncCtx, 0, 4,
"lsda_gep");
232 Builder.CreateStore(LSDA, LSDAFieldPtr,
true);
241 void SjLjEHPrepare::lowerIncomingArguments(
Function &F) {
243 while (isa<AllocaInst>(AfterAllocaInsPt) &&
244 isa<ConstantInt>(cast<AllocaInst>(AfterAllocaInsPt)->getArraySize()))
249 Type *Ty = AI->getType();
254 if (isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) {
258 AI->replaceAllUsesWith(NI);
284 void SjLjEHPrepare::lowerAcrossUnwindEdges(
Function &F,
303 if (
AllocaInst *AI = dyn_cast<AllocaInst>(Inst))
304 if (isa<ConstantInt>(AI->getArraySize()) && BB == F.
begin())
312 if (User->
getParent() != BB || isa<PHINode>(User))
319 while (!Users.
empty()) {
323 if (!isa<PHINode>(U)) {
327 PHINode *PN = cast<PHINode>(U);
336 bool NeedsSpill =
false;
337 for (
unsigned i = 0, e = Invokes.
size(); i != e; ++i) {
338 BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest();
339 if (UnwindBlock != BB && LiveBBs.
count(UnwindBlock)) {
340 DEBUG(
dbgs() <<
"SJLJ Spill: " << *Inst <<
" around "
341 << UnwindBlock->
getName() <<
"\n");
359 for (
unsigned i = 0, e = Invokes.
size(); i != e; ++i) {
360 BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest();
366 PHIsToDemote.
insert(cast<PHINode>(PN));
367 if (PHIsToDemote.
empty())
372 E = PHIsToDemote.
end();
384 bool SjLjEHPrepare::setupEntryBlockAndCallSites(
Function &F) {
391 if (
InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) {
392 if (
Function *Callee = II->getCalledFunction())
393 if (Callee->isIntrinsic() &&
402 LPads.
insert(II->getUnwindDest()->getLandingPadInst());
403 }
else if (
ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
410 NumInvokes += Invokes.
size();
412 lowerIncomingArguments(F);
413 lowerAcrossUnwindEdges(F, Invokes);
421 Value *JBufPtr = Builder.CreateConstGEP2_32(FuncCtx, 0, 5,
"jbuf_gep");
424 Value *FramePtr = Builder.CreateConstGEP2_32(JBufPtr, 0, 0,
"jbuf_fp_gep");
426 Value *Val = Builder.CreateCall(FrameAddrFn, Builder.getInt32(0),
"fp");
427 Builder.CreateStore(Val, FramePtr,
true);
430 Value *StackPtr = Builder.CreateConstGEP2_32(JBufPtr, 0, 2,
"jbuf_sp_gep");
432 Val = Builder.CreateCall(StackAddrFn,
"sp");
433 Builder.CreateStore(Val, StackPtr,
true);
437 Builder.CreateCall(BuiltinSetjmpFn, SetjmpArg);
441 Value *FuncCtxArg = Builder.CreateBitCast(FuncCtx, Builder.getInt8PtrTy());
442 Builder.CreateCall(FuncCtxFn, FuncCtxArg);
446 for (
unsigned I = 0, E = Invokes.
size(); I != E; ++
I) {
447 insertCallSiteStore(Invokes[I], I + 1);
464 if (
CallInst *CI = dyn_cast<CallInst>(I)) {
465 if (!CI->doesNotThrow())
466 insertCallSiteStore(CI, -1);
467 }
else if (
ResumeInst *RI = dyn_cast<ResumeInst>(I)) {
468 insertCallSiteStore(RI, -1);
482 if (
CallInst *CI = dyn_cast<CallInst>(I)) {
483 if (CI->getCalledFunction() != StackRestoreFn)
485 }
else if (!isa<AllocaInst>(I)) {
497 for (
unsigned I = 0, E = Returns.
size(); I != E; ++
I)
503 bool SjLjEHPrepare::runOnFunction(
Function &F) {
504 bool Res = setupEntryBlockAndCallSites(F);
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
static void MarkBlocksLiveIn(BasicBlock *BB, SmallPtrSet< BasicBlock *, 64 > &LiveBBs)
LLVMContext & getContext() const
The main container class for the LLVM Intermediate Representation.
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getPrefTypeAlignment(Type *Ty) const
AllocaInst * DemoteRegToStack(Instruction &X, bool VolatileLoads=false, Instruction *AllocaPoint=0)
iv Induction Variable Users
iterator end()
Get an iterator to the end of the SetVector.
StringRef getName() const
Base class of casting instructions.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=0)
ID
LLVM Calling Convention Representation.
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool count(PtrType Ptr) const
count - Return true if the specified pointer is in the set.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
iterator begin()
Get an iterator to the beginning of the SetVector.
This class represents a no-op cast from one type to another.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
void replaceAllUsesWith(Value *V)
size_t size() const
size - Get the array size.
unsigned getNumIncomingValues() const
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
LLVM Basic Block Representation.
LLVM Constant Representation.
LandingPadInst * getLandingPadInst()
Return the landingpad instruction associated with the landing pad.
Interval::pred_iterator pred_begin(Interval *I)
static Type * getVoidTy(LLVMContext &C)
BasicBlock * getIncomingBlock(unsigned i) const
ItTy next(ItTy it, Dist n)
const DataLayout * getDataLayout() const
AllocaInst * DemotePHIToStack(PHINode *P, Instruction *AllocaPoint=0)
Interval::pred_iterator pred_end(Interval *I)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
static UndefValue * get(Type *T)
LLVMContext & getContext() const
All values hold a context through their type.
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
FunctionPass * createSjLjEHPreparePass(const TargetMachine *TM)
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=0)
SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
A SetVector that performs no allocations if smaller than a certain size.
static PointerType * getUnqual(Type *ElementType)
Class for constant integers.
Value * getIncomingValue(unsigned i) const
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
Promote Memory to Register
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
static InsertValueInst * Create(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &NameStr="", Instruction *InsertBefore=0)
static IntegerType * getInt32Ty(LLVMContext &C)
void insertAfter(Instruction *InsertPos)
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
LLVM Value Representation.
static const Function * getParent(const Value *V)
void moveBefore(Instruction *MovePos)
STATISTIC(NumInvokes,"Number of invokes replaced")
iterator getFirstInsertionPt()
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
unsigned getNumUses() const
const BasicBlock * getParent() const
LLVMContext & getContext() const