41 #define DEBUG_TYPE "sjljehprepare"
43 STATISTIC(NumInvokes,
"Number of invokes replaced");
44 STATISTIC(NumSpilled,
"Number of registers live across unwind edges");
48 Type *doubleUnderDataTy;
49 Type *doubleUnderJBufTy;
50 Type *FunctionContextTy;
66 bool doInitialization(
Module &M)
override;
70 const char *getPassName()
const override {
71 return "SJLJ Exception Handling preparation";
75 bool setupEntryBlockAndCallSites(
Function &
F);
92 bool SjLjEHPrepare::doInitialization(
Module &M) {
119 PersonalityFn =
nullptr;
126 void SjLjEHPrepare::insertCallSiteStore(
Instruction *
I,
int Number) {
133 Value *Idxs[2] = { Zero, One };
135 Builder.CreateGEP(FunctionContextTy, FuncCtx, Idxs,
"call_site");
140 Builder.CreateStore(CallSiteNoC, CallSite,
true );
147 if (!LiveBBs.
insert(BB).second)
159 while (!UseWorkList.empty()) {
160 Value *Val = UseWorkList.pop_back_val();
183 LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0,
"lpad.val");
184 LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1,
"lpad.val");
199 unsigned Align =
DL.getPrefTypeAlignment(FunctionContextTy);
200 FuncCtx =
new AllocaInst(FunctionContextTy,
nullptr, Align,
"fn_context",
204 for (
unsigned I = 0, E = LPads.
size(); I != E; ++
I) {
210 Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 2,
"__data");
213 Value *ExceptionAddr = Builder.CreateConstGEP2_32(doubleUnderDataTy, FCData,
214 0, 0,
"exception_gep");
215 Value *ExnVal = Builder.CreateLoad(ExceptionAddr,
true,
"exn_val");
216 ExnVal = Builder.CreateIntToPtr(ExnVal, Builder.getInt8PtrTy());
218 Value *SelectorAddr = Builder.CreateConstGEP2_32(doubleUnderDataTy, FCData,
219 0, 1,
"exn_selector_gep");
220 Value *SelVal = Builder.CreateLoad(SelectorAddr,
true,
"exn_selector_val");
222 substituteLPadValues(LPI, ExnVal, SelVal);
229 Value *PersonalityFieldPtr = Builder.CreateConstGEP2_32(
230 FunctionContextTy, FuncCtx, 0, 3,
"pers_fn_gep");
232 Builder.CreateBitCast(PersonalityFn, Builder.getInt8PtrTy()),
233 PersonalityFieldPtr,
true);
236 Value *LSDA = Builder.CreateCall(LSDAAddrFn, {},
"lsda_addr");
237 Value *LSDAFieldPtr =
238 Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 4,
"lsda_gep");
239 Builder.CreateStore(LSDA, LSDAFieldPtr,
true);
248 void SjLjEHPrepare::lowerIncomingArguments(
Function &F) {
250 while (isa<AllocaInst>(AfterAllocaInsPt) &&
251 isa<ConstantInt>(cast<AllocaInst>(AfterAllocaInsPt)->getArraySize()))
256 Type *Ty = AI->getType();
273 void SjLjEHPrepare::lowerAcrossUnwindEdges(
Function &F,
292 if (
AllocaInst *AI = dyn_cast<AllocaInst>(Inst))
293 if (isa<ConstantInt>(AI->getArraySize()) && BB == F.
begin())
300 if (UI->
getParent() != BB || isa<PHINode>(UI))
307 while (!Users.
empty()) {
311 if (!isa<PHINode>(U)) {
315 PHINode *PN = cast<PHINode>(U);
324 bool NeedsSpill =
false;
325 for (
unsigned i = 0, e = Invokes.
size(); i != e; ++i) {
326 BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest();
327 if (UnwindBlock != BB && LiveBBs.
count(UnwindBlock)) {
328 DEBUG(
dbgs() <<
"SJLJ Spill: " << *Inst <<
" around "
329 << UnwindBlock->
getName() <<
"\n");
347 for (
unsigned i = 0, e = Invokes.
size(); i != e; ++i) {
348 BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest();
354 PHIsToDemote.
insert(cast<PHINode>(PN));
355 if (PHIsToDemote.
empty())
359 for (
PHINode *PN : PHIsToDemote)
370 bool SjLjEHPrepare::setupEntryBlockAndCallSites(
Function &F) {
377 if (
InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) {
378 if (
Function *Callee = II->getCalledFunction())
379 if (Callee->isIntrinsic() &&
380 Callee->getIntrinsicID() == Intrinsic::donothing) {
388 LPads.
insert(II->getUnwindDest()->getLandingPadInst());
389 }
else if (
ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
396 NumInvokes += Invokes.
size();
398 lowerIncomingArguments(F);
399 lowerAcrossUnwindEdges(F, Invokes);
408 Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 5,
"jbuf_gep");
411 Value *
FramePtr = Builder.CreateConstGEP2_32(doubleUnderJBufTy, JBufPtr, 0, 0,
414 Value *Val = Builder.CreateCall(FrameAddrFn, Builder.getInt32(0),
"fp");
415 Builder.CreateStore(Val, FramePtr,
true);
418 Value *StackPtr = Builder.CreateConstGEP2_32(doubleUnderJBufTy, JBufPtr, 0, 2,
421 Val = Builder.CreateCall(StackAddrFn, {},
"sp");
422 Builder.CreateStore(Val, StackPtr,
true);
426 Builder.CreateCall(BuiltinSetjmpFn, SetjmpArg);
430 Value *FuncCtxArg = Builder.CreateBitCast(FuncCtx, Builder.getInt8PtrTy());
431 Builder.CreateCall(FuncCtxFn, FuncCtxArg);
435 for (
unsigned I = 0, E = Invokes.
size(); I != E; ++
I) {
436 insertCallSiteStore(Invokes[I], I + 1);
453 if (
CallInst *CI = dyn_cast<CallInst>(I)) {
454 if (!CI->doesNotThrow())
455 insertCallSiteStore(CI, -1);
456 }
else if (
ResumeInst *RI = dyn_cast<ResumeInst>(I)) {
457 insertCallSiteStore(RI, -1);
471 if (
CallInst *CI = dyn_cast<CallInst>(I)) {
472 if (CI->getCalledFunction() != StackRestoreFn)
474 }
else if (!isa<AllocaInst>(I)) {
486 for (
unsigned I = 0, E = Returns.
size(); I != E; ++
I)
492 bool SjLjEHPrepare::runOnFunction(
Function &F) {
493 bool Res = setupEntryBlockAndCallSites(F);
ReturnInst - Return a value (possibly void), from a function.
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
AllocaInst * DemoteRegToStack(Instruction &X, bool VolatileLoads=false, Instruction *AllocaPoint=nullptr)
DemoteRegToStack - This function takes a virtual register computed by an Instruction and replaces it ...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
STATISTIC(NumFunctions,"Total number of functions")
A Module instance is used to store all the information related to an LLVM module. ...
CallInst - This class represents a function call, abstracting a target machine's calling convention...
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
iv Induction Variable Users
iterator end()
Get an iterator to the end of the SetVector.
StringRef getName() const
Return a constant reference to the value's name.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
iterator begin()
Instruction iterator methods.
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
UndefValue - 'undef' values are things that do not have specified contents.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
bool insert(const value_type &X)
Insert a new element into the SetVector.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
iterator begin()
Get an iterator to the beginning of the SetVector.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
StoreInst - an instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
size_t size() const
size - Get the array size.
unsigned getNumIncomingValues() const
getNumIncomingValues - Return the number of incoming edges
friend const_iterator end(StringRef path)
Get end iterator over path.
LandingPadInst - The landingpad instruction holds all of the information necessary to generate correc...
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
Look up the specified function in the module symbol table.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important base class in LLVM.
ResumeInst - Resume the propagation of an exception.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
LandingPadInst * getLandingPadInst()
Return the landingpad instruction associated with the landing pad.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
BasicBlock * getIncomingBlock(unsigned i) const
getIncomingBlock - Return incoming basic block number i.
FunctionPass class - This class is used to implement most global optimizations.
Interval::pred_iterator pred_end(Interval *I)
static UndefValue * get(Type *T)
get() - Static factory methods - Return an 'undef' object of the specified type.
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)
A SetVector that performs no allocations if smaller than a certain size.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
static PointerType * getUnqual(Type *ElementType)
PointerType::getUnqual - This constructs a pointer to an object of the specified type in the generic ...
This is the shared class of boolean and integer constants.
Value * getIncomingValue(unsigned i) const
getIncomingValue - Return incoming value number x
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
StructType::get - This static method is the primary way to create a literal StructType.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Instruction * user_back()
user_back - Specialize the methods defined in Value, as we know that an instruction can only be used ...
Promote Memory to Register
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
static ConstantInt * getTrue(LLVMContext &Context)
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
iterator_range< user_iterator > users()
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
static IntegerType * getInt32Ty(LLVMContext &C)
Constant * getPersonalityFn() const
void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction...
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
bool hasOneUse() const
Return true if there is exactly one user of this value.
static ArrayType * get(Type *ElementType, uint64_t NumElements)
ArrayType::get - This static method is the primary way to construct an ArrayType. ...
INITIALIZE_PASS(SjLjEHPrepare,"sjljehprepare","Prepare SjLj exceptions", false, false) FunctionPass *llvm
FunctionPass * createSjLjEHPreparePass()
createSjLjEHPreparePass - This pass adapts exception handling code to use the GCC-style builtin setjm...
user_iterator user_begin()
AllocaInst * DemotePHIToStack(PHINode *P, Instruction *AllocaPoint=nullptr)
DemotePHIToStack - This function takes a virtual register computed by a phi node and replaces it with...
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
static const Function * getParent(const Value *V)
void moveBefore(Instruction *MovePos)
moveBefore - Unlink this instruction from its current basic block and insert it into the basic block ...
static const unsigned FramePtr
InvokeInst - Invoke instruction.
static void MarkBlocksLiveIn(BasicBlock *BB, SmallPtrSetImpl< BasicBlock * > &LiveBBs)
MarkBlocksLiveIn - Insert BB and all of its predescessors into LiveBBs until we reach blocks we've al...
iterator getFirstInsertionPt()
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
unsigned getNumUses() const
This method computes the number of uses of this Value.
const BasicBlock * getParent() const
LLVMContext & getContext() const
Get the global data context.
This file describes how to lower LLVM code to machine code.
AllocaInst - an instruction to allocate memory on the stack.