45#define DEBUG_TYPE "win-eh-prepare"
50 "Clone multicolor basic blocks but do not demote cross scopes"),
55 cl::desc(
"Do not remove implausible terminators or other similar cleanups"),
60 switch (Personality) {
114class WinEHPrepareImpl {
119 void insertPHIStores(PHINode *OriginalPHI, AllocaInst *SpillSlot);
121 insertPHIStore(BasicBlock *PredBlock,
Value *PredVal, AllocaInst *SpillSlot,
122 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist);
123 AllocaInst *insertPHILoads(PHINode *PN,
Function &
F);
124 void replaceUseWithLoad(
Value *V, Use &U, AllocaInst *&SpillSlot,
125 DenseMap<BasicBlock *, Value *> &Loads,
Function &
F);
129 bool demotePHIsOnFunclets(
Function &
F,
bool DemoteCatchSwitchPHIOnly);
131 bool removeMalformedCatchswitch(
Value *FuncletToken);
132 bool removeImplausibleInstructions(
Function &
F);
133 bool cleanupPreparedFunclets(
Function &
F);
134 void verifyPreparedFunclets(
Function &
F);
137 bool DemoteCatchSwitchPHIOnly =
false;
142 const DataLayout *DL =
nullptr;
143 DenseMap<BasicBlock *, ColorVector> BlockColors;
144 MapVector<BasicBlock *, std::vector<BasicBlock *>> FuncletBlocks;
151 WinEHPrepare() : FunctionPass(ID) {}
153 StringRef getPassName()
const override {
154 return "Windows exception handling preparation";
158 return WinEHPrepareImpl().runOnFunction(Fn);
166 bool Changed = WinEHPrepareImpl().runOnFunction(
F);
170char WinEHPrepare::ID = 0;
176bool WinEHPrepareImpl::runOnFunction(
Function &Fn) {
193 return prepareExplicitEH(Fn);
206 int TryHigh,
int CatchHigh,
216 "Malformed CatchPadInst not caught by win-eh-prepare");
235 for (
const User *U : CleanupPad->
users())
237 return CRI->getUnwindDest();
250 auto &BBColors = BlockColors[&BB];
251 assert(BBColors.size() == 1 &&
"multi-color BB not removed by preparation");
259 FuncletUnwindDest =
nullptr;
261 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
269 if (FuncletUnwindDest == InvokeUnwindDest) {
272 BaseState = BaseStateI->second;
275 if (BaseState != -1) {
298 struct WorkItem *WI =
new WorkItem(BB, State);
301 while (!WorkList.
empty()) {
304 int State = WI->State;
307 if (!Inserted && StateIt->second <= State)
314 StateIt->second = State;
338 WI =
new WorkItem(SuccBB, State);
360 struct WorkItem *WI =
new WorkItem(BB, State);
363 while (!WorkList.
empty()) {
366 int State = WI->State;
381 "Malformed CatchPadInst not caught by win-eh-prepare");
385 if (!
Filter || !
Filter->getName().starts_with(
"__IsLocalUnwind"))
405 WI =
new WorkItem(SuccBB, State);
419 if (CatchSwitch->getParentPad() != ParentPad)
425 if (CleanupPad->getParentPad() != ParentPad)
427 return CleanupPad->getParent();
441 "shouldn't revist catch funclets!");
444 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
452 CatchSwitch->getParentPad())))
458 int TryHigh = CatchLow - 1;
464 bool IsPreOrder =
Mod->getTargetTriple().isArch64Bit();
467 unsigned TBMEIdx = FuncInfo.
TryBlockMap.size() - 1;
469 for (
const auto *CatchPad : Handlers) {
472 for (
const User *U : CatchPad->
users()) {
475 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
476 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
484 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
492 FuncInfo.
TryBlockMap[TBMEIdx].CatchHigh = CatchHigh;
506 auto [It, Inserted] = FuncInfo.
EHPadStateMap.try_emplace(CleanupPad);
511 It->second = CleanupState;
512 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
516 CleanupPad->getParentPad()))) {
521 for (
const User *U : CleanupPad->
users()) {
523 if (UserI->isEHPad())
525 "contain exceptional actions");
534 Entry.IsFinally =
false;
536 Entry.Handler = Handler;
545 Entry.IsFinally =
true;
546 Entry.Filter =
nullptr;
547 Entry.Handler = Handler;
563 "shouldn't revist catch funclets!");
567 assert(CatchSwitch->getNumHandlers() == 1 &&
568 "SEH doesn't have multiple handlers per __try");
569 const auto *CatchPad =
573 "Malformed CatchPadInst not caught by win-eh-prepare");
578 "unexpected filter value");
585 << CatchPadBB->
getName() <<
'\n');
588 CatchSwitch->getParentPad())))
594 for (
const User *U : CatchPad->
users()) {
597 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
598 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
606 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
615 auto [It, Inserted] = FuncInfo.
EHPadStateMap.try_emplace(CleanupPad);
620 It->second = CleanupState;
621 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
628 for (
const User *U : CleanupPad->
users()) {
630 if (UserI->isEHPad())
632 "contain exceptional actions");
640 CatchSwitch->unwindsToCaller();
658 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
682 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
702 Entry.TryParentState = TryParentState;
703 Entry.Handler = Handler;
704 Entry.HandlerType = HandlerType;
705 Entry.TypeToken = TypeToken;
742 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
743 const Value *ParentPad;
745 ParentPad = CPI->getParentPad();
747 ParentPad = CSI->getParentPad();
760 while (!Worklist.
empty()) {
762 int HandlerParentState;
763 std::tie(Pad, HandlerParentState) = Worklist.
pop_back_val();
784 int CatchState = -1, FollowerState = -1;
791 "Malformed CatchPadInst not caught by win-eh-prepare");
804 FollowerState = CatchState;
807 assert(CatchSwitch->getNumHandlers());
827 if (Entry.TryParentState != -1)
830 UnwindDest =
Catch->getCatchSwitch()->getUnwindDest();
833 UnwindDest =
nullptr;
838 UnwindDest = CleanupRet->getUnwindDest();
845 UserUnwindDest = Invoke->getUnwindDest();
847 UserUnwindDest = CatchSwitch->getUnwindDest();
850 int UserUnwindState =
852 if (UserUnwindState != -1)
867 const Value *UserUnwindParent;
869 UserUnwindParent = CSI->getParentPad();
876 if (UserUnwindParent ==
Cleanup)
880 UnwindDest = UserUnwindDest;
899 UnwindDestState = -1;
905 Entry.TryParentState = UnwindDestState;
912void WinEHPrepareImpl::colorFunclets(
Function &
F) {
919 FuncletBlocks[Color].push_back(&BB);
923bool WinEHPrepareImpl::demotePHIsOnFunclets(
Function &
F,
924 bool DemoteCatchSwitchPHIOnly) {
942 if (DemoteCatchSwitchPHIOnly) {
944 bool HasIncomingCatchSwitchBB =
false;
945 for (
unsigned I = 0,
E = PN->getNumIncomingValues();
I <
E; ++
I) {
947 PN->getIncomingBlock(
I)->getFirstNonPHIIt())) {
948 HasIncomingCatchSwitchBB =
true;
952 if (!IsCatchSwitchBB && !HasIncomingCatchSwitchBB)
960 insertPHIStores(PN, SpillSlot);
966 for (
auto *PN : PHINodes) {
969 PN->eraseFromParent();
975bool WinEHPrepareImpl::removeMalformedCatchswitch(
Value *FuncletToken) {
987 "catchpad with unexpected arguments", *CatchPad->
getParent()->getParent(),
1001 switch (Personality) {
1003 args = {nullPtr, constantZero, nullPtr};
1012 args = {constantZero};
1017 Value *NewCatchPad =
1018 Builder.CreateCatchPad(CPI->getParentPad(),
args, CPI->getName());
1027bool WinEHPrepareImpl::cloneCommonBlocks(
Function &
F) {
1033 for (
auto &Funclets : FuncletBlocks) {
1035 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
1036 Value *FuncletToken;
1037 if (FuncletPadBB == &
F.getEntryBlock())
1041 Changed |= removeMalformedCatchswitch(FuncletToken);
1044 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
1049 size_t NumColorsForBB = ColorsForBB.
size();
1050 if (NumColorsForBB == 1)
1054 dbgs() <<
" Cloning block \'" << BB->getName()
1055 <<
"\' for funclet \'" << FuncletPadBB->
getName()
1069 Orig2Clone.emplace_back(BB, CBB);
1073 if (Orig2Clone.empty())
1080 for (
auto &BBMapping : Orig2Clone) {
1084 BlocksInFunclet.push_back(NewBlock);
1086 assert(NewColors.
empty() &&
"A new block should only have one color!");
1090 dbgs() <<
" Assigned color \'" << FuncletPadBB->
getName()
1091 <<
"\' to block \'" << NewBlock->
getName()
1099 dbgs() <<
" Removed color \'" << FuncletPadBB->
getName()
1100 <<
"\' from block \'" << OldBlock->
getName()
1115 for (
auto &BBMapping : Orig2Clone) {
1119 FixupCatchrets.
clear();
1122 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
1126 CatchRet->setSuccessor(NewBlock);
1129 auto UpdatePHIOnClonedBlock = [&](
PHINode *PN,
bool IsForOldBlock) {
1133 bool EdgeTargetsFunclet;
1136 EdgeTargetsFunclet =
1137 (CRI->getCatchSwitchParentPad() == FuncletToken);
1139 ColorVector &IncomingColors = BlockColors[IncomingBlock];
1140 assert(!IncomingColors.
empty() &&
"Block not colored!");
1142 (IncomingColors.
size() == 1 ||
1144 "Cloning should leave this funclet's blocks monochromatic");
1145 EdgeTargetsFunclet = (IncomingColors.
front() == FuncletPadBB);
1147 return IsForOldBlock == EdgeTargetsFunclet;
1152 for (
auto &BBMapping : Orig2Clone) {
1156 UpdatePHIOnClonedBlock(&OldPN,
true);
1159 UpdatePHIOnClonedBlock(&NewPN,
false);
1165 for (
auto &BBMapping : Orig2Clone) {
1169 for (
PHINode &SuccPN : SuccBB->phis()) {
1172 int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock);
1173 if (OldBlockIdx == -1)
1175 Value *
IV = SuccPN.getIncomingValue(OldBlockIdx);
1180 if (
I != VMap.
end())
1184 SuccPN.addIncoming(
IV, NewBlock);
1206 ColorVector &ColorsForUserBB = BlockColors[UserBB];
1208 if (ColorsForUserBB.
size() > 1 ||
1209 *ColorsForUserBB.
begin() != FuncletPadBB)
1215 if (UsesToRename.
empty())
1222 SSAUpdate.
Initialize(OldI->getType(), OldI->getName());
1226 while (!UsesToRename.
empty())
1234bool WinEHPrepareImpl::removeImplausibleInstructions(
Function &
F) {
1238 for (
auto &Funclet : FuncletBlocks) {
1240 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
1252 Value *FuncletBundleOperand =
nullptr;
1254 FuncletBundleOperand = BU->Inputs.front();
1256 if (FuncletBundleOperand == FuncletPad)
1262 if (CB->isInlineAsm() ||
1263 (CalledFn && CalledFn->isIntrinsic() && CB->doesNotThrow()))
1274 std::prev(BB->getTerminator()->getIterator());
1290 bool IsUnreachableCatchret =
false;
1292 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
1294 bool IsUnreachableCleanupret =
false;
1296 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
1297 if (IsUnreachableRet || IsUnreachableCatchret ||
1298 IsUnreachableCleanupret) {
1316bool WinEHPrepareImpl::cleanupPreparedFunclets(
Function &
F) {
1335void WinEHPrepareImpl::verifyPreparedFunclets(
Function &
F) {
1337 size_t NumColors = BlockColors[&BB].size();
1338 assert(NumColors == 1 &&
"Expected monochromatic BB!");
1344 "EH Pad still has a PHI!");
1349bool WinEHPrepareImpl::prepareExplicitEH(
Function &
F) {
1361 Changed |= demotePHIsOnFunclets(
F, DemoteCatchSwitchPHIOnly);
1365 Changed |= removeImplausibleInstructions(
F);
1368 Changed |= cleanupPreparedFunclets(
F);
1391 F.getEntryBlock().begin());
1404 if (
isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
1409 replaceUseWithLoad(PN, U, SpillSlot, Loads,
F);
1418void WinEHPrepareImpl::insertPHIStores(
PHINode *OriginalPHI,
1426 while (!Worklist.
empty()) {
1449 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1455void WinEHPrepareImpl::insertPHIStore(
1461 Worklist.
push_back({PredBlock, PredVal});
1469void WinEHPrepareImpl::replaceUseWithLoad(
1474 SpillSlot =
new AllocaInst(
V->getType(),
DL->getAllocaAddrSpace(),
nullptr,
1475 Twine(
V->getName(),
".wineh.spillslot"),
1476 F.getEntryBlock().begin());
1489 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
1490 if (
auto *CatchRet =
1513 CatchRet->removeFromParent();
1514 CatchRet->insertInto(IncomingBlock, IncomingBlock->
end());
1517 CatchRet->setSuccessor(NewBlock);
1522 ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
1523 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
1524 ColorsForNewBlock = ColorsForPHIBlock;
1525 for (
BasicBlock *FuncletPad : ColorsForPHIBlock)
1526 FuncletBlocks[FuncletPad].
push_back(NewBlock);
1528 IncomingBlock = NewBlock;
1534 V->getType(), SpillSlot,
Twine(
V->getName(),
".wineh.reload"),
1541 Twine(
V->getName(),
".wineh.reload"),
1542 false, UsingInst->getIterator());
1551 "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 bool isMalformedCatchpad(const CatchPadInst *CPI, EHPersonality Personality)
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.
CatchSwitchInst * getCatchSwitch() const
Convenience accessors.
handler_range handlers()
iteration adapter for range-for loops.
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
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
unsigned arg_size() const
arg_size - Return the number of funcletpad arguments.
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th funcletpad argument.
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...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
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...
This is an important class for using LLVM in a threaded context.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
An instruction for reading from memory.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
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 PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
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...
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
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.
LLVMContext & getContext() const
All values hold a context through their type.
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,...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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