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;
264 if ((isa<CleanupReturnInst>(TI) || isa<CatchReturnInst>(TI)) && State > 0) {
267 }
else if (isa<InvokeInst>(TI)) {
268 auto *Call = cast<CallBase>(TI);
269 const Function *Fn = Call->getCalledFunction();
286 WI =
new WorkItem(SuccBB, State);
308 struct WorkItem *WI =
new WorkItem(BB, State);
311 while (!WorkList.
empty()) {
314 int State = WI->State;
326 if (isa<CatchPadInst>(It) && isa<CatchReturnInst>(TI)) {
327 const Constant *FilterOrNull = cast<Constant>(
328 cast<CatchPadInst>(It)->getArgOperand(0)->stripPointerCasts());
330 if (!
Filter || !
Filter->getName().starts_with(
"__IsLocalUnwind"))
332 }
else if ((isa<CleanupReturnInst>(TI) || isa<CatchReturnInst>(TI)) &&
336 }
else if (isa<InvokeInst>(TI)) {
337 auto *Call = cast<CallBase>(TI);
338 const Function *Fn = Call->getCalledFunction();
350 WI =
new WorkItem(SuccBB, State);
361 if (isa<InvokeInst>(TI))
363 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
364 if (CatchSwitch->getParentPad() != ParentPad)
369 auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
370 if (CleanupPad->getParentPad() != ParentPad)
372 return CleanupPad->getParent();
384 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
386 "shouldn't revist catch funclets!");
389 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
390 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHIIt());
397 CatchSwitch->getParentPad())))
403 int TryHigh = CatchLow - 1;
412 unsigned TBMEIdx = FuncInfo.
TryBlockMap.size() - 1;
414 for (
const auto *CatchPad : Handlers) {
417 for (
const User *U : CatchPad->users()) {
418 const auto *UserI = cast<Instruction>(U);
419 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
420 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
421 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
424 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
429 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
437 FuncInfo.
TryBlockMap[TBMEIdx].CatchHigh = CatchHigh;
447 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
456 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
460 CleanupPad->getParentPad()))) {
465 for (
const User *U : CleanupPad->users()) {
466 const auto *UserI = cast<Instruction>(U);
467 if (UserI->isEHPad())
469 "contain exceptional actions");
477 Entry.ToState = ParentState;
478 Entry.IsFinally =
false;
480 Entry.Handler = Handler;
488 Entry.ToState = ParentState;
489 Entry.IsFinally =
true;
490 Entry.Filter =
nullptr;
491 Entry.Handler = Handler;
505 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
507 "shouldn't revist catch funclets!");
511 assert(CatchSwitch->getNumHandlers() == 1 &&
512 "SEH doesn't have multiple handlers per __try");
513 const auto *CatchPad =
514 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHIIt());
517 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
520 "unexpected filter value");
527 << CatchPadBB->
getName() <<
'\n');
530 CatchSwitch->getParentPad())))
536 for (
const User *U : CatchPad->users()) {
537 const auto *UserI = cast<Instruction>(U);
538 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
539 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
540 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
543 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
548 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
553 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
562 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
569 for (
const User *U : CleanupPad->users()) {
570 const auto *UserI = cast<Instruction>(U);
571 if (UserI->isEHPad())
573 "contain exceptional actions");
579 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
580 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
581 CatchSwitch->unwindsToCaller();
582 if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
583 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
585 if (isa<CatchPadInst>(EHPad))
599 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
623 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
642 Entry.HandlerParentState = HandlerParentState;
643 Entry.TryParentState = TryParentState;
644 Entry.Handler = Handler;
645 Entry.HandlerType = HandlerType;
646 Entry.TypeToken = TypeToken;
683 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
684 const Value *ParentPad;
685 if (
const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI))
686 ParentPad = CPI->getParentPad();
687 else if (
const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI))
688 ParentPad = CSI->getParentPad();
691 if (isa<ConstantTokenNone>(ParentPad))
701 while (!Worklist.
empty()) {
703 int HandlerParentState;
704 std::tie(Pad, HandlerParentState) = Worklist.
pop_back_val();
706 if (
const auto *
Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
716 if (
const auto *
I = dyn_cast<Instruction>(U))
724 const auto *CatchSwitch = cast<CatchSwitchInst>(Pad);
725 int CatchState = -1, FollowerState = -1;
730 const auto *
Catch = cast<CatchPadInst>(CatchBlock->getFirstNonPHIIt());
732 cast<ConstantInt>(
Catch->getArgOperand(0))->getZExtValue());
738 if (
const auto *
I = dyn_cast<Instruction>(U))
743 FollowerState = CatchState;
746 assert(CatchSwitch->getNumHandlers());
756 &*cast<const BasicBlock *>(Entry.Handler)->getFirstNonPHIIt();
760 if (
const auto *
Catch = dyn_cast<CatchPadInst>(Pad)) {
766 if (Entry.TryParentState != -1)
769 UnwindDest =
Catch->getCatchSwitch()->getUnwindDest();
771 const auto *
Cleanup = cast<CleanupPadInst>(Pad);
772 UnwindDest =
nullptr;
774 if (
auto *CleanupRet = dyn_cast<CleanupReturnInst>(U)) {
777 UnwindDest = CleanupRet->getUnwindDest();
783 if (
auto *Invoke = dyn_cast<InvokeInst>(U)) {
784 UserUnwindDest = Invoke->getUnwindDest();
785 }
else if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) {
786 UserUnwindDest = CatchSwitch->getUnwindDest();
787 }
else if (
auto *ChildCleanup = dyn_cast<CleanupPadInst>(U)) {
789 int UserUnwindState =
791 if (UserUnwindState != -1)
792 UserUnwindDest = cast<const BasicBlock *>(
806 const Value *UserUnwindParent;
807 if (
auto *CSI = dyn_cast<CatchSwitchInst>(UserUnwindPad))
808 UserUnwindParent = CSI->getParentPad();
811 cast<CleanupPadInst>(UserUnwindPad)->getParentPad();
815 if (UserUnwindParent ==
Cleanup)
819 UnwindDest = UserUnwindDest;
838 UnwindDestState = -1;
844 Entry.TryParentState = UnwindDestState;
851void WinEHPrepareImpl::colorFunclets(
Function &
F) {
862void WinEHPrepareImpl::demotePHIsOnFunclets(
Function &
F,
863 bool DemoteCatchSwitchPHIOnly) {
869 if (DemoteCatchSwitchPHIOnly &&
870 !isa<CatchSwitchInst>(BB.getFirstNonPHIIt()))
874 auto *PN = dyn_cast<PHINode>(&
I);
881 insertPHIStores(PN, SpillSlot);
887 for (
auto *PN : PHINodes) {
890 PN->eraseFromParent();
894void WinEHPrepareImpl::cloneCommonBlocks(
Function &
F) {
898 for (
auto &Funclets : FuncletBlocks) {
900 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
902 if (FuncletPadBB == &
F.getEntryBlock())
907 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
912 size_t NumColorsForBB = ColorsForBB.
size();
913 if (NumColorsForBB == 1)
917 dbgs() <<
" Cloning block \'" << BB->getName()
918 <<
"\' for funclet \'" << FuncletPadBB->
getName()
932 Orig2Clone.emplace_back(BB, CBB);
936 if (Orig2Clone.empty())
941 for (
auto &BBMapping : Orig2Clone) {
945 BlocksInFunclet.push_back(NewBlock);
947 assert(NewColors.
empty() &&
"A new block should only have one color!");
951 dbgs() <<
" Assigned color \'" << FuncletPadBB->
getName()
952 <<
"\' to block \'" << NewBlock->
getName()
960 dbgs() <<
" Removed color \'" << FuncletPadBB->
getName()
961 <<
"\' from block \'" << OldBlock->
getName()
976 for (
auto &BBMapping : Orig2Clone) {
980 FixupCatchrets.
clear();
982 if (
auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
983 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
987 CatchRet->setSuccessor(NewBlock);
990 auto UpdatePHIOnClonedBlock = [&](
PHINode *PN,
bool IsForOldBlock) {
992 for (
unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
995 bool EdgeTargetsFunclet;
998 EdgeTargetsFunclet = (CRI->getCatchSwitchParentPad() == FuncletToken);
1000 ColorVector &IncomingColors = BlockColors[IncomingBlock];
1001 assert(!IncomingColors.
empty() &&
"Block not colored!");
1004 "Cloning should leave this funclet's blocks monochromatic");
1005 EdgeTargetsFunclet = (IncomingColors.
front() == FuncletPadBB);
1007 if (IsForOldBlock != EdgeTargetsFunclet)
1016 for (
auto &BBMapping : Orig2Clone) {
1020 UpdatePHIOnClonedBlock(&OldPN,
true);
1023 UpdatePHIOnClonedBlock(&NewPN,
false);
1029 for (
auto &BBMapping : Orig2Clone) {
1033 for (
PHINode &SuccPN : SuccBB->phis()) {
1036 int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock);
1037 if (OldBlockIdx == -1)
1039 Value *
IV = SuccPN.getIncomingValue(OldBlockIdx);
1042 if (
auto *Inst = dyn_cast<Instruction>(
IV)) {
1044 if (
I != VMap.
end())
1048 SuccPN.addIncoming(
IV, NewBlock);
1061 auto *OldI = dyn_cast<Instruction>(
const_cast<Value *
>(VT.first));
1064 auto *NewI = cast<Instruction>(VT.second);
1070 ColorVector &ColorsForUserBB = BlockColors[UserBB];
1072 if (ColorsForUserBB.
size() > 1 ||
1073 *ColorsForUserBB.
begin() != FuncletPadBB)
1079 if (UsesToRename.
empty())
1086 SSAUpdate.
Initialize(OldI->getType(), OldI->getName());
1090 while (!UsesToRename.
empty())
1096void WinEHPrepareImpl::removeImplausibleInstructions(
Function &
F) {
1098 for (
auto &Funclet : FuncletBlocks) {
1100 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
1102 auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
1103 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
1104 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
1108 auto *CB = dyn_cast<CallBase>(&
I);
1112 Value *FuncletBundleOperand =
nullptr;
1114 FuncletBundleOperand = BU->Inputs.front();
1116 if (FuncletBundleOperand == FuncletPad)
1121 dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
1122 if (CalledFn && ((CalledFn->isIntrinsic() && CB->doesNotThrow()) ||
1127 if (isa<InvokeInst>(CB)) {
1132 std::prev(BB->getTerminator()->getIterator());
1133 auto *CI = cast<CallInst>(&*CallI);
1146 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
1148 bool IsUnreachableCatchret =
false;
1149 if (
auto *CRI = dyn_cast<CatchReturnInst>(TI))
1150 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
1152 bool IsUnreachableCleanupret =
false;
1153 if (
auto *CRI = dyn_cast<CleanupReturnInst>(TI))
1154 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
1155 if (IsUnreachableRet || IsUnreachableCatchret ||
1156 IsUnreachableCleanupret) {
1158 }
else if (isa<InvokeInst>(TI)) {
1170void WinEHPrepareImpl::cleanupPreparedFunclets(
Function &
F) {
1185void WinEHPrepareImpl::verifyPreparedFunclets(
Function &
F) {
1187 size_t NumColors = BlockColors[&BB].size();
1188 assert(NumColors == 1 &&
"Expected monochromatic BB!");
1194 "EH Pad still has a PHI!");
1199bool WinEHPrepareImpl::prepareExplicitEH(
Function &
F) {
1208 cloneCommonBlocks(
F);
1211 demotePHIsOnFunclets(
F, DemoteCatchSwitchPHIOnly ||
1216 removeImplausibleInstructions(
F);
1219 cleanupPreparedFunclets(
F);
1242 F.getEntryBlock().begin());
1254 auto *UsingInst = cast<Instruction>(
U.getUser());
1255 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
1260 replaceUseWithLoad(PN, U, SpillSlot, Loads,
F);
1269void WinEHPrepareImpl::insertPHIStores(
PHINode *OriginalPHI,
1277 while (!Worklist.
empty()) {
1282 PHINode *PN = dyn_cast<PHINode>(InVal);
1291 if (isa<UndefValue>(PredVal))
1300 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1306void WinEHPrepareImpl::insertPHIStore(
1312 Worklist.
push_back({PredBlock, PredVal});
1320void WinEHPrepareImpl::replaceUseWithLoad(
1325 SpillSlot =
new AllocaInst(
V->getType(),
DL->getAllocaAddrSpace(),
nullptr,
1326 Twine(
V->getName(),
".wineh.spillslot"),
1327 F.getEntryBlock().begin());
1329 auto *UsingInst = cast<Instruction>(
U.getUser());
1330 if (
auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1340 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
1341 if (
auto *CatchRet =
1342 dyn_cast<CatchReturnInst>(IncomingBlock->
getTerminator())) {
1364 CatchRet->removeFromParent();
1365 CatchRet->insertInto(IncomingBlock, IncomingBlock->
end());
1368 CatchRet->setSuccessor(NewBlock);
1373 ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
1374 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
1375 ColorsForNewBlock = ColorsForPHIBlock;
1376 for (
BasicBlock *FuncletPad : ColorsForPHIBlock)
1377 FuncletBlocks[FuncletPad].
push_back(NewBlock);
1379 IncomingBlock = NewBlock;
1385 V->getType(), SpillSlot,
Twine(
V->getName(),
".wineh.reload"),
1392 Twine(
V->getName(),
".wineh.reload"),
1393 false, UsingInst->getIterator());
1402 "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...
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
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.
iterator find(const_arg_type_t< KeyT > Val)
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 RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataSetTy *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
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.
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