39 #define DEBUG_TYPE "winehprepare" 44 "Clone multicolor basic blocks but do not demote cross scopes"),
49 cl::desc(
"Do not remove implausible terminators or other similar cleanups"),
61 WinEHPrepare(
bool DemoteCatchSwitchPHIOnly =
false)
62 :
FunctionPass(ID), DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
66 bool doFinalization(
Module &M)
override;
71 return "Windows exception handling preparation";
85 void demotePHIsOnFunclets(
Function &
F,
bool DemoteCatchSwitchPHIOnly);
87 void removeImplausibleInstructions(
Function &
F);
88 void cleanupPreparedFunclets(
Function &
F);
91 bool DemoteCatchSwitchPHIOnly;
108 return new WinEHPrepare(DemoteCatchSwitchPHIOnly);
123 return prepareExplicitEH(Fn);
126 bool WinEHPrepare::doFinalization(
Module &M) {
return false; }
128 void WinEHPrepare::getAnalysisUsage(
AnalysisUsage &AU)
const {}
140 int TryHigh,
int CatchHigh,
149 Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
154 HT.
Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
157 dyn_cast<AllocaInst>(CPI->getArgOperand(2)->stripPointerCasts()))
167 for (
const User *U : CleanupPad->
users())
168 if (
const auto *CRI = dyn_cast<CleanupReturnInst>(U))
169 return CRI->getUnwindDest();
182 auto &BBColors = BlockColors[&BB];
183 assert(BBColors.size() == 1 &&
"multi-color BB not removed by preparation");
191 FuncletUnwindDest =
nullptr;
192 else if (
auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad))
193 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
194 else if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(FuncletPad))
199 BasicBlock *InvokeUnwindDest = II->getUnwindDest();
201 if (FuncletUnwindDest == InvokeUnwindDest) {
204 BaseState = BaseStateI->second;
207 if (BaseState != -1) {
222 if (isa<InvokeInst>(TI))
224 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
225 if (CatchSwitch->getParentPad() != ParentPad)
230 auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
231 if (CleanupPad->getParentPad() != ParentPad)
233 return CleanupPad->getParent();
242 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
244 "shouldn't revist catch funclets!");
247 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
248 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
255 CatchSwitch->getParentPad())))
261 int TryHigh = CatchLow - 1;
262 for (
const auto *CatchPad : Handlers) {
264 for (
const User *U : CatchPad->
users()) {
265 const auto *UserI = cast<Instruction>(U);
266 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
267 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
268 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
271 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
276 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
289 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
298 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB " 302 CleanupPad->getParentPad()))) {
307 for (
const User *U : CleanupPad->
users()) {
308 const auto *UserI = cast<Instruction>(U);
309 if (UserI->isEHPad())
311 "contain exceptional actions");
344 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
346 "shouldn't revist catch funclets!");
350 assert(CatchSwitch->getNumHandlers() == 1 &&
351 "SEH doesn't have multiple handlers per __try");
352 const auto *CatchPad =
353 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHI());
356 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
359 "unexpected filter value");
360 int TryState =
addSEHExcept(FuncInfo, ParentState, Filter, CatchPadBB);
365 << CatchPadBB->getName() <<
'\n');
368 CatchSwitch->getParentPad())))
374 for (
const User *U : CatchPad->
users()) {
375 const auto *UserI = cast<Instruction>(U);
376 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
377 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
378 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
381 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
386 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
391 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
400 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB " 407 for (
const User *U : CleanupPad->
users()) {
408 const auto *UserI = cast<Instruction>(U);
409 if (UserI->isEHPad())
411 "contain exceptional actions");
417 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
418 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
419 CatchSwitch->unwindsToCaller();
420 if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
421 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
423 if (isa<CatchPadInst>(EHPad))
437 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
455 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
509 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
510 const Value *ParentPad;
511 if (
const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI))
512 ParentPad = CPI->getParentPad();
513 else if (
const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI))
514 ParentPad = CSI->getParentPad();
517 if (isa<ConstantTokenNone>(ParentPad))
527 while (!Worklist.
empty()) {
529 int HandlerParentState;
530 std::tie(Pad, HandlerParentState) = Worklist.
pop_back_val();
532 if (
const auto *Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
542 if (
const auto *
I = dyn_cast<Instruction>(U))
550 const auto *CatchSwitch = cast<CatchSwitchInst>(Pad);
551 int CatchState = -1, FollowerState = -1;
553 for (
auto CBI = CatchBlocks.rbegin(), CBE = CatchBlocks.rend();
554 CBI != CBE; ++CBI, FollowerState = CatchState) {
560 cast<ConstantInt>(
Catch->getArgOperand(0))->getZExtValue());
566 if (
const auto *
I = dyn_cast<Instruction>(U))
573 assert(CatchSwitch->getNumHandlers());
583 Entry != End; ++Entry) {
585 Entry->Handler.get<
const BasicBlock *>()->getFirstNonPHI();
589 if (
const auto *
Catch = dyn_cast<CatchPadInst>(Pad)) {
595 if (Entry->TryParentState != -1)
598 UnwindDest =
Catch->getCatchSwitch()->getUnwindDest();
600 const auto *Cleanup = cast<CleanupPadInst>(Pad);
601 UnwindDest =
nullptr;
603 if (
auto *CleanupRet = dyn_cast<CleanupReturnInst>(U)) {
606 UnwindDest = CleanupRet->getUnwindDest();
612 if (
auto *Invoke = dyn_cast<InvokeInst>(U)) {
613 UserUnwindDest = Invoke->getUnwindDest();
614 }
else if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) {
615 UserUnwindDest = CatchSwitch->getUnwindDest();
616 }
else if (
auto *ChildCleanup = dyn_cast<CleanupPadInst>(U)) {
618 int UserUnwindState =
620 if (UserUnwindState != -1)
635 const Value *UserUnwindParent;
636 if (
auto *CSI = dyn_cast<CatchSwitchInst>(UserUnwindPad))
637 UserUnwindParent = CSI->getParentPad();
644 if (UserUnwindParent == Cleanup)
648 UnwindDest = UserUnwindDest;
667 UnwindDestState = -1;
672 Entry->TryParentState = UnwindDestState;
679 void WinEHPrepare::colorFunclets(
Function &
F) {
690 void WinEHPrepare::demotePHIsOnFunclets(
Function &F,
691 bool DemoteCatchSwitchPHIOnly) {
698 if (DemoteCatchSwitchPHIOnly && !isa<CatchSwitchInst>(BB->
getFirstNonPHI()))
708 AllocaInst *SpillSlot = insertPHILoads(PN, F);
710 insertPHIStores(PN, SpillSlot);
716 for (
auto *PN : PHINodes) {
719 PN->eraseFromParent();
723 void WinEHPrepare::cloneCommonBlocks(
Function &F) {
727 for (
auto &Funclets : FuncletBlocks) {
729 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
736 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
741 size_t NumColorsForBB = ColorsForBB.
size();
742 if (NumColorsForBB == 1)
746 dbgs() <<
" Cloning block \'" << BB->getName()
747 <<
"\' for funclet \'" << FuncletPadBB->
getName()
755 CBB->insertInto(&F, BB->getNextNode());
761 Orig2Clone.emplace_back(BB, CBB);
765 if (Orig2Clone.empty())
770 for (
auto &BBMapping : Orig2Clone) {
774 BlocksInFunclet.push_back(NewBlock);
776 assert(NewColors.
empty() &&
"A new block should only have one color!");
780 dbgs() <<
" Assigned color \'" << FuncletPadBB->
getName()
781 <<
"\' to block \'" << NewBlock->
getName()
784 BlocksInFunclet.erase(
785 std::remove(BlocksInFunclet.begin(), BlocksInFunclet.end(), OldBlock),
786 BlocksInFunclet.end());
793 dbgs() <<
" Removed color \'" << FuncletPadBB->
getName()
794 <<
"\' from block \'" << OldBlock->
getName()
809 for (
auto &BBMapping : Orig2Clone) {
813 FixupCatchrets.
clear();
815 if (
auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
816 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
820 CatchRet->setSuccessor(NewBlock);
823 auto UpdatePHIOnClonedBlock = [&](
PHINode *PN,
bool IsForOldBlock) {
825 for (
unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
828 bool EdgeTargetsFunclet;
831 EdgeTargetsFunclet = (CRI->getCatchSwitchParentPad() == FuncletToken);
833 ColorVector &IncomingColors = BlockColors[IncomingBlock];
834 assert(!IncomingColors.
empty() &&
"Block not colored!");
838 return Color != FuncletPadBB;
840 "Cloning should leave this funclet's blocks monochromatic");
841 EdgeTargetsFunclet = (IncomingColors.
front() == FuncletPadBB);
843 if (IsForOldBlock != EdgeTargetsFunclet)
852 for (
auto &BBMapping : Orig2Clone) {
856 UpdatePHIOnClonedBlock(&OldPN,
true);
859 UpdatePHIOnClonedBlock(&NewPN,
false);
865 for (
auto &BBMapping : Orig2Clone) {
869 for (
PHINode &SuccPN : SuccBB->phis()) {
872 int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock);
873 if (OldBlockIdx == -1)
875 Value *IV = SuccPN.getIncomingValue(OldBlockIdx);
878 if (
auto *Inst = dyn_cast<Instruction>(IV)) {
884 SuccPN.addIncoming(IV, NewBlock);
900 auto *NewI = cast<Instruction>(VT.second);
904 Instruction *UserI = cast<Instruction>(U.getUser());
906 ColorVector &ColorsForUserBB = BlockColors[UserBB];
908 if (ColorsForUserBB.
size() > 1 ||
909 *ColorsForUserBB.
begin() != FuncletPadBB)
915 if (UsesToRename.
empty())
922 SSAUpdate.
Initialize(OldI->getType(), OldI->getName());
926 while (!UsesToRename.
empty())
932 void WinEHPrepare::removeImplausibleInstructions(
Function &F) {
934 for (
auto &Funclet : FuncletBlocks) {
936 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
939 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
940 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
948 Value *FuncletBundleOperand =
nullptr;
950 FuncletBundleOperand = BU->Inputs.front();
952 if (FuncletBundleOperand == FuncletPad)
958 if (CalledFn && ((CalledFn->isIntrinsic() && CS.
doesNotThrow()) ||
968 std::prev(BB->getTerminator()->getIterator());
969 auto *CI = cast<CallInst>(&*CallI);
982 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
984 bool IsUnreachableCatchret =
false;
985 if (
auto *CRI = dyn_cast<CatchReturnInst>(TI))
986 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
988 bool IsUnreachableCleanupret =
false;
989 if (
auto *CRI = dyn_cast<CleanupReturnInst>(TI))
990 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
991 if (IsUnreachableRet || IsUnreachableCatchret ||
992 IsUnreachableCleanupret) {
994 }
else if (isa<InvokeInst>(TI)) {
1006 void WinEHPrepare::cleanupPreparedFunclets(
Function &F) {
1022 void WinEHPrepare::verifyPreparedFunclets(
Function &F) {
1024 size_t NumColors = BlockColors[&BB].size();
1025 assert(NumColors == 1 &&
"Expected monochromatic BB!");
1031 "EH Pad still has a PHI!");
1036 bool WinEHPrepare::prepareExplicitEH(
Function &F) {
1045 cloneCommonBlocks(F);
1048 demotePHIsOnFunclets(F, DemoteCatchSwitchPHIOnly ||
1053 removeImplausibleInstructions(F);
1056 cleanupPreparedFunclets(F);
1064 BlockColors.clear();
1065 FuncletBlocks.clear();
1095 auto *UsingInst = cast<Instruction>(U.
getUser());
1096 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
1101 replaceUseWithLoad(PN, U, SpillSlot, Loads, F);
1110 void WinEHPrepare::insertPHIStores(
PHINode *OriginalPHI,
1118 while (!Worklist.
empty()) {
1132 if (isa<UndefValue>(PredVal))
1141 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1147 void WinEHPrepare::insertPHIStore(
1153 Worklist.push_back({PredBlock, PredVal});
1170 auto *UsingInst = cast<Instruction>(U.
getUser());
1171 if (
auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1181 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
1182 if (
auto *CatchRet =
1183 dyn_cast<CatchReturnInst>(IncomingBlock->
getTerminator())) {
1205 CatchRet->removeFromParent();
1209 CatchRet->setSuccessor(NewBlock);
1214 ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
1215 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
1216 ColorsForNewBlock = ColorsForPHIBlock;
1217 for (
BasicBlock *FuncletPad : ColorsForPHIBlock)
1218 FuncletBlocks[FuncletPad].
push_back(NewBlock);
1220 IncomingBlock = NewBlock;
1240 assert(InvokeStateMap.count(II) &&
1241 "should get invoke with precomputed state");
1242 LabelToStateMap[InvokeBegin] = std::make_pair(InvokeStateMap[II], InvokeEnd);
A parsed version of the target data layout string in and methods for querying it. ...
static Value * getParentPad(Value *EHPad)
iterator_range< use_iterator > uses()
SmallVector< WinEHHandlerType, 1 > HandlerArray
Helper class for SSA formation on a set of values defined in multiple blocks.
int getLastStateNumber() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions=false, const TargetLibraryInfo *TLI=nullptr, DomTreeUpdater *DTU=nullptr)
If a terminator instruction is predicated on a constant value, convert it into an unconditional branc...
A Module instance is used to store all the information related to an LLVM module. ...
bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr)
Attempts to merge a block into its predecessor, if possible.
SmallVector< SEHUnwindMapEntry, 4 > SEHUnwindMap
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
void push_back(const T &Elt)
void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value...
bool removeUnreachableBlocks(Function &F, LazyValueInfo *LVI=nullptr, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
DenseMap< const FuncletPadInst *, int > FuncletBaseStateMap
const AllocaInst * Alloca
bool isTerminator() const
This class implements a map that also provides access to all stored values in a deterministic order...
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr)
Scan the specified basic block and try to simplify any instructions in it and recursively delete dead...
An instruction for reading from memory.
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...
TinyPtrVector - This class is specialized for cases where there are normally 0 or 1 element in a vect...
static cl::opt< bool > DisableCleanups("disable-cleanups", cl::Hidden, cl::desc("Do not remove implausible terminators or other similar cleanups"), cl::init(false))
union llvm::WinEHHandlerType::@189 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
iterator begin()
Instruction iterator methods.
MBBOrBasicBlock Handler
Holds the __except or __finally basic block.
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Split the edge connecting specified block.
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
Value * removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty=true)
Remove an incoming value.
iterator erase(iterator I)
unsigned changeToUnreachable(Instruction *I, bool UseLLVMTrap, bool PreserveLCSSA=false, DomTreeUpdater *DTU=nullptr)
Insert an unreachable instruction before the specified instruction, making it and the rest of the cod...
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
void calculateSEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
A Use represents the edge between a Value definition and its users.
int TryParentState
Outer try region enclosing this entry's try region, treating later catches on same try as "outer"...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
static BasicBlock * getCleanupRetUnwindDest(const CleanupPadInst *CleanupPad)
static cl::opt< bool > DisableDemotion("disable-demotion", cl::Hidden, cl::desc("Clone multicolor basic blocks but do not demote cross scopes"), cl::init(false))
int ToState
If unwinding continues through this handler, transition to the handler at this state.
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch, catchpad/ret, and cleanuppad/ret.
ValTy * getCalledValue() const
Return the pointer to function that is being called.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
User * getUser() const LLVM_READONLY
Returns the User that contains this Use.
Type * getType() const
All values are typed, get the type of this value.
static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState, const BasicBlock *BB)
static cl::opt< bool > DemoteCatchSwitchPHIOnlyOpt("demote-catchswitch-only", cl::Hidden, cl::desc("Demote catchswitch BBs only (for wasm EH)"), cl::init(false))
static void calculateStateNumbersForInvokes(const Function *Fn, WinEHFuncInfo &FuncInfo)
iterator find(const KeyT &Val)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
An instruction for storing to memory.
bool hasPersonalityFn() const
Check whether this function has a personality function.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
use_iterator_impl< Use > use_iterator
Similar to CxxUnwindMapEntry, but supports SEH filters.
Optional< OperandBundleUse > getOperandBundle(StringRef Name) const
const BasicBlock & getEntryBlock() const
static bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
SmallVector< ClrEHUnwindMapEntry, 4 > ClrEHUnwindMap
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
static int addSEHExcept(WinEHFuncInfo &FuncInfo, int ParentState, const Function *Filter, const BasicBlock *Handler)
LLVM Basic Block Representation.
void push_back(EltTy NewVal)
void RewriteUseAfterInsertions(Use &U)
Rewrite a use like RewriteUse but handling in-block definitions.
Conditional or Unconditional Branch instruction.
std::pair< const Value *, WeakTrackingVH > value_type
This is an important base class in LLVM.
const Instruction & front() const
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
DenseMap< const Instruction *, int > EHPadStateMap
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
DenseMap< const InvokeInst *, int > InvokeStateMap
FunctionPass * createWinEHPass(bool DemoteCatchSwitchPHIOnly=false)
createWinEHPass - Prepares personality functions used by MSVC on Windows, in addition to the Itanium ...
void calculateClrEHStateNumbers(const Function *Fn, WinEHFuncInfo &FuncInfo)
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.
const Constant * stripPointerCasts() const
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs, and aliases.
static bool isTopLevelPadForMSVC(const Instruction *EHPad)
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isInvoke() const
Return true if a InvokeInst is enclosed.
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
void calculateWinCXXEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which describes the state number...
SmallVector< CxxUnwindMapEntry, 4 > CxxUnwindMap
const InstListType & getInstList() const
Return the underlying instruction list container.
const Function * Filter
Holds the filter expression function.
Iterator for intrusive lists based on ilist_node.
Color
A "color", which is either even or odd.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static void calculateCXXStateNumbers(WinEHFuncInfo &FuncInfo, const Instruction *FirstNonPHI, int ParentState)
int HandlerParentState
Outer handler enclosing this entry's handler.
LLVM_NODISCARD T pop_back_val()
void addIPToStateRange(const InvokeInst *II, MCSymbol *InvokeBegin, MCSymbol *InvokeEnd)
pred_range predecessors(BasicBlock *BB)
unsigned getNumIncomingValues() const
Return the number of incoming edges.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
void push_back(pointer val)
BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, DebugInfoFinder *DIFinder=nullptr)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
void removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU=nullptr)
Replace 'BB's terminator with one that does not have an unwind successor block.
iterator_range< user_iterator > users()
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM...
GlobalVariable * TypeDescriptor
If this flag is set, the remapper ignores missing function-local entries (Argument, Instruction, BasicBlock) that are not in the value map.
void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
void emplace_back(ArgTypes &&... Args)
LLVM_NODISCARD bool empty() const
static int addSEHFinally(WinEHFuncInfo &FuncInfo, int ParentState, const BasicBlock *Handler)
StringRef getName() const
Return a constant reference to the value's name.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
const Function * getParent() const
Return the enclosing method, or null if none.
bool doesNotThrow() const
Determine if the call cannot unwind.
bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
static ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
ClrHandlerType HandlerType
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isEHPad() const
Return true if this basic block is an exception handling block.
static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int HandlerParentState, int TryParentState, ClrHandlerType HandlerType, uint32_t TypeToken, const BasicBlock *Handler)
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.
succ_range successors(Instruction *I)
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
StringRef - Represent a constant reference to a string, i.e.
DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
static const BasicBlock * getEHPadFromPredecessor(const BasicBlock *BB, Value *ParentPad)
static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow, int TryHigh, int CatchHigh, ArrayRef< const CatchPadInst *> Handlers)
INITIALIZE_PASS(WinEHPrepare, DEBUG_TYPE, "Prepare Windows exceptions", false, false) FunctionPass *llvm
const BasicBlock * getParent() const
an instruction to allocate memory on the stack