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) {
110 Value *Idxs[2] = { Zero, One };
112 Builder.
CreateGEP(FunctionContextTy, FuncCtx, Idxs,
"call_site");
124 if (!LiveBBs.
insert(BB).second)
139 while (!UseWorkList.empty()) {
140 Value *Val = UseWorkList.pop_back_val();
144 if (EVI->getNumIndices() != 1)
146 if (*EVI->idx_begin() == 0)
148 else if (*EVI->idx_begin() == 1)
149 EVI->replaceAllUsesWith(SelVal);
150 if (EVI->use_empty())
151 EVI->eraseFromParent();
161 auto *SelI = cast<Instruction>(SelVal);
162 IRBuilder<> Builder(SelI->getParent(), std::next(SelI->getIterator()));
163 LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0,
"lpad.val");
164 LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1,
"lpad.val");
179 unsigned Align = DL.getPrefTypeAlignment(FunctionContextTy);
180 FuncCtx =
new AllocaInst(FunctionContextTy, DL.getAllocaAddrSpace(),
181 nullptr,
Align,
"fn_context", &EntryBB->
front());
190 Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 2,
"__data");
193 Value *ExceptionAddr = Builder.CreateConstGEP2_32(doubleUnderDataTy, FCData,
194 0, 0,
"exception_gep");
195 Value *ExnVal = Builder.CreateLoad(ExceptionAddr,
true,
"exn_val");
196 ExnVal = Builder.CreateIntToPtr(ExnVal, Builder.getInt8PtrTy());
198 Value *SelectorAddr = Builder.CreateConstGEP2_32(doubleUnderDataTy, FCData,
199 0, 1,
"exn_selector_gep");
200 Value *SelVal = Builder.CreateLoad(SelectorAddr,
true,
"exn_selector_val");
202 substituteLPadValues(LPI, ExnVal, SelVal);
208 Value *PersonalityFieldPtr = Builder.CreateConstGEP2_32(
209 FunctionContextTy, FuncCtx, 0, 3,
"pers_fn_gep");
211 Builder.CreateBitCast(PersonalityFn, Builder.
getInt8PtrTy()),
212 PersonalityFieldPtr,
true);
215 Value *LSDA = Builder.CreateCall(LSDAAddrFn, {},
"lsda_addr");
216 Value *LSDAFieldPtr =
217 Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 4,
"lsda_gep");
218 Builder.CreateStore(LSDA, LSDAFieldPtr,
true);
227 void SjLjEHPrepare::lowerIncomingArguments(
Function &F) {
229 while (isa<AllocaInst>(AfterAllocaInsPt) &&
230 cast<AllocaInst>(AfterAllocaInsPt)->isStaticAlloca())
234 for (
auto &AI : F.
args()) {
239 if (AI.isSwiftError())
242 Type *Ty = AI.getType();
248 TrueValue, &AI, UndefValue, AI.
getName() +
".tmp", &*AfterAllocaInsPt);
258 void SjLjEHPrepare::lowerAcrossUnwindEdges(
Function &F,
266 if (Inst.use_empty())
268 if (Inst.hasOneUse() &&
269 cast<Instruction>(Inst.user_back())->
getParent() == &BB &&
270 !isa<PHINode>(Inst.user_back()))
275 if (
auto *AI = dyn_cast<AllocaInst>(&Inst))
276 if (AI->isStaticAlloca())
283 if (UI->
getParent() != &BB || isa<PHINode>(UI))
290 while (!Users.
empty()) {
293 if (!isa<PHINode>(U)) {
297 PHINode *PN = cast<PHINode>(U);
306 bool NeedsSpill =
false;
308 BasicBlock *UnwindBlock = Invoke->getUnwindDest();
309 if (UnwindBlock != &BB && LiveBBs.
count(UnwindBlock)) {
311 << UnwindBlock->
getName() <<
"\n");
330 BasicBlock *UnwindBlock = Invoke->getUnwindDest();
336 PHIsToDemote.
insert(cast<PHINode>(PN));
337 if (PHIsToDemote.
empty())
341 for (
PHINode *PN : PHIsToDemote)
352 bool SjLjEHPrepare::setupEntryBlockAndCallSites(
Function &F) {
359 if (
auto *II = dyn_cast<InvokeInst>(BB.getTerminator())) {
369 LPads.
insert(II->getUnwindDest()->getLandingPadInst());
370 }
else if (
auto *RI = dyn_cast<ReturnInst>(BB.getTerminator())) {
377 NumInvokes += Invokes.
size();
379 lowerIncomingArguments(F);
380 lowerAcrossUnwindEdges(F, Invokes);
389 Builder.CreateConstGEP2_32(FunctionContextTy, FuncCtx, 0, 5,
"jbuf_gep");
392 Value *FramePtr = Builder.CreateConstGEP2_32(doubleUnderJBufTy, JBufPtr, 0, 0,
395 Value *Val = Builder.CreateCall(FrameAddrFn, Builder.getInt32(0),
"fp");
396 Builder.CreateStore(Val, FramePtr,
true);
399 Value *StackPtr = Builder.CreateConstGEP2_32(doubleUnderJBufTy, JBufPtr, 0, 2,
402 Val = Builder.CreateCall(StackAddrFn, {},
"sp");
403 Builder.CreateStore(Val, StackPtr,
true);
406 Builder.CreateCall(BuiltinSetupDispatchFn, {});
410 Value *FuncCtxArg = Builder.CreateBitCast(FuncCtx, Builder.getInt8PtrTy());
411 Builder.CreateCall(FuncCtxFn, FuncCtxArg);
415 for (
unsigned I = 0,
E = Invokes.
size(); I !=
E; ++
I) {
416 insertCallSiteStore(Invokes[I], I + 1);
432 if (&BB == &F.front())
436 insertCallSiteStore(&I, -1);
447 if (&BB == &F.front())
450 if (
auto *CI = dyn_cast<CallInst>(&I)) {
451 if (CI->getCalledFunction() != StackRestoreFn)
453 }
else if (!isa<AllocaInst>(&I)) {
482 BuiltinSetupDispatchFn =
488 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.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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 ...
This class represents lattice values for constants.
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
A Module instance is used to store all the information related to an LLVM module. ...
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
void push_back(const T &Elt)
This class represents a function call, abstracting a target machine's calling convention.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr, Instruction *MDFrom=nullptr)
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< idf_ext_iterator< T, SetTy > > inverse_depth_first_ext(const T &G, SetTy &S)
STATISTIC(NumFunctions, "Total number of functions")
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
iv Induction Variable Users
iterator end()
Get an iterator to the end of the SetVector.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
iterator begin()
Instruction iterator methods.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
'undef' values are things that do not have specified contents.
LLVMContext & getContext() const
Get the global data context.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static StructType * get(LLVMContext &Context, ArrayRef< Type *> Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Type * getType() const
All values are typed, get the type of this value.
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)...
An instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
amdgpu Simplify well known AMD library false Value * Callee
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
static bool runOnFunction(Function &F, bool PostInlining)
The landingpad instruction holds all of the information necessary to generate correct exception handl...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
LLVM_NODISCARD bool empty() const
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const Instruction & front() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool mayThrow() const
Return true if this instruction may throw an exception.
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
FunctionPass class - This class is used to implement most global optimizations.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
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)
Value * CreateGEP(Value *Ptr, ArrayRef< Value *> IdxList, const Twine &Name="")
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.
Module.h This file contains the declarations for the Module class.
Promote Memory to Register
LLVM_NODISCARD T pop_back_val()
INITIALIZE_PASS(SjLjEHPrepare, DEBUG_TYPE, "Prepare SjLj exceptions", false, false) FunctionPass *llvm
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)
unsigned getNumIncomingValues() const
Return the number of incoming edges.
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()
static IntegerType * getInt32Ty(LLVMContext &C)
LLVM_NODISCARD bool empty() const
StringRef getName() const
Return a constant reference to the value's name.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction...
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)
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...
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.
Constant * getPersonalityFn() const
Get the personality function associated with this function.
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 ...
StringRef - Represent a constant reference to a string, i.e.
const LandingPadInst * getLandingPadInst() const
Return the landingpad instruction associated with the landing pad.
iterator_range< arg_iterator > args()
const BasicBlock * getParent() const
an instruction to allocate memory on the stack