42#define DEBUG_TYPE "win-eh-prepare"
47 "Clone multicolor basic blocks but do not demote cross scopes"),
52 cl::desc(
"Do not remove implausible terminators or other similar cleanups"),
62class WinEHPrepareImpl {
64 WinEHPrepareImpl(
bool DemoteCatchSwitchPHIOnly)
65 : DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
80 void demotePHIsOnFunclets(
Function &
F,
bool DemoteCatchSwitchPHIOnly);
82 void removeImplausibleInstructions(
Function &
F);
83 void cleanupPreparedFunclets(
Function &
F);
86 bool DemoteCatchSwitchPHIOnly;
97 bool DemoteCatchSwitchPHIOnly;
102 WinEHPrepare(
bool DemoteCatchSwitchPHIOnly =
false)
103 :
FunctionPass(
ID), DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
106 return "Windows exception handling preparation";
110 return WinEHPrepareImpl(DemoteCatchSwitchPHIOnly).runOnFunction(Fn);
118 bool Changed = WinEHPrepareImpl(DemoteCatchSwitchPHIOnly).runOnFunction(
F);
122char WinEHPrepare::ID = 0;
127 return new WinEHPrepare(DemoteCatchSwitchPHIOnly);
130bool WinEHPrepareImpl::runOnFunction(
Function &Fn) {
142 return prepareExplicitEH(Fn);
155 int TryHigh,
int CatchHigh,
164 Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
169 HT.
Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
172 dyn_cast<AllocaInst>(CPI->getArgOperand(2)->stripPointerCasts()))
182 for (
const User *U : CleanupPad->
users())
183 if (
const auto *CRI = dyn_cast<CleanupReturnInst>(U))
184 return CRI->getUnwindDest();
193 auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
197 auto &BBColors = BlockColors[&BB];
198 assert(BBColors.size() == 1 &&
"multi-color BB not removed by preparation");
206 FuncletUnwindDest =
nullptr;
207 else if (
auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad))
208 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
209 else if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(FuncletPad))
214 BasicBlock *InvokeUnwindDest = II->getUnwindDest();
216 if (FuncletUnwindDest == InvokeUnwindDest) {
219 BaseState = BaseStateI->second;
222 if (BaseState != -1) {
245 struct WorkItem *WI =
new WorkItem(BB, State);
248 while (!WorkList.
empty()) {
251 int State = WI->State;
262 if ((isa<CleanupReturnInst>(TI) || isa<CatchReturnInst>(TI)) && State > 0) {
265 }
else if (isa<InvokeInst>(TI)) {
266 auto *Call = cast<CallBase>(TI);
267 const Function *Fn = Call->getCalledFunction();
284 WI =
new WorkItem(SuccBB, State);
306 struct WorkItem *WI =
new WorkItem(BB, State);
309 while (!WorkList.
empty()) {
312 int State = WI->State;
323 if (isa<CatchPadInst>(
I) && isa<CatchReturnInst>(TI)) {
324 const Constant *FilterOrNull = cast<Constant>(
325 cast<CatchPadInst>(
I)->getArgOperand(0)->stripPointerCasts());
327 if (!
Filter || !
Filter->getName().starts_with(
"__IsLocalUnwind"))
329 }
else if ((isa<CleanupReturnInst>(TI) || isa<CatchReturnInst>(TI)) &&
333 }
else if (isa<InvokeInst>(TI)) {
334 auto *Call = cast<CallBase>(TI);
335 const Function *Fn = Call->getCalledFunction();
347 WI =
new WorkItem(SuccBB, State);
358 if (isa<InvokeInst>(TI))
360 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
361 if (CatchSwitch->getParentPad() != ParentPad)
366 auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
367 if (CleanupPad->getParentPad() != ParentPad)
369 return CleanupPad->getParent();
381 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
383 "shouldn't revist catch funclets!");
386 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
387 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
394 CatchSwitch->getParentPad())))
400 int TryHigh = CatchLow - 1;
409 unsigned TBMEIdx = FuncInfo.
TryBlockMap.size() - 1;
411 for (
const auto *CatchPad : Handlers) {
414 for (
const User *U : CatchPad->users()) {
415 const auto *UserI = cast<Instruction>(U);
416 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
417 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
418 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
421 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
426 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
434 FuncInfo.
TryBlockMap[TBMEIdx].CatchHigh = CatchHigh;
444 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
453 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
457 CleanupPad->getParentPad()))) {
462 for (
const User *U : CleanupPad->users()) {
463 const auto *UserI = cast<Instruction>(U);
464 if (UserI->isEHPad())
466 "contain exceptional actions");
474 Entry.ToState = ParentState;
475 Entry.IsFinally =
false;
477 Entry.Handler = Handler;
485 Entry.ToState = ParentState;
486 Entry.IsFinally =
true;
487 Entry.Filter =
nullptr;
488 Entry.Handler = Handler;
502 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
504 "shouldn't revist catch funclets!");
508 assert(CatchSwitch->getNumHandlers() == 1 &&
509 "SEH doesn't have multiple handlers per __try");
510 const auto *CatchPad =
511 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHI());
514 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
517 "unexpected filter value");
524 << CatchPadBB->
getName() <<
'\n');
527 CatchSwitch->getParentPad())))
533 for (
const User *U : CatchPad->users()) {
534 const auto *UserI = cast<Instruction>(U);
535 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
536 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
537 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
540 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
545 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
550 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
559 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
566 for (
const User *U : CleanupPad->users()) {
567 const auto *UserI = cast<Instruction>(U);
568 if (UserI->isEHPad())
570 "contain exceptional actions");
576 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
577 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
578 CatchSwitch->unwindsToCaller();
579 if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
580 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
582 if (isa<CatchPadInst>(EHPad))
596 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
620 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
639 Entry.HandlerParentState = HandlerParentState;
640 Entry.TryParentState = TryParentState;
641 Entry.Handler = Handler;
642 Entry.HandlerType = HandlerType;
643 Entry.TypeToken = TypeToken;
680 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
681 const Value *ParentPad;
682 if (
const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI))
683 ParentPad = CPI->getParentPad();
684 else if (
const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI))
685 ParentPad = CSI->getParentPad();
688 if (isa<ConstantTokenNone>(ParentPad))
698 while (!Worklist.
empty()) {
700 int HandlerParentState;
701 std::tie(Pad, HandlerParentState) = Worklist.
pop_back_val();
703 if (
const auto *
Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
713 if (
const auto *
I = dyn_cast<Instruction>(U))
721 const auto *CatchSwitch = cast<CatchSwitchInst>(Pad);
722 int CatchState = -1, FollowerState = -1;
727 const auto *
Catch = cast<CatchPadInst>(CatchBlock->getFirstNonPHI());
729 cast<ConstantInt>(
Catch->getArgOperand(0))->getZExtValue());
735 if (
const auto *
I = dyn_cast<Instruction>(U))
740 FollowerState = CatchState;
743 assert(CatchSwitch->getNumHandlers());
753 cast<const BasicBlock *>(Entry.Handler)->getFirstNonPHI();
757 if (
const auto *
Catch = dyn_cast<CatchPadInst>(Pad)) {
763 if (Entry.TryParentState != -1)
766 UnwindDest =
Catch->getCatchSwitch()->getUnwindDest();
768 const auto *
Cleanup = cast<CleanupPadInst>(Pad);
769 UnwindDest =
nullptr;
771 if (
auto *CleanupRet = dyn_cast<CleanupReturnInst>(U)) {
774 UnwindDest = CleanupRet->getUnwindDest();
780 if (
auto *Invoke = dyn_cast<InvokeInst>(U)) {
781 UserUnwindDest = Invoke->getUnwindDest();
782 }
else if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) {
783 UserUnwindDest = CatchSwitch->getUnwindDest();
784 }
else if (
auto *ChildCleanup = dyn_cast<CleanupPadInst>(U)) {
786 int UserUnwindState =
788 if (UserUnwindState != -1)
789 UserUnwindDest = cast<const BasicBlock *>(
803 const Value *UserUnwindParent;
804 if (
auto *CSI = dyn_cast<CatchSwitchInst>(UserUnwindPad))
805 UserUnwindParent = CSI->getParentPad();
808 cast<CleanupPadInst>(UserUnwindPad)->getParentPad();
812 if (UserUnwindParent ==
Cleanup)
816 UnwindDest = UserUnwindDest;
835 UnwindDestState = -1;
840 Entry.TryParentState = UnwindDestState;
847void WinEHPrepareImpl::colorFunclets(
Function &
F) {
858void WinEHPrepareImpl::demotePHIsOnFunclets(
Function &
F,
859 bool DemoteCatchSwitchPHIOnly) {
865 if (DemoteCatchSwitchPHIOnly && !isa<CatchSwitchInst>(BB.getFirstNonPHI()))
869 auto *PN = dyn_cast<PHINode>(&
I);
876 insertPHIStores(PN, SpillSlot);
882 for (
auto *PN : PHINodes) {
885 PN->eraseFromParent();
889void WinEHPrepareImpl::cloneCommonBlocks(
Function &
F) {
893 for (
auto &Funclets : FuncletBlocks) {
895 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
897 if (FuncletPadBB == &
F.getEntryBlock())
902 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
907 size_t NumColorsForBB = ColorsForBB.
size();
908 if (NumColorsForBB == 1)
912 dbgs() <<
" Cloning block \'" << BB->getName()
913 <<
"\' for funclet \'" << FuncletPadBB->
getName()
927 Orig2Clone.emplace_back(BB, CBB);
931 if (Orig2Clone.empty())
936 for (
auto &BBMapping : Orig2Clone) {
940 BlocksInFunclet.push_back(NewBlock);
942 assert(NewColors.
empty() &&
"A new block should only have one color!");
946 dbgs() <<
" Assigned color \'" << FuncletPadBB->
getName()
947 <<
"\' to block \'" << NewBlock->
getName()
955 dbgs() <<
" Removed color \'" << FuncletPadBB->
getName()
956 <<
"\' from block \'" << OldBlock->
getName()
971 for (
auto &BBMapping : Orig2Clone) {
975 FixupCatchrets.
clear();
977 if (
auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
978 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
982 CatchRet->setSuccessor(NewBlock);
985 auto UpdatePHIOnClonedBlock = [&](
PHINode *PN,
bool IsForOldBlock) {
987 for (
unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
990 bool EdgeTargetsFunclet;
993 EdgeTargetsFunclet = (CRI->getCatchSwitchParentPad() == FuncletToken);
995 ColorVector &IncomingColors = BlockColors[IncomingBlock];
996 assert(!IncomingColors.
empty() &&
"Block not colored!");
999 "Cloning should leave this funclet's blocks monochromatic");
1000 EdgeTargetsFunclet = (IncomingColors.
front() == FuncletPadBB);
1002 if (IsForOldBlock != EdgeTargetsFunclet)
1011 for (
auto &BBMapping : Orig2Clone) {
1015 UpdatePHIOnClonedBlock(&OldPN,
true);
1018 UpdatePHIOnClonedBlock(&NewPN,
false);
1024 for (
auto &BBMapping : Orig2Clone) {
1028 for (
PHINode &SuccPN : SuccBB->phis()) {
1031 int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock);
1032 if (OldBlockIdx == -1)
1034 Value *
IV = SuccPN.getIncomingValue(OldBlockIdx);
1037 if (
auto *Inst = dyn_cast<Instruction>(
IV)) {
1039 if (
I != VMap.
end())
1043 SuccPN.addIncoming(
IV, NewBlock);
1056 auto *OldI = dyn_cast<Instruction>(
const_cast<Value *
>(VT.first));
1059 auto *NewI = cast<Instruction>(VT.second);
1065 ColorVector &ColorsForUserBB = BlockColors[UserBB];
1067 if (ColorsForUserBB.
size() > 1 ||
1068 *ColorsForUserBB.
begin() != FuncletPadBB)
1074 if (UsesToRename.
empty())
1081 SSAUpdate.
Initialize(OldI->getType(), OldI->getName());
1085 while (!UsesToRename.
empty())
1091void WinEHPrepareImpl::removeImplausibleInstructions(
Function &
F) {
1093 for (
auto &Funclet : FuncletBlocks) {
1095 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
1097 auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
1098 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
1099 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
1103 auto *CB = dyn_cast<CallBase>(&
I);
1107 Value *FuncletBundleOperand =
nullptr;
1109 FuncletBundleOperand = BU->Inputs.front();
1111 if (FuncletBundleOperand == FuncletPad)
1116 dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
1117 if (CalledFn && ((CalledFn->isIntrinsic() && CB->doesNotThrow()) ||
1122 if (isa<InvokeInst>(CB)) {
1127 std::prev(BB->getTerminator()->getIterator());
1128 auto *CI = cast<CallInst>(&*CallI);
1141 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
1143 bool IsUnreachableCatchret =
false;
1144 if (
auto *CRI = dyn_cast<CatchReturnInst>(TI))
1145 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
1147 bool IsUnreachableCleanupret =
false;
1148 if (
auto *CRI = dyn_cast<CleanupReturnInst>(TI))
1149 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
1150 if (IsUnreachableRet || IsUnreachableCatchret ||
1151 IsUnreachableCleanupret) {
1153 }
else if (isa<InvokeInst>(TI)) {
1165void WinEHPrepareImpl::cleanupPreparedFunclets(
Function &
F) {
1180void WinEHPrepareImpl::verifyPreparedFunclets(
Function &
F) {
1182 size_t NumColors = BlockColors[&BB].size();
1183 assert(NumColors == 1 &&
"Expected monochromatic BB!");
1189 "EH Pad still has a PHI!");
1194bool WinEHPrepareImpl::prepareExplicitEH(
Function &
F) {
1203 cloneCommonBlocks(
F);
1206 demotePHIsOnFunclets(
F, DemoteCatchSwitchPHIOnly ||
1211 removeImplausibleInstructions(
F);
1214 cleanupPreparedFunclets(
F);
1237 F.getEntryBlock().begin());
1249 auto *UsingInst = cast<Instruction>(
U.getUser());
1250 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
1255 replaceUseWithLoad(PN, U, SpillSlot, Loads,
F);
1264void WinEHPrepareImpl::insertPHIStores(
PHINode *OriginalPHI,
1272 while (!Worklist.
empty()) {
1277 PHINode *PN = dyn_cast<PHINode>(InVal);
1286 if (isa<UndefValue>(PredVal))
1295 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1301void WinEHPrepareImpl::insertPHIStore(
1307 Worklist.
push_back({PredBlock, PredVal});
1315void WinEHPrepareImpl::replaceUseWithLoad(
1320 SpillSlot =
new AllocaInst(
V->getType(),
DL->getAllocaAddrSpace(),
nullptr,
1321 Twine(
V->getName(),
".wineh.spillslot"),
1322 F.getEntryBlock().begin());
1324 auto *UsingInst = cast<Instruction>(
U.getUser());
1325 if (
auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1335 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
1336 if (
auto *CatchRet =
1337 dyn_cast<CatchReturnInst>(IncomingBlock->
getTerminator())) {
1359 CatchRet->removeFromParent();
1360 CatchRet->insertInto(IncomingBlock, IncomingBlock->
end());
1363 CatchRet->setSuccessor(NewBlock);
1368 ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
1369 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
1370 ColorsForNewBlock = ColorsForPHIBlock;
1371 for (
BasicBlock *FuncletPad : ColorsForPHIBlock)
1372 FuncletBlocks[FuncletPad].
push_back(NewBlock);
1374 IncomingBlock = NewBlock;
1380 V->getType(), SpillSlot,
Twine(
V->getName(),
".wineh.reload"),
1387 Twine(
V->getName(),
".wineh.reload"),
1388 false, UsingInst->getIterator());
1397 "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, X)
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
This file implements a map that provides insertion order iteration.
#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
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.
const BasicBlock * getParent() const
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.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
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)
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)
BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, DebugInfoFinder *DIFinder=nullptr)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
@ 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.
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::@242 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