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 bool demotePHIsOnFunclets(
Function &
F,
bool DemoteCatchSwitchPHIOnly);
83 bool removeImplausibleInstructions(
Function &
F);
84 bool 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;
255 if (!Inserted && StateIt->second <= State)
262 StateIt->second = 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;
409 bool IsPreOrder =
Mod->getTargetTriple().isArch64Bit();
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);
451 auto [It, Inserted] = FuncInfo.
EHPadStateMap.try_emplace(CleanupPad);
456 It->second = CleanupState;
457 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
461 CleanupPad->getParentPad()))) {
466 for (
const User *U : CleanupPad->users()) {
467 const auto *UserI = cast<Instruction>(U);
468 if (UserI->isEHPad())
470 "contain exceptional actions");
478 Entry.ToState = ParentState;
479 Entry.IsFinally =
false;
481 Entry.Handler = Handler;
489 Entry.ToState = ParentState;
490 Entry.IsFinally =
true;
491 Entry.Filter =
nullptr;
492 Entry.Handler = Handler;
506 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
508 "shouldn't revist catch funclets!");
512 assert(CatchSwitch->getNumHandlers() == 1 &&
513 "SEH doesn't have multiple handlers per __try");
514 const auto *CatchPad =
515 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHIIt());
518 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
521 "unexpected filter value");
528 << CatchPadBB->
getName() <<
'\n');
531 CatchSwitch->getParentPad())))
537 for (
const User *U : CatchPad->users()) {
538 const auto *UserI = cast<Instruction>(U);
539 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
540 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
541 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
544 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
549 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
554 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
558 auto [It, Inserted] = FuncInfo.
EHPadStateMap.try_emplace(CleanupPad);
563 It->second = CleanupState;
564 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
571 for (
const User *U : CleanupPad->users()) {
572 const auto *UserI = cast<Instruction>(U);
573 if (UserI->isEHPad())
575 "contain exceptional actions");
581 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
582 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
583 CatchSwitch->unwindsToCaller();
584 if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
585 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
587 if (isa<CatchPadInst>(EHPad))
601 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
625 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
644 Entry.HandlerParentState = HandlerParentState;
645 Entry.TryParentState = TryParentState;
646 Entry.Handler = Handler;
647 Entry.HandlerType = HandlerType;
648 Entry.TypeToken = TypeToken;
685 const Instruction *FirstNonPHI = &*BB.getFirstNonPHIIt();
686 const Value *ParentPad;
687 if (
const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI))
688 ParentPad = CPI->getParentPad();
689 else if (
const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI))
690 ParentPad = CSI->getParentPad();
693 if (isa<ConstantTokenNone>(ParentPad))
703 while (!Worklist.
empty()) {
705 int HandlerParentState;
706 std::tie(Pad, HandlerParentState) = Worklist.
pop_back_val();
708 if (
const auto *
Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
718 if (
const auto *
I = dyn_cast<Instruction>(U))
726 const auto *CatchSwitch = cast<CatchSwitchInst>(Pad);
727 int CatchState = -1, FollowerState = -1;
732 const auto *
Catch = cast<CatchPadInst>(CatchBlock->getFirstNonPHIIt());
734 cast<ConstantInt>(
Catch->getArgOperand(0))->getZExtValue());
740 if (
const auto *
I = dyn_cast<Instruction>(U))
745 FollowerState = CatchState;
748 assert(CatchSwitch->getNumHandlers());
758 &*cast<const BasicBlock *>(Entry.Handler)->getFirstNonPHIIt();
762 if (
const auto *
Catch = dyn_cast<CatchPadInst>(Pad)) {
768 if (Entry.TryParentState != -1)
771 UnwindDest =
Catch->getCatchSwitch()->getUnwindDest();
773 const auto *
Cleanup = cast<CleanupPadInst>(Pad);
774 UnwindDest =
nullptr;
776 if (
auto *CleanupRet = dyn_cast<CleanupReturnInst>(U)) {
779 UnwindDest = CleanupRet->getUnwindDest();
785 if (
auto *Invoke = dyn_cast<InvokeInst>(U)) {
786 UserUnwindDest = Invoke->getUnwindDest();
787 }
else if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) {
788 UserUnwindDest = CatchSwitch->getUnwindDest();
789 }
else if (
auto *ChildCleanup = dyn_cast<CleanupPadInst>(U)) {
791 int UserUnwindState =
793 if (UserUnwindState != -1)
794 UserUnwindDest = cast<const BasicBlock *>(
808 const Value *UserUnwindParent;
809 if (
auto *CSI = dyn_cast<CatchSwitchInst>(UserUnwindPad))
810 UserUnwindParent = CSI->getParentPad();
813 cast<CleanupPadInst>(UserUnwindPad)->getParentPad();
817 if (UserUnwindParent ==
Cleanup)
821 UnwindDest = UserUnwindDest;
840 UnwindDestState = -1;
846 Entry.TryParentState = UnwindDestState;
853void WinEHPrepareImpl::colorFunclets(
Function &
F) {
864bool WinEHPrepareImpl::demotePHIsOnFunclets(
Function &
F,
865 bool DemoteCatchSwitchPHIOnly) {
866 bool Changed =
false;
875 auto *PN = dyn_cast<PHINode>(&
I);
883 if (DemoteCatchSwitchPHIOnly) {
884 bool IsCatchSwitchBB = isa<CatchSwitchInst>(BB.getFirstNonPHIIt());
885 bool HasIncomingCatchSwitchBB =
false;
886 for (
unsigned I = 0,
E = PN->getNumIncomingValues();
I <
E; ++
I) {
887 if (isa<CatchSwitchInst>(
888 PN->getIncomingBlock(
I)->getFirstNonPHIIt())) {
889 HasIncomingCatchSwitchBB =
true;
893 if (!IsCatchSwitchBB && !HasIncomingCatchSwitchBB)
901 insertPHIStores(PN, SpillSlot);
907 for (
auto *PN : PHINodes) {
910 PN->eraseFromParent();
916bool WinEHPrepareImpl::cloneCommonBlocks(
Function &
F) {
917 bool Changed =
false;
922 for (
auto &Funclets : FuncletBlocks) {
924 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
926 if (FuncletPadBB == &
F.getEntryBlock())
931 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
936 size_t NumColorsForBB = ColorsForBB.
size();
937 if (NumColorsForBB == 1)
941 dbgs() <<
" Cloning block \'" << BB->getName()
942 <<
"\' for funclet \'" << FuncletPadBB->
getName()
956 Orig2Clone.emplace_back(BB, CBB);
960 if (Orig2Clone.empty())
967 for (
auto &BBMapping : Orig2Clone) {
971 BlocksInFunclet.push_back(NewBlock);
973 assert(NewColors.
empty() &&
"A new block should only have one color!");
977 dbgs() <<
" Assigned color \'" << FuncletPadBB->
getName()
978 <<
"\' to block \'" << NewBlock->
getName()
986 dbgs() <<
" Removed color \'" << FuncletPadBB->
getName()
987 <<
"\' from block \'" << OldBlock->
getName()
1002 for (
auto &BBMapping : Orig2Clone) {
1006 FixupCatchrets.
clear();
1008 if (
auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
1009 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
1013 CatchRet->setSuccessor(NewBlock);
1016 auto UpdatePHIOnClonedBlock = [&](
PHINode *PN,
bool IsForOldBlock) {
1018 for (
unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
1021 bool EdgeTargetsFunclet;
1023 dyn_cast<CatchReturnInst>(IncomingBlock->
getTerminator())) {
1024 EdgeTargetsFunclet = (CRI->getCatchSwitchParentPad() == FuncletToken);
1026 ColorVector &IncomingColors = BlockColors[IncomingBlock];
1027 assert(!IncomingColors.
empty() &&
"Block not colored!");
1030 "Cloning should leave this funclet's blocks monochromatic");
1031 EdgeTargetsFunclet = (IncomingColors.
front() == FuncletPadBB);
1033 if (IsForOldBlock != EdgeTargetsFunclet)
1042 for (
auto &BBMapping : Orig2Clone) {
1046 UpdatePHIOnClonedBlock(&OldPN,
true);
1049 UpdatePHIOnClonedBlock(&NewPN,
false);
1055 for (
auto &BBMapping : Orig2Clone) {
1059 for (
PHINode &SuccPN : SuccBB->phis()) {
1062 int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock);
1063 if (OldBlockIdx == -1)
1065 Value *
IV = SuccPN.getIncomingValue(OldBlockIdx);
1068 if (
auto *Inst = dyn_cast<Instruction>(
IV)) {
1070 if (
I != VMap.
end())
1074 SuccPN.addIncoming(
IV, NewBlock);
1087 auto *OldI = dyn_cast<Instruction>(
const_cast<Value *
>(VT.first));
1090 auto *NewI = cast<Instruction>(VT.second);
1096 ColorVector &ColorsForUserBB = BlockColors[UserBB];
1098 if (ColorsForUserBB.
size() > 1 ||
1099 *ColorsForUserBB.
begin() != FuncletPadBB)
1105 if (UsesToRename.
empty())
1112 SSAUpdate.
Initialize(OldI->getType(), OldI->getName());
1116 while (!UsesToRename.
empty())
1124bool WinEHPrepareImpl::removeImplausibleInstructions(
Function &
F) {
1125 bool Changed =
false;
1128 for (
auto &Funclet : FuncletBlocks) {
1130 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
1132 auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
1133 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
1134 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
1138 auto *CB = dyn_cast<CallBase>(&
I);
1142 Value *FuncletBundleOperand =
nullptr;
1144 FuncletBundleOperand = BU->Inputs.front();
1146 if (FuncletBundleOperand == FuncletPad)
1151 dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
1152 if (CB->isInlineAsm() ||
1153 (CalledFn && CalledFn->isIntrinsic() && CB->doesNotThrow()))
1159 if (isa<InvokeInst>(CB)) {
1164 std::prev(BB->getTerminator()->getIterator());
1165 auto *CI = cast<CallInst>(&*CallI);
1178 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
1180 bool IsUnreachableCatchret =
false;
1181 if (
auto *CRI = dyn_cast<CatchReturnInst>(TI))
1182 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
1184 bool IsUnreachableCleanupret =
false;
1185 if (
auto *CRI = dyn_cast<CleanupReturnInst>(TI))
1186 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
1187 if (IsUnreachableRet || IsUnreachableCatchret ||
1188 IsUnreachableCleanupret) {
1191 }
else if (isa<InvokeInst>(TI)) {
1206bool WinEHPrepareImpl::cleanupPreparedFunclets(
Function &
F) {
1207 bool Changed =
false;
1225void WinEHPrepareImpl::verifyPreparedFunclets(
Function &
F) {
1227 size_t NumColors = BlockColors[&BB].size();
1228 assert(NumColors == 1 &&
"Expected monochromatic BB!");
1234 "EH Pad still has a PHI!");
1239bool WinEHPrepareImpl::prepareExplicitEH(
Function &
F) {
1248 Changed |= cloneCommonBlocks(
F);
1251 Changed |= demotePHIsOnFunclets(
F, DemoteCatchSwitchPHIOnly ||
1256 Changed |= removeImplausibleInstructions(
F);
1259 Changed |= cleanupPreparedFunclets(
F);
1282 F.getEntryBlock().begin());
1294 auto *UsingInst = cast<Instruction>(
U.getUser());
1295 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
1300 replaceUseWithLoad(PN, U, SpillSlot, Loads,
F);
1309void WinEHPrepareImpl::insertPHIStores(
PHINode *OriginalPHI,
1317 while (!Worklist.
empty()) {
1322 PHINode *PN = dyn_cast<PHINode>(InVal);
1331 if (isa<UndefValue>(PredVal))
1340 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1346void WinEHPrepareImpl::insertPHIStore(
1352 Worklist.
push_back({PredBlock, PredVal});
1360void WinEHPrepareImpl::replaceUseWithLoad(
1365 SpillSlot =
new AllocaInst(
V->getType(),
DL->getAllocaAddrSpace(),
nullptr,
1366 Twine(
V->getName(),
".wineh.spillslot"),
1367 F.getEntryBlock().begin());
1369 auto *UsingInst = cast<Instruction>(
U.getUser());
1370 if (
auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1380 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
1381 if (
auto *CatchRet =
1382 dyn_cast<CatchReturnInst>(IncomingBlock->
getTerminator())) {
1404 CatchRet->removeFromParent();
1405 CatchRet->insertInto(IncomingBlock, IncomingBlock->
end());
1408 CatchRet->setSuccessor(NewBlock);
1413 ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
1414 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
1415 ColorsForNewBlock = ColorsForPHIBlock;
1416 for (
BasicBlock *FuncletPad : ColorsForPHIBlock)
1417 FuncletBlocks[FuncletPad].
push_back(NewBlock);
1419 IncomingBlock = NewBlock;
1425 V->getType(), SpillSlot,
Twine(
V->getName(),
".wineh.reload"),
1432 Twine(
V->getName(),
".wineh.reload"),
1433 false, UsingInst->getIterator());
1442 "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)
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)
#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 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.
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...
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
const Function * getParent() const
Return the enclosing method, or null if none.
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 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 LLVM_ABI ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
This is an important base class in LLVM.
const Constant * stripPointerCasts() const
LLVM_ABI 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)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
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...
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
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 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 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.
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)
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.
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.
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.
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...
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)
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...
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...
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.
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.
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...
void calculateCXXStateForAsynchEH(const BasicBlock *BB, int State, WinEHFuncInfo &FuncInfo)
@ Mod
The access may modify the value stored in memory.
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.
LLVM_ABI FunctionPass * createWinEHPass(bool DemoteCatchSwitchPHIOnly=false)
createWinEHPass - Prepares personality functions used by MSVC on Windows, in addition to the Itanium ...
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
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 bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
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::@254 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