44#define DEBUG_TYPE "dwarfehprepare"
46STATISTIC(NumResumesLowered,
"Number of resume calls lowered");
48 "Number of cleanup landing pads found unreachable");
50 "Number of cleanup landing pads remaining");
51STATISTIC(NumNoUnwind,
"Number of functions with nounwind");
52STATISTIC(NumUnwind,
"Number of functions with unwind");
63 const Triple &TargetTriple;
78 bool InsertUnwindResumeCalls();
84 : OptLevel(OptLevel_),
F(F_), TLI(TLI_), DTU(DTU_),
TTI(TTI_),
85 TargetTriple(TargetTriple_) {}
94 Value *ExnObj =
nullptr;
98 bool EraseIVIs =
false;
102 ExcIVI = dyn_cast<InsertValueInst>(SelIVI->
getOperand(0));
103 if (ExcIVI && isa<UndefValue>(ExcIVI->
getOperand(0)) &&
106 SelLoad = dyn_cast<LoadInst>(SelIVI->
getOperand(1));
129size_t DwarfEHPrepare::pruneUnreachableResumes(
132 assert(DTU &&
"Should have DomTreeUpdater here.");
135 size_t ResumeIndex = 0;
136 for (
auto *RI : Resumes) {
137 for (
auto *LP : CleanupLPads) {
139 ResumeReachable.set(ResumeIndex);
147 if (ResumeReachable.all())
148 return Resumes.size();
153 size_t ResumesLeft = 0;
154 for (
size_t I = 0,
E = Resumes.size();
I <
E; ++
I) {
156 if (ResumeReachable[
I]) {
157 Resumes[ResumesLeft++] = RI;
165 Resumes.resize(ResumesLeft);
169bool DwarfEHPrepare::InsertUnwindResumeCalls() {
172 if (
F.doesNotThrow())
184 NumCleanupLandingPadsRemaining += CleanupLPads.
size();
196 size_t ResumesLeft = Resumes.
size();
198 ResumesLeft = pruneUnreachableResumes(Resumes, CleanupLPads);
200 unsigned NumRemainingLPs = 0;
206 NumCleanupLandingPadsUnreachable += CleanupLPads.
size() - NumRemainingLPs;
207 NumCleanupLandingPadsRemaining -= CleanupLPads.
size() - NumRemainingLPs;
211 if (ResumesLeft == 0)
218 const char *RewindName;
219 bool DoesRewindFunctionNeedExceptionObject;
221 if ((Pers == EHPersonality::GNU_CXX || Pers == EHPersonality::GNU_CXX_SjLj) &&
222 TargetTriple.isTargetEHABICompatible()) {
223 RewindName = TLI.getLibcallName(RTLIB::CXA_END_CLEANUP);
225 RewindFunctionCallingConv =
226 TLI.getLibcallCallingConv(RTLIB::CXA_END_CLEANUP);
227 DoesRewindFunctionNeedExceptionObject =
false;
229 RewindName = TLI.getLibcallName(RTLIB::UNWIND_RESUME);
232 RewindFunctionCallingConv = TLI.getLibcallCallingConv(RTLIB::UNWIND_RESUME);
233 DoesRewindFunctionNeedExceptionObject =
true;
235 RewindFunction =
F.getParent()->getOrInsertFunction(RewindName, FTy);
238 if (ResumesLeft == 1) {
243 Value *ExnObj = GetExceptionObject(RI);
245 if (DoesRewindFunctionNeedExceptionObject)
257 CI->
setDebugLoc(DILocation::get(SP->getContext(), 0, 0, SP));
266 std::vector<DominatorTree::UpdateType> Updates;
267 Updates.reserve(Resumes.
size());
280 Updates.push_back({DominatorTree::Insert, Parent, UnwindBB});
282 Value *ExnObj = GetExceptionObject(RI);
288 if (DoesRewindFunctionNeedExceptionObject)
301 DTU->applyUpdates(Updates);
306bool DwarfEHPrepare::run() {
307 bool Changed = InsertUnwindResumeCalls();
315 const Triple &TargetTriple) {
318 return DwarfEHPrepare(OptLevel,
F, TLI, DT ? &DTU :
nullptr,
TTI,
341 if (
auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
342 DT = &DTWP->getDomTree();
345 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
346 TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
362 return "Exception handling preparation";
368char DwarfEHPrepareLegacyPass::ID = 0;
371 "Prepare DWARF exceptions",
false,
false)
379 return new DwarfEHPrepareLegacyPass(OptLevel);
This file implements the BitVector class.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool prepareDwarfEH(CodeGenOpt::Level OptLevel, Function &F, const TargetLowering &TLI, DominatorTree *DT, const TargetTransformInfo *TTI, const Triple &TargetTriple)
Module.h This file contains the declarations for the Module class.
const char LLVMTargetMachineRef TM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM Basic Block Representation.
const LandingPadInst * getLandingPadInst() const
Return the landingpad instruction associated with the landing pad.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
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...
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
void setCallingConv(CallingConv::ID CC)
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
DISubprogram * getSubprogram() const
Get the attached subprogram.
This instruction inserts a struct field of array element value into an aggregate value.
unsigned getNumIndices() const
idx_iterator idx_begin() const
const BasicBlock * getParent() const
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Resume the propagation of an exception.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
Target-Independent Code Generator Pass Configuration Options.
Triple - Helper class for working with autoconf configuration names.
static Type * getVoidTy(LLVMContext &C)
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
This function has undefined behavior.
Value * getOperand(unsigned i) const
LLVM Value Representation.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Level
Code generation optimization level.
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
This is an optimization pass for GlobalISel generic memory operations.
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
FunctionPass * createDwarfEHPass(CodeGenOpt::Level OptLevel)
createDwarfEHPass - This pass mulches exception handling code into a form adapted to code generation.
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
bool simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI, DomTreeUpdater *DTU=nullptr, const SimplifyCFGOptions &Options={}, ArrayRef< WeakVH > LoopHeaders={})
bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...