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"),
63class WinEHPrepareImpl {
65 WinEHPrepareImpl(
bool DemoteCatchSwitchPHIOnly)
66 : DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
81 void demotePHIsOnFunclets(
Function &
F,
bool DemoteCatchSwitchPHIOnly);
83 void removeImplausibleInstructions(
Function &
F);
84 void cleanupPreparedFunclets(
Function &
F);
87 bool DemoteCatchSwitchPHIOnly;
98 bool DemoteCatchSwitchPHIOnly;
103 WinEHPrepare(
bool DemoteCatchSwitchPHIOnly =
false)
104 :
FunctionPass(
ID), DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
107 return "Windows exception handling preparation";
111 return WinEHPrepareImpl(DemoteCatchSwitchPHIOnly).runOnFunction(Fn);
119 bool Changed = WinEHPrepareImpl(DemoteCatchSwitchPHIOnly).runOnFunction(
F);
123char WinEHPrepare::ID = 0;
128 return new WinEHPrepare(DemoteCatchSwitchPHIOnly);
131bool WinEHPrepareImpl::runOnFunction(
Function &Fn) {
143 return prepareExplicitEH(Fn);
156 int TryHigh,
int CatchHigh,
165 Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
170 HT.
Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
173 dyn_cast<AllocaInst>(CPI->getArgOperand(2)->stripPointerCasts()))
183 for (
const User *U : CleanupPad->
users())
184 if (
const auto *CRI = dyn_cast<CleanupReturnInst>(U))
185 return CRI->getUnwindDest();
194 auto *
II = dyn_cast<InvokeInst>(BB.getTerminator());
198 auto &BBColors = BlockColors[&BB];
199 assert(BBColors.size() == 1 &&
"multi-color BB not removed by preparation");
207 FuncletUnwindDest =
nullptr;
208 else if (
auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad))
209 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
210 else if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(FuncletPad))
217 if (FuncletUnwindDest == InvokeUnwindDest) {
220 BaseState = BaseStateI->second;
223 if (BaseState != -1) {
246 struct WorkItem *WI =
new WorkItem(BB, State);
249 while (!WorkList.
empty()) {
252 int State = WI->State;
263 if ((isa<CleanupReturnInst>(TI) || isa<CatchReturnInst>(TI)) && State > 0) {
266 }
else if (isa<InvokeInst>(TI)) {
267 auto *Call = cast<CallBase>(TI);
268 const Function *Fn = Call->getCalledFunction();
285 WI =
new WorkItem(SuccBB, State);
307 struct WorkItem *WI =
new WorkItem(BB, State);
310 while (!WorkList.
empty()) {
313 int State = WI->State;
324 if (isa<CatchPadInst>(
I) && isa<CatchReturnInst>(TI)) {
325 const Constant *FilterOrNull = cast<Constant>(
326 cast<CatchPadInst>(
I)->getArgOperand(0)->stripPointerCasts());
328 if (!
Filter || !
Filter->getName().starts_with(
"__IsLocalUnwind"))
330 }
else if ((isa<CleanupReturnInst>(TI) || isa<CatchReturnInst>(TI)) &&
334 }
else if (isa<InvokeInst>(TI)) {
335 auto *Call = cast<CallBase>(TI);
336 const Function *Fn = Call->getCalledFunction();
348 WI =
new WorkItem(SuccBB, State);
359 if (isa<InvokeInst>(TI))
361 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
362 if (CatchSwitch->getParentPad() != ParentPad)
367 auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
368 if (CleanupPad->getParentPad() != ParentPad)
370 return CleanupPad->getParent();
382 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
384 "shouldn't revist catch funclets!");
387 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
388 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
395 CatchSwitch->getParentPad())))
401 int TryHigh = CatchLow - 1;
410 unsigned TBMEIdx = FuncInfo.
TryBlockMap.size() - 1;
412 for (
const auto *CatchPad : Handlers) {
415 for (
const User *U : CatchPad->users()) {
416 const auto *UserI = cast<Instruction>(U);
417 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
418 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
419 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
422 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
427 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
435 FuncInfo.
TryBlockMap[TBMEIdx].CatchHigh = CatchHigh;
445 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
454 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
458 CleanupPad->getParentPad()))) {
463 for (
const User *U : CleanupPad->users()) {
464 const auto *UserI = cast<Instruction>(U);
465 if (UserI->isEHPad())
467 "contain exceptional actions");
475 Entry.ToState = ParentState;
476 Entry.IsFinally =
false;
478 Entry.Handler = Handler;
486 Entry.ToState = ParentState;
487 Entry.IsFinally =
true;
488 Entry.Filter =
nullptr;
489 Entry.Handler = Handler;
503 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
505 "shouldn't revist catch funclets!");
509 assert(CatchSwitch->getNumHandlers() == 1 &&
510 "SEH doesn't have multiple handlers per __try");
511 const auto *CatchPad =
512 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHI());
515 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
518 "unexpected filter value");
525 << CatchPadBB->
getName() <<
'\n');
528 CatchSwitch->getParentPad())))
534 for (
const User *U : CatchPad->users()) {
535 const auto *UserI = cast<Instruction>(U);
536 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
537 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
538 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
541 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
546 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
551 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
560 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
567 for (
const User *U : CleanupPad->users()) {
568 const auto *UserI = cast<Instruction>(U);
569 if (UserI->isEHPad())
571 "contain exceptional actions");
577 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
578 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
579 CatchSwitch->unwindsToCaller();
580 if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
581 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
583 if (isa<CatchPadInst>(EHPad))
597 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
621 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
640 Entry.HandlerParentState = HandlerParentState;
641 Entry.TryParentState = TryParentState;
642 Entry.Handler = Handler;
643 Entry.HandlerType = HandlerType;
644 Entry.TypeToken = TypeToken;
681 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
682 const Value *ParentPad;
683 if (
const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI))
684 ParentPad = CPI->getParentPad();
685 else if (
const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI))
686 ParentPad = CSI->getParentPad();
689 if (isa<ConstantTokenNone>(ParentPad))
699 while (!Worklist.
empty()) {
701 int HandlerParentState;
702 std::tie(Pad, HandlerParentState) = Worklist.
pop_back_val();
704 if (
const auto *
Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
714 if (
const auto *
I = dyn_cast<Instruction>(U))
722 const auto *CatchSwitch = cast<CatchSwitchInst>(Pad);
723 int CatchState = -1, FollowerState = -1;
728 const auto *
Catch = cast<CatchPadInst>(CatchBlock->getFirstNonPHI());
730 cast<ConstantInt>(
Catch->getArgOperand(0))->getZExtValue());
736 if (
const auto *
I = dyn_cast<Instruction>(U))
741 FollowerState = CatchState;
744 assert(CatchSwitch->getNumHandlers());
754 cast<const BasicBlock *>(Entry.Handler)->getFirstNonPHI();
758 if (
const auto *
Catch = dyn_cast<CatchPadInst>(Pad)) {
764 if (Entry.TryParentState != -1)
767 UnwindDest =
Catch->getCatchSwitch()->getUnwindDest();
769 const auto *
Cleanup = cast<CleanupPadInst>(Pad);
770 UnwindDest =
nullptr;
772 if (
auto *CleanupRet = dyn_cast<CleanupReturnInst>(U)) {
775 UnwindDest = CleanupRet->getUnwindDest();
781 if (
auto *Invoke = dyn_cast<InvokeInst>(U)) {
782 UserUnwindDest = Invoke->getUnwindDest();
783 }
else if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) {
784 UserUnwindDest = CatchSwitch->getUnwindDest();
785 }
else if (
auto *ChildCleanup = dyn_cast<CleanupPadInst>(U)) {
787 int UserUnwindState =
789 if (UserUnwindState != -1)
790 UserUnwindDest = cast<const BasicBlock *>(
804 const Value *UserUnwindParent;
805 if (
auto *CSI = dyn_cast<CatchSwitchInst>(UserUnwindPad))
806 UserUnwindParent = CSI->getParentPad();
809 cast<CleanupPadInst>(UserUnwindPad)->getParentPad();
813 if (UserUnwindParent ==
Cleanup)
817 UnwindDest = UserUnwindDest;
836 UnwindDestState = -1;
841 Entry.TryParentState = UnwindDestState;
848void WinEHPrepareImpl::colorFunclets(
Function &
F) {
859void WinEHPrepareImpl::demotePHIsOnFunclets(
Function &
F,
860 bool DemoteCatchSwitchPHIOnly) {
866 if (DemoteCatchSwitchPHIOnly && !isa<CatchSwitchInst>(BB.getFirstNonPHI()))
870 auto *PN = dyn_cast<PHINode>(&
I);
877 insertPHIStores(PN, SpillSlot);
883 for (
auto *PN : PHINodes) {
886 PN->eraseFromParent();
890void WinEHPrepareImpl::cloneCommonBlocks(
Function &
F) {
894 for (
auto &Funclets : FuncletBlocks) {
896 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
898 if (FuncletPadBB == &
F.getEntryBlock())
903 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
908 size_t NumColorsForBB = ColorsForBB.
size();
909 if (NumColorsForBB == 1)
913 dbgs() <<
" Cloning block \'" << BB->getName()
914 <<
"\' for funclet \'" << FuncletPadBB->
getName()
928 Orig2Clone.emplace_back(BB, CBB);
932 if (Orig2Clone.empty())
937 for (
auto &BBMapping : Orig2Clone) {
941 BlocksInFunclet.push_back(NewBlock);
943 assert(NewColors.
empty() &&
"A new block should only have one color!");
947 dbgs() <<
" Assigned color \'" << FuncletPadBB->
getName()
948 <<
"\' to block \'" << NewBlock->
getName()
956 dbgs() <<
" Removed color \'" << FuncletPadBB->
getName()
957 <<
"\' from block \'" << OldBlock->
getName()
972 for (
auto &BBMapping : Orig2Clone) {
976 FixupCatchrets.
clear();
978 if (
auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
979 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
983 CatchRet->setSuccessor(NewBlock);
986 auto UpdatePHIOnClonedBlock = [&](
PHINode *PN,
bool IsForOldBlock) {
988 for (
unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
991 bool EdgeTargetsFunclet;
994 EdgeTargetsFunclet = (CRI->getCatchSwitchParentPad() == FuncletToken);
996 ColorVector &IncomingColors = BlockColors[IncomingBlock];
997 assert(!IncomingColors.
empty() &&
"Block not colored!");
1000 "Cloning should leave this funclet's blocks monochromatic");
1001 EdgeTargetsFunclet = (IncomingColors.
front() == FuncletPadBB);
1003 if (IsForOldBlock != EdgeTargetsFunclet)
1012 for (
auto &BBMapping : Orig2Clone) {
1016 UpdatePHIOnClonedBlock(&OldPN,
true);
1019 UpdatePHIOnClonedBlock(&NewPN,
false);
1025 for (
auto &BBMapping : Orig2Clone) {
1029 for (
PHINode &SuccPN : SuccBB->phis()) {
1032 int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock);
1033 if (OldBlockIdx == -1)
1035 Value *
IV = SuccPN.getIncomingValue(OldBlockIdx);
1038 if (
auto *Inst = dyn_cast<Instruction>(
IV)) {
1040 if (
I != VMap.
end())
1044 SuccPN.addIncoming(
IV, NewBlock);
1057 auto *OldI = dyn_cast<Instruction>(
const_cast<Value *
>(VT.first));
1060 auto *NewI = cast<Instruction>(VT.second);
1066 ColorVector &ColorsForUserBB = BlockColors[UserBB];
1068 if (ColorsForUserBB.
size() > 1 ||
1069 *ColorsForUserBB.
begin() != FuncletPadBB)
1075 if (UsesToRename.
empty())
1082 SSAUpdate.
Initialize(OldI->getType(), OldI->getName());
1086 while (!UsesToRename.
empty())
1092void WinEHPrepareImpl::removeImplausibleInstructions(
Function &
F) {
1094 for (
auto &Funclet : FuncletBlocks) {
1096 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
1098 auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
1099 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
1100 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
1104 auto *CB = dyn_cast<CallBase>(&
I);
1108 Value *FuncletBundleOperand =
nullptr;
1110 FuncletBundleOperand = BU->Inputs.front();
1112 if (FuncletBundleOperand == FuncletPad)
1117 dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
1118 if (CalledFn && ((CalledFn->isIntrinsic() && CB->doesNotThrow()) ||
1123 if (isa<InvokeInst>(CB)) {
1128 std::prev(BB->getTerminator()->getIterator());
1129 auto *CI = cast<CallInst>(&*CallI);
1142 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
1144 bool IsUnreachableCatchret =
false;
1145 if (
auto *CRI = dyn_cast<CatchReturnInst>(TI))
1146 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
1148 bool IsUnreachableCleanupret =
false;
1149 if (
auto *CRI = dyn_cast<CleanupReturnInst>(TI))
1150 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
1151 if (IsUnreachableRet || IsUnreachableCatchret ||
1152 IsUnreachableCleanupret) {
1154 }
else if (isa<InvokeInst>(TI)) {
1166void WinEHPrepareImpl::cleanupPreparedFunclets(
Function &
F) {
1181void WinEHPrepareImpl::verifyPreparedFunclets(
Function &
F) {
1183 size_t NumColors = BlockColors[&BB].size();
1184 assert(NumColors == 1 &&
"Expected monochromatic BB!");
1190 "EH Pad still has a PHI!");
1195bool WinEHPrepareImpl::prepareExplicitEH(
Function &
F) {
1204 cloneCommonBlocks(
F);
1207 demotePHIsOnFunclets(
F, DemoteCatchSwitchPHIOnly ||
1212 removeImplausibleInstructions(
F);
1215 cleanupPreparedFunclets(
F);
1238 F.getEntryBlock().begin());
1250 auto *UsingInst = cast<Instruction>(
U.getUser());
1251 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
1256 replaceUseWithLoad(PN, U, SpillSlot, Loads,
F);
1265void WinEHPrepareImpl::insertPHIStores(
PHINode *OriginalPHI,
1273 while (!Worklist.
empty()) {
1278 PHINode *PN = dyn_cast<PHINode>(InVal);
1287 if (isa<UndefValue>(PredVal))
1296 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1302void WinEHPrepareImpl::insertPHIStore(
1308 Worklist.
push_back({PredBlock, PredVal});
1316void WinEHPrepareImpl::replaceUseWithLoad(
1321 SpillSlot =
new AllocaInst(
V->getType(),
DL->getAllocaAddrSpace(),
nullptr,
1322 Twine(
V->getName(),
".wineh.spillslot"),
1323 F.getEntryBlock().begin());
1325 auto *UsingInst = cast<Instruction>(
U.getUser());
1326 if (
auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1336 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
1337 if (
auto *CatchRet =
1338 dyn_cast<CatchReturnInst>(IncomingBlock->
getTerminator())) {
1360 CatchRet->removeFromParent();
1361 CatchRet->insertInto(IncomingBlock, IncomingBlock->
end());
1364 CatchRet->setSuccessor(NewBlock);
1369 ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
1370 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
1371 ColorsForNewBlock = ColorsForPHIBlock;
1372 for (
BasicBlock *FuncletPad : ColorsForPHIBlock)
1373 FuncletBlocks[FuncletPad].
push_back(NewBlock);
1375 IncomingBlock = NewBlock;
1381 V->getType(), SpillSlot,
Twine(
V->getName(),
".wineh.reload"),
1388 Twine(
V->getName(),
".wineh.reload"),
1389 false, UsingInst->getIterator());
1398 "should get invoke with precomputed state");
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
static const 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
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 cl::opt< bool > DemoteCatchSwitchPHIOnlyOpt("demote-catchswitch-only", cl::Hidden, cl::desc("Demote catchswitch BBs only (for wasm EH)"), cl::init(false))
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
A container for analyses that lazily runs them and caches their results.
ArrayRef - 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.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
const Instruction & front() const
const Function * getParent() const
Return the enclosing method, or null if none.
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 if the block is well formed or null if the block is not well forme...
Conditional or Unconditional Branch instruction.
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
static ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
This is an important base class in LLVM.
const Constant * stripPointerCasts() const
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
A parsed version of the target data layout string in and methods for querying it.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
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...
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
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.
Value * removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty=true)
Remove an incoming value.
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.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
static 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.
void RewriteUseAfterInsertions(Use &U)
Rewrite a use like RewriteUse but handling in-block definitions.
void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
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.
StringRef - Represent a constant reference to a string, i.e.
TinyPtrVector - This class is specialized for cases where there are normally 0 or 1 element in a vect...
void push_back(EltTy NewVal)
Triple - Helper class for working with autoconf configuration names.
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A Use represents the edge between a Value definition and its users.
std::pair< const Value *, WeakTrackingVH > value_type
iterator find(const KeyT &Val)
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
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()
StringRef getName() const
Return a constant reference to the value's name.
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
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...
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)
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...
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...
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,...
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...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Instruction * removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU=nullptr)
Replace 'BB's terminator with one that does not have an unwind successor block.
void calculateSEHStateForAsynchEH(const BasicBlock *BB, int State, WinEHFuncInfo &FuncInfo)
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
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.
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...
void calculateCXXStateForAsynchEH(const BasicBlock *BB, int State, WinEHFuncInfo &FuncInfo)
@ Mod
The access may modify the value stored in memory.
BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
void calculateSEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
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.
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
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 removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
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)
WorkItem(const BasicBlock *BB, int St)
Similar to CxxUnwindMapEntry, but supports SEH filters.
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
union llvm::WinEHHandlerType::@253 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
GlobalVariable * TypeDescriptor
const AllocaInst * Alloca
SmallVector< WinEHHandlerType, 1 > HandlerArray