33 #define DEBUG_TYPE "sjljehprepare"
35 STATISTIC(NumInvokes,
"Number of invokes replaced");
36 STATISTIC(NumSpilled,
"Number of registers live across unwind edges");
40 Type *doubleUnderDataTy;
41 Type *doubleUnderJBufTy;
42 Type *FunctionContextTy;
57 bool doInitialization(
Module &M)
override;
62 return "SJLJ Exception Handling preparation";
66 bool setupEntryBlockAndCallSites(
Function &
F);
83 bool SjLjEHPrepare::doInitialization(
Module &M) {
103 void SjLjEHPrepare::insertCallSiteStore(
Instruction *
I,
int Number) {
112 Builder.CreateGEP(FunctionContextTy, FuncCtx, Idxs,
"call_site");
117 Builder.CreateStore(CallSiteNoC, CallSite,
true );
124 if (!LiveBBs.
insert(BB).second)
136 while (!UseWorkList.empty()) {
137 Value *Val = UseWorkList.pop_back_val();
141 if (EVI->getNumIndices() != 1)
143 if (*EVI->idx_begin() == 0)
145 else if (*EVI->idx_begin() == 1)
146 EVI->replaceAllUsesWith(SelVal);
147 if (EVI->use_empty())
148 EVI->eraseFromParent();
158 auto *SelI = cast<Instruction>(SelVal);
159 IRBuilder<> Builder(SelI->getParent(), std::next(SelI->getIterator()));
160 LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0,
"lpad.val");
161 LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1,
"lpad.val");
176 unsigned Align =
DL.getPrefTypeAlignment(FunctionContextTy);
177 FuncCtx =
new AllocaInst(FunctionContextTy,
nullptr, Align,
"fn_context",
187 Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 2,
"__data");
190 Value *ExceptionAddr = Builder.CreateConstGEP2_32(doubleUnderDataTy, FCData,
191 0, 0,
"exception_gep");
192 Value *ExnVal = Builder.CreateLoad(ExceptionAddr,
true,
"exn_val");
193 ExnVal = Builder.CreateIntToPtr(ExnVal, Builder.getInt8PtrTy());
195 Value *SelectorAddr = Builder.CreateConstGEP2_32(doubleUnderDataTy, FCData,
196 0, 1,
"exn_selector_gep");
197 Value *SelVal = Builder.CreateLoad(SelectorAddr,
true,
"exn_selector_val");
199 substituteLPadValues(LPI, ExnVal, SelVal);
205 Value *PersonalityFieldPtr = Builder.CreateConstGEP2_32(
206 FunctionContextTy, FuncCtx, 0, 3,
"pers_fn_gep");
208 Builder.CreateBitCast(PersonalityFn, Builder.
getInt8PtrTy()),
209 PersonalityFieldPtr,
true);
212 Value *LSDA = Builder.CreateCall(LSDAAddrFn, {},
"lsda_addr");
213 Value *LSDAFieldPtr =
214 Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 4,
"lsda_gep");
215 Builder.CreateStore(LSDA, LSDAFieldPtr,
true);
224 void SjLjEHPrepare::lowerIncomingArguments(
Function &F) {
226 while (isa<AllocaInst>(AfterAllocaInsPt) &&
227 cast<AllocaInst>(AfterAllocaInsPt)->isStaticAlloca())
231 for (
auto &AI : F.
args()) {
232 Type *Ty = AI.getType();
238 TrueValue, &AI, UndefValue, AI.
getName() +
".tmp", &*AfterAllocaInsPt);
248 void SjLjEHPrepare::lowerAcrossUnwindEdges(
Function &F,
256 if (Inst.use_empty())
258 if (Inst.hasOneUse() &&
259 cast<Instruction>(Inst.user_back())->
getParent() == &BB &&
260 !isa<PHINode>(Inst.user_back()))
265 if (
auto *AI = dyn_cast<AllocaInst>(&Inst))
266 if (AI->isStaticAlloca())
273 if (UI->
getParent() != &BB || isa<PHINode>(UI))
280 while (!Users.
empty()) {
283 if (!isa<PHINode>(U)) {
287 PHINode *PN = cast<PHINode>(U);
296 bool NeedsSpill =
false;
298 BasicBlock *UnwindBlock = Invoke->getUnwindDest();
299 if (UnwindBlock != &BB && LiveBBs.
count(UnwindBlock)) {
300 DEBUG(
dbgs() <<
"SJLJ Spill: " << Inst <<
" around "
301 << UnwindBlock->
getName() <<
"\n");
320 BasicBlock *UnwindBlock = Invoke->getUnwindDest();
326 PHIsToDemote.
insert(cast<PHINode>(PN));
327 if (PHIsToDemote.
empty())
331 for (
PHINode *PN : PHIsToDemote)
342 bool SjLjEHPrepare::setupEntryBlockAndCallSites(
Function &F) {
349 if (
auto *II = dyn_cast<InvokeInst>(BB.getTerminator())) {
350 if (
Function *Callee = II->getCalledFunction())
351 if (Callee->getIntrinsicID() == Intrinsic::donothing) {
359 LPads.
insert(II->getUnwindDest()->getLandingPadInst());
360 }
else if (
auto *RI = dyn_cast<ReturnInst>(BB.getTerminator())) {
367 NumInvokes += Invokes.
size();
369 lowerIncomingArguments(F);
370 lowerAcrossUnwindEdges(F, Invokes);
379 Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 5,
"jbuf_gep");
382 Value *
FramePtr = Builder.CreateConstGEP2_32(doubleUnderJBufTy, JBufPtr, 0, 0,
385 Value *Val = Builder.CreateCall(FrameAddrFn, Builder.getInt32(0),
"fp");
386 Builder.CreateStore(Val, FramePtr,
true);
389 Value *StackPtr = Builder.CreateConstGEP2_32(doubleUnderJBufTy, JBufPtr, 0, 2,
392 Val = Builder.CreateCall(StackAddrFn, {},
"sp");
393 Builder.CreateStore(Val, StackPtr,
true);
396 Builder.CreateCall(BuiltinSetupDispatchFn, {});
400 Value *FuncCtxArg = Builder.CreateBitCast(FuncCtx, Builder.getInt8PtrTy());
401 Builder.CreateCall(FuncCtxFn, FuncCtxArg);
405 for (
unsigned I = 0,
E = Invokes.
size(); I !=
E; ++
I) {
406 insertCallSiteStore(Invokes[I], I + 1);
422 if (&BB == &F.front())
426 insertCallSiteStore(&I, -1);
437 if (&BB == &F.front())
440 if (
auto *CI = dyn_cast<CallInst>(&I)) {
441 if (CI->getCalledFunction() != StackRestoreFn)
443 }
else if (!isa<AllocaInst>(&I)) {
461 bool SjLjEHPrepare::runOnFunction(
Function &F) {
472 BuiltinSetupDispatchFn =
478 bool Res = setupEntryBlockAndCallSites(F);
Return a value (possibly void), from a function.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void push_back(const T &Elt)
AllocaInst * DemoteRegToStack(Instruction &X, bool VolatileLoads=false, Instruction *AllocaPoint=nullptr)
This function takes a virtual register computed by an Instruction and replaces it with a slot in the ...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
STATISTIC(NumFunctions,"Total number of functions")
A Module instance is used to store all the information related to an LLVM module. ...
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.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr, Instruction *MDFrom=nullptr)
const Instruction & front() const
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.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
'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...
Constant * getPersonalityFn() const
Get the personality function associated with this function.
LLVM_NODISCARD bool empty() const
bool insert(const value_type &X)
Insert a new element into the SetVector.
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.
An instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
unsigned getNumIncomingValues() const
Return the number of incoming edges.
The landingpad instruction holds all of the information necessary to generate correct exception handl...
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.
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.
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
FunctionPass class - This class is used to implement most global optimizations.
LLVM_NODISCARD bool empty() const
static UndefValue * get(Type *T)
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.
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the generic address space (address sp...
This is the shared class of boolean and integer constants.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, ArrayRef< OperandBundleDef > Bundles=None, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Promote Memory to Register
LLVM_NODISCARD T pop_back_val()
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)
pred_range predecessors(BasicBlock *BB)
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()
bool mayThrow() const
Return true if this instruction may throw an exception.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
static IntegerType * getInt32Ty(LLVMContext &C)
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...
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
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...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
const BasicBlock & front() const
AllocaInst * DemotePHIToStack(PHINode *P, Instruction *AllocaPoint=nullptr)
This function takes a virtual register computed by a phi node and replaces it with a slot in the stac...
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)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
static const unsigned FramePtr
StringRef - Represent a constant reference to a string, i.e.
static void MarkBlocksLiveIn(BasicBlock *BB, SmallPtrSetImpl< BasicBlock * > &LiveBBs)
MarkBlocksLiveIn - Insert BB and all of its predecessors into LiveBBs until we reach blocks we've alr...
iterator getFirstInsertionPt()
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const BasicBlock * getParent() const
iterator_range< arg_iterator > args()
LLVMContext & getContext() const
Get the global data context.
an instruction to allocate memory on the stack