41 #define DEBUG_TYPE "winehprepare" 46 "Clone multicolor basic blocks but do not demote cross scopes"),
51 cl::desc(
"Do not remove implausible terminators or other similar cleanups"),
63 WinEHPrepare(
bool DemoteCatchSwitchPHIOnly =
false)
64 :
FunctionPass(
ID), DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
68 bool doFinalization(
Module &M)
override;
73 return "Windows exception handling preparation";
87 void demotePHIsOnFunclets(
Function &
F,
bool DemoteCatchSwitchPHIOnly);
89 void removeImplausibleInstructions(
Function &
F);
90 void cleanupPreparedFunclets(
Function &
F);
93 bool DemoteCatchSwitchPHIOnly;
110 return new WinEHPrepare(DemoteCatchSwitchPHIOnly);
125 return prepareExplicitEH(Fn);
128 bool WinEHPrepare::doFinalization(
Module &M) {
return false; }
130 void WinEHPrepare::getAnalysisUsage(
AnalysisUsage &AU)
const {}
142 int TryHigh,
int CatchHigh,
151 Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
156 HT.
Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
159 dyn_cast<AllocaInst>(CPI->getArgOperand(2)->stripPointerCasts()))
169 for (
const User *U : CleanupPad->
users())
170 if (
const auto *CRI = dyn_cast<CleanupReturnInst>(U))
171 return CRI->getUnwindDest();
177 auto *
F = const_cast<Function *>(Fn);
180 auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
184 auto &BBColors = BlockColors[&BB];
185 assert(BBColors.size() == 1 &&
"multi-color BB not removed by preparation");
190 dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHI());
193 FuncletUnwindDest =
nullptr;
194 else if (
auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad))
195 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
196 else if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(FuncletPad))
201 BasicBlock *InvokeUnwindDest = II->getUnwindDest();
203 if (FuncletUnwindDest == InvokeUnwindDest) {
206 BaseState = BaseStateI->second;
209 if (BaseState != -1) {
224 if (isa<InvokeInst>(TI))
226 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
227 if (CatchSwitch->getParentPad() != ParentPad)
232 auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
233 if (CleanupPad->getParentPad() != ParentPad)
235 return CleanupPad->getParent();
247 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
249 "shouldn't revist catch funclets!");
252 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
253 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
260 CatchSwitch->getParentPad())))
266 int TryHigh = CatchLow - 1;
272 bool IsPreOrder =
Triple(
Mod->getTargetTriple()).isArch64Bit();
275 unsigned TBMEIdx = FuncInfo.
TryBlockMap.size() - 1;
277 for (
const auto *CatchPad : Handlers) {
279 for (
const User *U : CatchPad->
users()) {
280 const auto *UserI = cast<Instruction>(U);
281 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
282 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
283 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
286 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
291 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
299 FuncInfo.
TryBlockMap[TBMEIdx].CatchHigh = CatchHigh;
309 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
318 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB " 322 CleanupPad->getParentPad()))) {
327 for (
const User *U : CleanupPad->
users()) {
328 const auto *UserI = cast<Instruction>(U);
329 if (UserI->isEHPad())
331 "contain exceptional actions");
339 Entry.ToState = ParentState;
340 Entry.IsFinally =
false;
342 Entry.Handler = Handler;
350 Entry.ToState = ParentState;
351 Entry.IsFinally =
true;
352 Entry.Filter =
nullptr;
353 Entry.Handler = Handler;
367 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
369 "shouldn't revist catch funclets!");
373 assert(CatchSwitch->getNumHandlers() == 1 &&
374 "SEH doesn't have multiple handlers per __try");
375 const auto *CatchPad =
376 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHI());
379 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
382 "unexpected filter value");
388 << CatchPadBB->getName() <<
'\n');
391 CatchSwitch->getParentPad())))
397 for (
const User *U : CatchPad->
users()) {
398 const auto *UserI = cast<Instruction>(U);
399 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
400 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
401 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
404 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
409 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
414 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
423 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB " 430 for (
const User *U : CleanupPad->
users()) {
431 const auto *UserI = cast<Instruction>(U);
432 if (UserI->isEHPad())
434 "contain exceptional actions");
440 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
441 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
442 CatchSwitch->unwindsToCaller();
443 if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
444 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
446 if (isa<CatchPadInst>(EHPad))
460 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
478 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
491 Entry.HandlerParentState = HandlerParentState;
492 Entry.TryParentState = TryParentState;
493 Entry.Handler = Handler;
494 Entry.HandlerType = HandlerType;
495 Entry.TypeToken = TypeToken;
532 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
533 const Value *ParentPad;
534 if (
const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI))
535 ParentPad = CPI->getParentPad();
536 else if (
const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI))
537 ParentPad = CSI->getParentPad();
540 if (isa<ConstantTokenNone>(ParentPad))
550 while (!Worklist.
empty()) {
552 int HandlerParentState;
553 std::tie(Pad, HandlerParentState) = Worklist.
pop_back_val();
555 if (
const auto *Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
565 if (
const auto *
I = dyn_cast<Instruction>(U))
573 const auto *CatchSwitch = cast<CatchSwitchInst>(Pad);
574 int CatchState = -1, FollowerState = -1;
576 for (
auto CBI = CatchBlocks.rbegin(), CBE = CatchBlocks.rend();
577 CBI != CBE; ++CBI, FollowerState = CatchState) {
582 uint32_t TypeToken = static_cast<uint32_t>(
583 cast<ConstantInt>(
Catch->getArgOperand(0))->getZExtValue());
589 if (
const auto *
I = dyn_cast<Instruction>(U))
596 assert(CatchSwitch->getNumHandlers());
606 Entry != End; ++Entry) {
608 Entry->Handler.get<
const BasicBlock *>()->getFirstNonPHI();
612 if (
const auto *
Catch = dyn_cast<CatchPadInst>(Pad)) {
618 if (Entry->TryParentState != -1)
621 UnwindDest =
Catch->getCatchSwitch()->getUnwindDest();
623 const auto *Cleanup = cast<CleanupPadInst>(Pad);
624 UnwindDest =
nullptr;
626 if (
auto *CleanupRet = dyn_cast<CleanupReturnInst>(U)) {
629 UnwindDest = CleanupRet->getUnwindDest();
635 if (
auto *Invoke = dyn_cast<InvokeInst>(U)) {
636 UserUnwindDest = Invoke->getUnwindDest();
637 }
else if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) {
638 UserUnwindDest = CatchSwitch->getUnwindDest();
639 }
else if (
auto *ChildCleanup = dyn_cast<CleanupPadInst>(U)) {
641 int UserUnwindState =
643 if (UserUnwindState != -1)
658 const Value *UserUnwindParent;
659 if (
auto *CSI = dyn_cast<CatchSwitchInst>(UserUnwindPad))
660 UserUnwindParent = CSI->getParentPad();
663 cast<CleanupPadInst>(UserUnwindPad)->getParentPad();
667 if (UserUnwindParent == Cleanup)
671 UnwindDest = UserUnwindDest;
690 UnwindDestState = -1;
695 Entry->TryParentState = UnwindDestState;
702 void WinEHPrepare::colorFunclets(
Function &
F) {
713 void WinEHPrepare::demotePHIsOnFunclets(
Function &
F,
714 bool DemoteCatchSwitchPHIOnly) {
721 if (DemoteCatchSwitchPHIOnly && !isa<CatchSwitchInst>(BB->
getFirstNonPHI()))
726 auto *PN = dyn_cast<PHINode>(
I);
733 insertPHIStores(PN, SpillSlot);
739 for (
auto *PN : PHINodes) {
742 PN->eraseFromParent();
746 void WinEHPrepare::cloneCommonBlocks(
Function &
F) {
750 for (
auto &Funclets : FuncletBlocks) {
752 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
754 if (FuncletPadBB == &
F.getEntryBlock())
759 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
764 size_t NumColorsForBB = ColorsForBB.
size();
765 if (NumColorsForBB == 1)
770 <<
"\' for funclet \'" << FuncletPadBB->
getName()
784 Orig2Clone.emplace_back(BB, CBB);
788 if (Orig2Clone.empty())
793 for (
auto &BBMapping : Orig2Clone) {
797 BlocksInFunclet.push_back(NewBlock);
799 assert(NewColors.
empty() &&
"A new block should only have one color!");
803 dbgs() <<
" Assigned color \'" << FuncletPadBB->
getName()
804 <<
"\' to block \'" << NewBlock->
getName()
812 dbgs() <<
" Removed color \'" << FuncletPadBB->
getName()
813 <<
"\' from block \'" << OldBlock->
getName()
828 for (
auto &BBMapping : Orig2Clone) {
832 FixupCatchrets.
clear();
834 if (
auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
835 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
839 CatchRet->setSuccessor(NewBlock);
842 auto UpdatePHIOnClonedBlock = [&](
PHINode *PN,
bool IsForOldBlock) {
844 for (
unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
847 bool EdgeTargetsFunclet;
850 EdgeTargetsFunclet = (CRI->getCatchSwitchParentPad() == FuncletToken);
852 ColorVector &IncomingColors = BlockColors[IncomingBlock];
853 assert(!IncomingColors.
empty() &&
"Block not colored!");
857 return Color != FuncletPadBB;
859 "Cloning should leave this funclet's blocks monochromatic");
860 EdgeTargetsFunclet = (IncomingColors.
front() == FuncletPadBB);
862 if (IsForOldBlock != EdgeTargetsFunclet)
871 for (
auto &BBMapping : Orig2Clone) {
875 UpdatePHIOnClonedBlock(&OldPN,
true);
878 UpdatePHIOnClonedBlock(&NewPN,
false);
884 for (
auto &BBMapping : Orig2Clone) {
888 for (
PHINode &SuccPN : SuccBB->phis()) {
891 int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock);
892 if (OldBlockIdx == -1)
894 Value *IV = SuccPN.getIncomingValue(OldBlockIdx);
897 if (
auto *Inst = dyn_cast<Instruction>(IV)) {
903 SuccPN.addIncoming(IV, NewBlock);
916 auto *OldI = dyn_cast<Instruction>(const_cast<Value *>(VT.first));
919 auto *NewI = cast<Instruction>(VT.second);
923 Instruction *UserI = cast<Instruction>(U.getUser());
925 ColorVector &ColorsForUserBB = BlockColors[UserBB];
927 if (ColorsForUserBB.
size() > 1 ||
928 *ColorsForUserBB.
begin() != FuncletPadBB)
934 if (UsesToRename.
empty())
941 SSAUpdate.
Initialize(OldI->getType(), OldI->getName());
945 while (!UsesToRename.
empty())
951 void WinEHPrepare::removeImplausibleInstructions(
Function &
F) {
953 for (
auto &Funclet : FuncletBlocks) {
955 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
957 auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
958 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
959 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
963 auto *CB = dyn_cast<CallBase>(&
I);
967 Value *FuncletBundleOperand =
nullptr;
969 FuncletBundleOperand = BU->Inputs.front();
971 if (FuncletBundleOperand == FuncletPad)
976 dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
977 if (CalledFn && ((CalledFn->isIntrinsic() && CB->doesNotThrow()) ||
982 if (isa<InvokeInst>(CB)) {
987 std::prev(BB->getTerminator()->getIterator());
988 auto *CI = cast<CallInst>(&*CallI);
1001 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
1003 bool IsUnreachableCatchret =
false;
1004 if (
auto *CRI = dyn_cast<CatchReturnInst>(TI))
1005 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
1007 bool IsUnreachableCleanupret =
false;
1008 if (
auto *CRI = dyn_cast<CleanupReturnInst>(TI))
1009 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
1010 if (IsUnreachableRet || IsUnreachableCatchret ||
1011 IsUnreachableCleanupret) {
1013 }
else if (isa<InvokeInst>(TI)) {
1025 void WinEHPrepare::cleanupPreparedFunclets(
Function &
F) {
1041 void WinEHPrepare::verifyPreparedFunclets(
Function &
F) {
1043 size_t NumColors = BlockColors[&BB].size();
1044 assert(NumColors == 1 &&
"Expected monochromatic BB!");
1050 "EH Pad still has a PHI!");
1055 bool WinEHPrepare::prepareExplicitEH(
Function &
F) {
1064 cloneCommonBlocks(
F);
1067 demotePHIsOnFunclets(
F, DemoteCatchSwitchPHIOnly ||
1072 removeImplausibleInstructions(
F);
1075 cleanupPreparedFunclets(
F);
1083 BlockColors.clear();
1084 FuncletBlocks.clear();
1101 &
F.getEntryBlock().front());
1115 auto *UsingInst = cast<Instruction>(U.
getUser());
1116 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
1121 replaceUseWithLoad(PN, U, SpillSlot, Loads,
F);
1130 void WinEHPrepare::insertPHIStores(
PHINode *OriginalPHI,
1138 while (!Worklist.
empty()) {
1143 PHINode *PN = dyn_cast<PHINode>(InVal);
1152 if (isa<UndefValue>(PredVal))
1161 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1167 void WinEHPrepare::insertPHIStore(
1173 Worklist.
push_back({PredBlock, PredVal});
1188 &
F.getEntryBlock().front());
1190 auto *UsingInst = cast<Instruction>(U.
getUser());
1191 if (
auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1201 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
1202 if (
auto *CatchRet =
1203 dyn_cast<CatchReturnInst>(IncomingBlock->
getTerminator())) {
1225 CatchRet->removeFromParent();
1229 CatchRet->setSuccessor(NewBlock);
1234 ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
1235 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
1236 ColorsForNewBlock = ColorsForPHIBlock;
1237 for (
BasicBlock *FuncletPad : ColorsForPHIBlock)
1238 FuncletBlocks[FuncletPad].
push_back(NewBlock);
1240 IncomingBlock = NewBlock;
1263 "should get invoke with precomputed state");
A parsed version of the target data layout string in and methods for querying it.
reference emplace_back(ArgTypes &&... Args)
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
DenseMap< MCSymbol *, std::pair< int, MCSymbol * > > LabelToStateMap
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
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.
LLVM_NODISCARD bool empty() const
SmallVector< SEHUnwindMapEntry, 4 > SEHUnwindMap
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.
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))
iterator begin()
Instruction iterator methods.
bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false)
Attempts to merge a block into its predecessor, if possible.
#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.
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.
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))
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
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.
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)
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
const Constant * stripPointerCasts() const
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.
Triple - Helper class for working with autoconf configuration names.
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...
User * getUser() const
Returns the User that contains this Use.
SmallVector< CxxUnwindMapEntry, 4 > CxxUnwindMap
const InstListType & getInstList() const
Return the underlying instruction list container.
Iterator for intrusive lists based on ilist_node.
Color
A "color", which is either even or odd.
union llvm::WinEHHandlerType::@216 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
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)
LLVM_NODISCARD T pop_back_val()
static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow, int TryHigh, int CatchHigh, ArrayRef< const CatchPadInst * > Handlers)
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.
The access may modify the value stored in memory.
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,...
void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
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 verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
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.
bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void erase_value(Container &C, ValueType V)
Wrapper function to remove a value from a container:
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
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)
unsigned changeToUnreachable(Instruction *I, bool UseLLVMTrap, bool PreserveLCSSA=false, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Insert an unreachable instruction before the specified instruction, making it and the rest of the cod...
INITIALIZE_PASS(WinEHPrepare, DEBUG_TYPE, "Prepare Windows exceptions", false, false) FunctionPass *llvm
const BasicBlock * getParent() const
an instruction to allocate memory on the stack
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL