43#define DEBUG_TYPE "win-eh-prepare"
48 "Clone multicolor basic blocks but do not demote cross scopes"),
53 cl::desc(
"Do not remove implausible terminators or other similar cleanups"),
58class WinEHPrepareImpl {
73 bool demotePHIsOnFunclets(
Function &
F,
bool DemoteCatchSwitchPHIOnly);
75 bool removeImplausibleInstructions(
Function &
F);
76 bool cleanupPreparedFunclets(
Function &
F);
80 bool DemoteCatchSwitchPHIOnly =
false;
94 WinEHPrepare() : FunctionPass(ID) {}
96 StringRef getPassName()
const override {
97 return "Windows exception handling preparation";
101 return WinEHPrepareImpl().runOnFunction(Fn);
109 bool Changed = WinEHPrepareImpl().runOnFunction(
F);
113char WinEHPrepare::ID = 0;
119bool WinEHPrepareImpl::runOnFunction(
Function &Fn) {
136 return prepareExplicitEH(Fn);
149 int TryHigh,
int CatchHigh,
176 for (
const User *U : CleanupPad->
users())
178 return CRI->getUnwindDest();
191 auto &BBColors = BlockColors[&BB];
192 assert(BBColors.size() == 1 &&
"multi-color BB not removed by preparation");
200 FuncletUnwindDest =
nullptr;
202 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
210 if (FuncletUnwindDest == InvokeUnwindDest) {
213 BaseState = BaseStateI->second;
216 if (BaseState != -1) {
239 struct WorkItem *WI =
new WorkItem(BB, State);
242 while (!WorkList.
empty()) {
245 int State = WI->State;
248 if (!Inserted && StateIt->second <= State)
255 StateIt->second = State;
279 WI =
new WorkItem(SuccBB, State);
301 struct WorkItem *WI =
new WorkItem(BB, State);
304 while (!WorkList.
empty()) {
307 int State = WI->State;
323 if (!
Filter || !
Filter->getName().starts_with(
"__IsLocalUnwind"))
343 WI =
new WorkItem(SuccBB, State);
357 if (CatchSwitch->getParentPad() != ParentPad)
363 if (CleanupPad->getParentPad() != ParentPad)
365 return CleanupPad->getParent();
379 "shouldn't revist catch funclets!");
382 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
390 CatchSwitch->getParentPad())))
396 int TryHigh = CatchLow - 1;
402 bool IsPreOrder =
Mod->getTargetTriple().isArch64Bit();
405 unsigned TBMEIdx = FuncInfo.
TryBlockMap.size() - 1;
407 for (
const auto *CatchPad : Handlers) {
410 for (
const User *U : CatchPad->
users()) {
413 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
414 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
422 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
430 FuncInfo.
TryBlockMap[TBMEIdx].CatchHigh = CatchHigh;
444 auto [It, Inserted] = FuncInfo.
EHPadStateMap.try_emplace(CleanupPad);
449 It->second = CleanupState;
450 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
454 CleanupPad->getParentPad()))) {
459 for (
const User *U : CleanupPad->
users()) {
461 if (UserI->isEHPad())
463 "contain exceptional actions");
472 Entry.IsFinally =
false;
474 Entry.Handler = Handler;
483 Entry.IsFinally =
true;
484 Entry.Filter =
nullptr;
485 Entry.Handler = Handler;
501 "shouldn't revist catch funclets!");
505 assert(CatchSwitch->getNumHandlers() == 1 &&
506 "SEH doesn't have multiple handlers per __try");
507 const auto *CatchPad =
514 "unexpected filter value");
521 << CatchPadBB->
getName() <<
'\n');
524 CatchSwitch->getParentPad())))
530 for (
const User *U : CatchPad->
users()) {
533 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
534 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
542 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
551 auto [It, Inserted] = FuncInfo.
EHPadStateMap.try_emplace(CleanupPad);
556 It->second = CleanupState;
557 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
564 for (
const User *U : CleanupPad->
users()) {
566 if (UserI->isEHPad())
568 "contain exceptional actions");
576 CatchSwitch->unwindsToCaller();
594 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
618 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
638 Entry.TryParentState = TryParentState;
639 Entry.Handler = Handler;
640 Entry.HandlerType = HandlerType;
641 Entry.TypeToken = TypeToken;
678 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
679 const Value *ParentPad;
681 ParentPad = CPI->getParentPad();
683 ParentPad = CSI->getParentPad();
696 while (!Worklist.
empty()) {
698 int HandlerParentState;
699 std::tie(Pad, HandlerParentState) = Worklist.
pop_back_val();
720 int CatchState = -1, FollowerState = -1;
738 FollowerState = CatchState;
741 assert(CatchSwitch->getNumHandlers());
761 if (Entry.TryParentState != -1)
764 UnwindDest =
Catch->getCatchSwitch()->getUnwindDest();
767 UnwindDest =
nullptr;
772 UnwindDest = CleanupRet->getUnwindDest();
779 UserUnwindDest = Invoke->getUnwindDest();
781 UserUnwindDest = CatchSwitch->getUnwindDest();
784 int UserUnwindState =
786 if (UserUnwindState != -1)
801 const Value *UserUnwindParent;
803 UserUnwindParent = CSI->getParentPad();
810 if (UserUnwindParent ==
Cleanup)
814 UnwindDest = UserUnwindDest;
833 UnwindDestState = -1;
839 Entry.TryParentState = UnwindDestState;
846void WinEHPrepareImpl::colorFunclets(
Function &
F) {
853 FuncletBlocks[Color].push_back(&BB);
857bool WinEHPrepareImpl::demotePHIsOnFunclets(
Function &
F,
858 bool DemoteCatchSwitchPHIOnly) {
876 if (DemoteCatchSwitchPHIOnly) {
878 bool HasIncomingCatchSwitchBB =
false;
879 for (
unsigned I = 0,
E = PN->getNumIncomingValues();
I <
E; ++
I) {
881 PN->getIncomingBlock(
I)->getFirstNonPHIIt())) {
882 HasIncomingCatchSwitchBB =
true;
886 if (!IsCatchSwitchBB && !HasIncomingCatchSwitchBB)
894 insertPHIStores(PN, SpillSlot);
900 for (
auto *PN : PHINodes) {
903 PN->eraseFromParent();
909bool WinEHPrepareImpl::cloneCommonBlocks(
Function &
F) {
915 for (
auto &Funclets : FuncletBlocks) {
917 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
919 if (FuncletPadBB == &
F.getEntryBlock())
924 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
929 size_t NumColorsForBB = ColorsForBB.
size();
930 if (NumColorsForBB == 1)
934 dbgs() <<
" Cloning block \'" << BB->getName()
935 <<
"\' for funclet \'" << FuncletPadBB->
getName()
949 Orig2Clone.emplace_back(BB, CBB);
953 if (Orig2Clone.empty())
960 for (
auto &BBMapping : Orig2Clone) {
964 BlocksInFunclet.push_back(NewBlock);
966 assert(NewColors.
empty() &&
"A new block should only have one color!");
970 dbgs() <<
" Assigned color \'" << FuncletPadBB->
getName()
971 <<
"\' to block \'" << NewBlock->
getName()
979 dbgs() <<
" Removed color \'" << FuncletPadBB->
getName()
980 <<
"\' from block \'" << OldBlock->
getName()
995 for (
auto &BBMapping : Orig2Clone) {
999 FixupCatchrets.
clear();
1002 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
1006 CatchRet->setSuccessor(NewBlock);
1009 auto UpdatePHIOnClonedBlock = [&](
PHINode *PN,
bool IsForOldBlock) {
1013 bool EdgeTargetsFunclet;
1016 EdgeTargetsFunclet =
1017 (CRI->getCatchSwitchParentPad() == FuncletToken);
1019 ColorVector &IncomingColors = BlockColors[IncomingBlock];
1020 assert(!IncomingColors.
empty() &&
"Block not colored!");
1022 (IncomingColors.
size() == 1 ||
1024 "Cloning should leave this funclet's blocks monochromatic");
1025 EdgeTargetsFunclet = (IncomingColors.
front() == FuncletPadBB);
1027 return IsForOldBlock == EdgeTargetsFunclet;
1032 for (
auto &BBMapping : Orig2Clone) {
1036 UpdatePHIOnClonedBlock(&OldPN,
true);
1039 UpdatePHIOnClonedBlock(&NewPN,
false);
1045 for (
auto &BBMapping : Orig2Clone) {
1049 for (
PHINode &SuccPN : SuccBB->phis()) {
1052 int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock);
1053 if (OldBlockIdx == -1)
1055 Value *
IV = SuccPN.getIncomingValue(OldBlockIdx);
1060 if (
I != VMap.
end())
1064 SuccPN.addIncoming(
IV, NewBlock);
1086 ColorVector &ColorsForUserBB = BlockColors[UserBB];
1088 if (ColorsForUserBB.
size() > 1 ||
1089 *ColorsForUserBB.
begin() != FuncletPadBB)
1095 if (UsesToRename.
empty())
1102 SSAUpdate.
Initialize(OldI->getType(), OldI->getName());
1106 while (!UsesToRename.
empty())
1114bool WinEHPrepareImpl::removeImplausibleInstructions(
Function &
F) {
1118 for (
auto &Funclet : FuncletBlocks) {
1120 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
1132 Value *FuncletBundleOperand =
nullptr;
1134 FuncletBundleOperand = BU->Inputs.front();
1136 if (FuncletBundleOperand == FuncletPad)
1142 if (CB->isInlineAsm() ||
1143 (CalledFn && CalledFn->isIntrinsic() && CB->doesNotThrow()))
1154 std::prev(BB->getTerminator()->getIterator());
1170 bool IsUnreachableCatchret =
false;
1172 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
1174 bool IsUnreachableCleanupret =
false;
1176 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
1177 if (IsUnreachableRet || IsUnreachableCatchret ||
1178 IsUnreachableCleanupret) {
1196bool WinEHPrepareImpl::cleanupPreparedFunclets(
Function &
F) {
1215void WinEHPrepareImpl::verifyPreparedFunclets(
Function &
F) {
1217 size_t NumColors = BlockColors[&BB].size();
1218 assert(NumColors == 1 &&
"Expected monochromatic BB!");
1224 "EH Pad still has a PHI!");
1229bool WinEHPrepareImpl::prepareExplicitEH(
Function &
F) {
1241 Changed |= demotePHIsOnFunclets(
F, DemoteCatchSwitchPHIOnly);
1245 Changed |= removeImplausibleInstructions(
F);
1248 Changed |= cleanupPreparedFunclets(
F);
1271 F.getEntryBlock().begin());
1284 if (
isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
1289 replaceUseWithLoad(PN, U, SpillSlot, Loads,
F);
1298void WinEHPrepareImpl::insertPHIStores(
PHINode *OriginalPHI,
1306 while (!Worklist.
empty()) {
1329 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1335void WinEHPrepareImpl::insertPHIStore(
1341 Worklist.
push_back({PredBlock, PredVal});
1349void WinEHPrepareImpl::replaceUseWithLoad(
1354 SpillSlot =
new AllocaInst(
V->getType(),
DL->getAllocaAddrSpace(),
nullptr,
1355 Twine(
V->getName(),
".wineh.spillslot"),
1356 F.getEntryBlock().begin());
1369 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
1370 if (
auto *CatchRet =
1393 CatchRet->removeFromParent();
1394 CatchRet->insertInto(IncomingBlock, IncomingBlock->
end());
1397 CatchRet->setSuccessor(NewBlock);
1402 ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
1403 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
1404 ColorsForNewBlock = ColorsForPHIBlock;
1405 for (
BasicBlock *FuncletPad : ColorsForPHIBlock)
1406 FuncletBlocks[FuncletPad].
push_back(NewBlock);
1408 IncomingBlock = NewBlock;
1414 V->getType(), SpillSlot,
Twine(
V->getName(),
".wineh.reload"),
1421 Twine(
V->getName(),
".wineh.reload"),
1422 false, UsingInst->getIterator());
1431 "should get invoke with precomputed state");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
ManagedStatic< HTTPClientCleanup > Cleanup
Module.h This file contains the declarations for the Module class.
This file implements a map that provides insertion order iteration.
uint64_t IntrinsicInst * II
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
static cl::opt< bool > DisableDemotion("disable-demotion", cl::Hidden, cl::desc("Clone multicolor basic blocks but do not demote cross scopes"), cl::init(false))
static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState, const BasicBlock *BB)
static void calculateStateNumbersForInvokes(const Function *Fn, WinEHFuncInfo &FuncInfo)
static BasicBlock * getCleanupRetUnwindDest(const CleanupPadInst *CleanupPad)
static cl::opt< bool > DisableCleanups("disable-cleanups", cl::Hidden, cl::desc("Do not remove implausible terminators or other similar cleanups"), cl::init(false))
static int addSEHFinally(WinEHFuncInfo &FuncInfo, int ParentState, const BasicBlock *Handler)
static const BasicBlock * getEHPadFromPredecessor(const BasicBlock *BB, Value *ParentPad)
static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int HandlerParentState, int TryParentState, ClrHandlerType HandlerType, uint32_t TypeToken, const BasicBlock *Handler)
static void calculateCXXStateNumbers(WinEHFuncInfo &FuncInfo, const Instruction *FirstNonPHI, int ParentState)
static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow, int TryHigh, int CatchHigh, ArrayRef< const CatchPadInst * > Handlers)
static bool isTopLevelPadForMSVC(const Instruction *EHPad)
static int addSEHExcept(WinEHFuncInfo &FuncInfo, int ParentState, const Function *Filter, const BasicBlock *Handler)
static const uint32_t IV[8]
an instruction to allocate memory on the stack
Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
InstListType::const_iterator const_iterator
const Instruction & front() const
LLVM_ABI void insertInto(Function *Parent, BasicBlock *InsertBefore=nullptr)
Insert unlinked basic block into a function.
InstListType::iterator iterator
Instruction iterators...
bool isEHPad() const
Return true if this basic block is an exception handling block.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
static LLVM_ABI ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
This is an important base class in LLVM.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
const Constant * stripPointerCasts() const
A parsed version of the target data layout string in and methods for querying it.
FunctionPass class - This class is used to implement most global optimizations.
const BasicBlock & getEntryBlock() const
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
bool hasPersonalityFn() const
Check whether this function has a personality function.
Constant * getPersonalityFn() const
Get the personality function associated with this function.
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
bool isTerminator() const
iterator_range< user_iterator > users()
LLVM_ABI InstListType::iterator insertInto(BasicBlock *ParentBB, InstListType::iterator It)
Inserts an unlinked instruction into ParentBB at position It and returns the iterator of the inserted...
An instruction for reading from memory.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
This class implements a map that also provides access to all stored values in a deterministic order.
A Module instance is used to store all the information related to an LLVM module.
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
LLVM_ABI void removeIncomingValueIf(function_ref< bool(unsigned)> Predicate, bool DeletePHIIfEmpty=true)
Remove all incoming values for which the predicate returns true.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Helper class for SSA formation on a set of values defined in multiple blocks.
LLVM_ABI void RewriteUseAfterInsertions(Use &U)
Rewrite a use like RewriteUse but handling in-block definitions.
LLVM_ABI void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
LLVM_ABI void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
void push_back(EltTy NewVal)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Unconditional Branch instruction.
void setSuccessor(BasicBlock *NewSucc)
A Use represents the edge between a Value definition and its users.
std::pair< const Value *, WeakTrackingVH > value_type
iterator find(const KeyT &Val)
ValueMapIteratorImpl< MapT, const Value *, false > iterator
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI FunctionPass * createWinEHPass()
createWinEHPass - Prepares personality functions used by MSVC on Windows, in addition to the Itanium ...
LLVM_ABI 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...
LLVM_ABI BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, bool MapAtoms=true)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
auto successors(const MachineBasicBlock *BB)
@ Load
The value being inserted comes from a load (InsertElement only).
LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI 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...
LLVM_ABI void calculateWinCXXEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which describes the state number...
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool FoldInstsToUnreachable=true)
Remove all blocks that can not be reached from the function's entry.
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
auto reverse(ContainerTy &&C)
@ RF_IgnoreMissingLocals
If this flag is set, the remapper ignores missing function-local entries (Argument,...
@ RF_NoModuleLevelChanges
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ABI Instruction * removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU=nullptr)
Replace 'BB's terminator with one that does not have an unwind successor block.
LLVM_ABI void calculateSEHStateForAsynchEH(const BasicBlock *BB, int State, WinEHFuncInfo &FuncInfo)
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI unsigned changeToUnreachable(Instruction *I, 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...
LLVM_ABI void calculateCXXStateForAsynchEH(const BasicBlock *BB, int State, WinEHFuncInfo &FuncInfo)
bool isFuncletEHPersonality(EHPersonality Pers)
Returns true if this is a personality function that invokes handler funclets (which must return to it...
LLVM_ABI void calculateSEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
LLVM_ABI bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false, DominatorTree *DT=nullptr)
Attempts to merge a block into its predecessor, if possible.
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
TinyPtrVector< BasicBlock * > ColorVector
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI 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...
LLVM_ABI void calculateClrEHStateNumbers(const Function *Fn, WinEHFuncInfo &FuncInfo)
WorkItem(const BasicBlock *BB, int St)
int HandlerParentState
Outer handler enclosing this entry's handler.
Similar to CxxUnwindMapEntry, but supports SEH filters.
int ToState
If unwinding continues through this handler, transition to the handler at this state.
LLVM_ABI void addIPToStateRange(const InvokeInst *II, MCSymbol *InvokeBegin, MCSymbol *InvokeEnd)
SmallVector< SEHUnwindMapEntry, 4 > SEHUnwindMap
SmallVector< ClrEHUnwindMapEntry, 4 > ClrEHUnwindMap
DenseMap< const FuncletPadInst *, int > FuncletBaseStateMap
DenseMap< const BasicBlock *, int > BlockToStateMap
DenseMap< const InvokeInst *, int > InvokeStateMap
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
DenseMap< const Instruction *, int > EHPadStateMap
DenseMap< MCSymbol *, std::pair< int, MCSymbol * > > LabelToStateMap
SmallVector< CxxUnwindMapEntry, 4 > CxxUnwindMap
int getLastStateNumber() const
GlobalVariable * TypeDescriptor
union llvm::WinEHHandlerType::@246205307012256373115155017221207221353102114334 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
const AllocaInst * Alloca
SmallVector< WinEHHandlerType, 1 > HandlerArray