41#define DEBUG_TYPE "winehprepare"
46 "Clone multicolor basic blocks but do not demote cross scopes"),
51 cl::desc(
"Do not remove implausible terminators or other similar cleanups"),
63 WinEHPrepare(
bool DemoteCatchSwitchPHIOnly =
false)
64 :
FunctionPass(
ID), DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {}
73 return "Windows exception handling preparation";
87 void demotePHIsOnFunclets(
Function &
F,
bool DemoteCatchSwitchPHIOnly);
89 void removeImplausibleInstructions(
Function &
F);
90 void cleanupPreparedFunclets(
Function &
F);
93 bool DemoteCatchSwitchPHIOnly;
105char WinEHPrepare::ID = 0;
110 return new WinEHPrepare(DemoteCatchSwitchPHIOnly);
113bool WinEHPrepare::runOnFunction(
Function &Fn) {
125 return prepareExplicitEH(Fn);
128bool WinEHPrepare::doFinalization(
Module &M) {
return false; }
130void WinEHPrepare::getAnalysisUsage(
AnalysisUsage &AU)
const {}
142 int TryHigh,
int CatchHigh,
151 Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
156 HT.
Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
159 dyn_cast<AllocaInst>(CPI->getArgOperand(2)->stripPointerCasts()))
169 for (
const User *U : CleanupPad->
users())
170 if (
const auto *CRI = dyn_cast<CleanupReturnInst>(U))
171 return CRI->getUnwindDest();
180 auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
184 auto &BBColors = BlockColors[&BB];
185 assert(BBColors.size() == 1 &&
"multi-color BB not removed by preparation");
193 FuncletUnwindDest =
nullptr;
194 else if (
auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad))
195 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
196 else if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(FuncletPad))
201 BasicBlock *InvokeUnwindDest = II->getUnwindDest();
203 if (FuncletUnwindDest == InvokeUnwindDest) {
206 BaseState = BaseStateI->second;
209 if (BaseState != -1) {
232 struct WorkItem *WI =
new WorkItem(BB,
State);
235 while (!WorkList.
empty()) {
238 int State = WI->State;
249 if ((isa<CleanupReturnInst>(TI) || isa<CatchReturnInst>(TI)) &&
State > 0) {
252 }
else if (isa<InvokeInst>(TI)) {
253 auto *Call = cast<CallBase>(TI);
254 const Function *Fn = Call->getCalledFunction();
271 WI =
new WorkItem(SuccBB,
State);
293 struct WorkItem *WI =
new WorkItem(BB,
State);
296 while (!WorkList.
empty()) {
299 int State = WI->State;
310 if (isa<CatchPadInst>(
I) && isa<CatchReturnInst>(TI)) {
311 const Constant *FilterOrNull = cast<Constant>(
312 cast<CatchPadInst>(
I)->getArgOperand(0)->stripPointerCasts());
314 if (!
Filter || !
Filter->getName().startswith(
"__IsLocalUnwind"))
316 }
else if ((isa<CleanupReturnInst>(TI) || isa<CatchReturnInst>(TI)) &&
320 }
else if (isa<InvokeInst>(TI)) {
321 auto *Call = cast<CallBase>(TI);
322 const Function *Fn = Call->getCalledFunction();
334 WI =
new WorkItem(SuccBB,
State);
345 if (isa<InvokeInst>(TI))
347 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
348 if (CatchSwitch->getParentPad() != ParentPad)
353 auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
354 if (CleanupPad->getParentPad() != ParentPad)
356 return CleanupPad->getParent();
368 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
370 "shouldn't revist catch funclets!");
373 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
374 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
381 CatchSwitch->getParentPad())))
387 int TryHigh = CatchLow - 1;
396 unsigned TBMEIdx = FuncInfo.
TryBlockMap.size() - 1;
398 for (
const auto *CatchPad : Handlers) {
401 for (
const User *U : CatchPad->users()) {
402 const auto *UserI = cast<Instruction>(U);
403 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
404 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
405 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
408 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
413 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
421 FuncInfo.
TryBlockMap[TBMEIdx].CatchHigh = CatchHigh;
431 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
440 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
444 CleanupPad->getParentPad()))) {
449 for (
const User *U : CleanupPad->users()) {
450 const auto *UserI = cast<Instruction>(U);
451 if (UserI->isEHPad())
453 "contain exceptional actions");
461 Entry.ToState = ParentState;
462 Entry.IsFinally =
false;
464 Entry.Handler = Handler;
472 Entry.ToState = ParentState;
473 Entry.IsFinally =
true;
474 Entry.Filter =
nullptr;
475 Entry.Handler = Handler;
489 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
491 "shouldn't revist catch funclets!");
495 assert(CatchSwitch->getNumHandlers() == 1 &&
496 "SEH doesn't have multiple handlers per __try");
497 const auto *CatchPad =
498 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHI());
501 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
504 "unexpected filter value");
511 << CatchPadBB->
getName() <<
'\n');
514 CatchSwitch->getParentPad())))
520 for (
const User *U : CatchPad->users()) {
521 const auto *UserI = cast<Instruction>(U);
522 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
523 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
524 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
527 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
532 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
537 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
546 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
553 for (
const User *U : CleanupPad->users()) {
554 const auto *UserI = cast<Instruction>(U);
555 if (UserI->isEHPad())
557 "contain exceptional actions");
563 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
564 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
565 CatchSwitch->unwindsToCaller();
566 if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
567 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
569 if (isa<CatchPadInst>(EHPad))
583 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
607 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
626 Entry.HandlerParentState = HandlerParentState;
627 Entry.TryParentState = TryParentState;
628 Entry.Handler = Handler;
629 Entry.HandlerType = HandlerType;
630 Entry.TypeToken = TypeToken;
667 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
668 const Value *ParentPad;
669 if (
const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI))
670 ParentPad = CPI->getParentPad();
671 else if (
const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI))
672 ParentPad = CSI->getParentPad();
675 if (isa<ConstantTokenNone>(ParentPad))
685 while (!Worklist.
empty()) {
687 int HandlerParentState;
688 std::tie(Pad, HandlerParentState) = Worklist.
pop_back_val();
690 if (
const auto *
Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
694 (
Cleanup->arg_size() ? ClrHandlerType::Fault
695 : ClrHandlerType::Finally);
700 if (
const auto *
I = dyn_cast<Instruction>(U))
708 const auto *CatchSwitch = cast<CatchSwitchInst>(Pad);
709 int CatchState = -1, FollowerState = -1;
714 const auto *
Catch = cast<CatchPadInst>(CatchBlock->getFirstNonPHI());
716 cast<ConstantInt>(
Catch->getArgOperand(0))->getZExtValue());
719 ClrHandlerType::Catch, TypeToken, CatchBlock);
722 if (
const auto *
I = dyn_cast<Instruction>(U))
727 FollowerState = CatchState;
730 assert(CatchSwitch->getNumHandlers());
740 cast<const BasicBlock *>(Entry.Handler)->getFirstNonPHI();
744 if (
const auto *
Catch = dyn_cast<CatchPadInst>(Pad)) {
750 if (Entry.TryParentState != -1)
753 UnwindDest =
Catch->getCatchSwitch()->getUnwindDest();
755 const auto *
Cleanup = cast<CleanupPadInst>(Pad);
756 UnwindDest =
nullptr;
758 if (
auto *CleanupRet = dyn_cast<CleanupReturnInst>(U)) {
761 UnwindDest = CleanupRet->getUnwindDest();
767 if (
auto *Invoke = dyn_cast<InvokeInst>(U)) {
768 UserUnwindDest = Invoke->getUnwindDest();
769 }
else if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) {
770 UserUnwindDest = CatchSwitch->getUnwindDest();
771 }
else if (
auto *ChildCleanup = dyn_cast<CleanupPadInst>(U)) {
773 int UserUnwindState =
775 if (UserUnwindState != -1)
776 UserUnwindDest = cast<const BasicBlock *>(
790 const Value *UserUnwindParent;
791 if (
auto *CSI = dyn_cast<CatchSwitchInst>(UserUnwindPad))
792 UserUnwindParent = CSI->getParentPad();
795 cast<CleanupPadInst>(UserUnwindPad)->getParentPad();
799 if (UserUnwindParent ==
Cleanup)
803 UnwindDest = UserUnwindDest;
822 UnwindDestState = -1;
827 Entry.TryParentState = UnwindDestState;
834void WinEHPrepare::colorFunclets(
Function &
F) {
845void WinEHPrepare::demotePHIsOnFunclets(
Function &
F,
846 bool DemoteCatchSwitchPHIOnly) {
852 if (DemoteCatchSwitchPHIOnly && !isa<CatchSwitchInst>(BB.getFirstNonPHI()))
856 auto *PN = dyn_cast<PHINode>(&
I);
863 insertPHIStores(PN, SpillSlot);
869 for (
auto *PN : PHINodes) {
872 PN->eraseFromParent();
876void WinEHPrepare::cloneCommonBlocks(
Function &
F) {
880 for (
auto &Funclets : FuncletBlocks) {
882 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
884 if (FuncletPadBB == &
F.getEntryBlock())
889 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
894 size_t NumColorsForBB = ColorsForBB.
size();
895 if (NumColorsForBB == 1)
899 dbgs() <<
" Cloning block \'" << BB->getName()
900 <<
"\' for funclet \'" << FuncletPadBB->
getName()
914 Orig2Clone.emplace_back(BB, CBB);
918 if (Orig2Clone.empty())
923 for (
auto &BBMapping : Orig2Clone) {
927 BlocksInFunclet.push_back(NewBlock);
929 assert(NewColors.
empty() &&
"A new block should only have one color!");
933 dbgs() <<
" Assigned color \'" << FuncletPadBB->
getName()
934 <<
"\' to block \'" << NewBlock->
getName()
942 dbgs() <<
" Removed color \'" << FuncletPadBB->
getName()
943 <<
"\' from block \'" << OldBlock->
getName()
958 for (
auto &BBMapping : Orig2Clone) {
962 FixupCatchrets.
clear();
964 if (
auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
965 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
969 CatchRet->setSuccessor(NewBlock);
972 auto UpdatePHIOnClonedBlock = [&](
PHINode *PN,
bool IsForOldBlock) {
974 for (
unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
977 bool EdgeTargetsFunclet;
980 EdgeTargetsFunclet = (CRI->getCatchSwitchParentPad() == FuncletToken);
982 ColorVector &IncomingColors = BlockColors[IncomingBlock];
983 assert(!IncomingColors.
empty() &&
"Block not colored!");
986 "Cloning should leave this funclet's blocks monochromatic");
987 EdgeTargetsFunclet = (IncomingColors.
front() == FuncletPadBB);
989 if (IsForOldBlock != EdgeTargetsFunclet)
998 for (
auto &BBMapping : Orig2Clone) {
1002 UpdatePHIOnClonedBlock(&OldPN,
true);
1005 UpdatePHIOnClonedBlock(&NewPN,
false);
1011 for (
auto &BBMapping : Orig2Clone) {
1015 for (
PHINode &SuccPN : SuccBB->phis()) {
1018 int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock);
1019 if (OldBlockIdx == -1)
1021 Value *
IV = SuccPN.getIncomingValue(OldBlockIdx);
1024 if (
auto *Inst = dyn_cast<Instruction>(
IV)) {
1026 if (
I != VMap.
end())
1030 SuccPN.addIncoming(
IV, NewBlock);
1043 auto *OldI = dyn_cast<Instruction>(
const_cast<Value *
>(VT.first));
1046 auto *NewI = cast<Instruction>(VT.second);
1052 ColorVector &ColorsForUserBB = BlockColors[UserBB];
1054 if (ColorsForUserBB.
size() > 1 ||
1055 *ColorsForUserBB.
begin() != FuncletPadBB)
1061 if (UsesToRename.
empty())
1068 SSAUpdate.
Initialize(OldI->getType(), OldI->getName());
1072 while (!UsesToRename.
empty())
1078void WinEHPrepare::removeImplausibleInstructions(
Function &
F) {
1080 for (
auto &Funclet : FuncletBlocks) {
1082 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
1084 auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
1085 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
1086 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
1090 auto *CB = dyn_cast<CallBase>(&
I);
1094 Value *FuncletBundleOperand =
nullptr;
1096 FuncletBundleOperand = BU->Inputs.front();
1098 if (FuncletBundleOperand == FuncletPad)
1103 dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
1104 if (CalledFn && ((CalledFn->isIntrinsic() && CB->doesNotThrow()) ||
1109 if (isa<InvokeInst>(CB)) {
1114 std::prev(BB->getTerminator()->getIterator());
1115 auto *CI = cast<CallInst>(&*CallI);
1128 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
1130 bool IsUnreachableCatchret =
false;
1131 if (
auto *CRI = dyn_cast<CatchReturnInst>(TI))
1132 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
1134 bool IsUnreachableCleanupret =
false;
1135 if (
auto *CRI = dyn_cast<CleanupReturnInst>(TI))
1136 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
1137 if (IsUnreachableRet || IsUnreachableCatchret ||
1138 IsUnreachableCleanupret) {
1140 }
else if (isa<InvokeInst>(TI)) {
1141 if (Personality == EHPersonality::MSVC_CXX && CleanupPad) {
1152void WinEHPrepare::cleanupPreparedFunclets(
Function &
F) {
1167void WinEHPrepare::verifyPreparedFunclets(
Function &
F) {
1169 size_t NumColors = BlockColors[&BB].size();
1170 assert(NumColors == 1 &&
"Expected monochromatic BB!");
1176 "EH Pad still has a PHI!");
1181bool WinEHPrepare::prepareExplicitEH(
Function &
F) {
1190 cloneCommonBlocks(
F);
1193 demotePHIsOnFunclets(
F, DemoteCatchSwitchPHIOnly ||
1198 removeImplausibleInstructions(
F);
1201 cleanupPreparedFunclets(
F);
1209 BlockColors.clear();
1210 FuncletBlocks.clear();
1227 &
F.getEntryBlock().front());
1239 auto *UsingInst = cast<Instruction>(
U.getUser());
1240 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
1245 replaceUseWithLoad(PN, U, SpillSlot, Loads,
F);
1254void WinEHPrepare::insertPHIStores(
PHINode *OriginalPHI,
1262 while (!Worklist.
empty()) {
1267 PHINode *PN = dyn_cast<PHINode>(InVal);
1276 if (isa<UndefValue>(PredVal))
1285 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1291void WinEHPrepare::insertPHIStore(
1297 Worklist.
push_back({PredBlock, PredVal});
1310 SpillSlot =
new AllocaInst(
V->getType(),
DL->getAllocaAddrSpace(),
nullptr,
1311 Twine(
V->getName(),
".wineh.spillslot"),
1312 &
F.getEntryBlock().front());
1314 auto *UsingInst = cast<Instruction>(
U.getUser());
1315 if (
auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1325 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
1326 if (
auto *CatchRet =
1327 dyn_cast<CatchReturnInst>(IncomingBlock->
getTerminator())) {
1349 CatchRet->removeFromParent();
1350 CatchRet->insertInto(IncomingBlock, IncomingBlock->
end());
1353 CatchRet->setSuccessor(NewBlock);
1358 ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
1359 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
1360 ColorsForNewBlock = ColorsForPHIBlock;
1361 for (
BasicBlock *FuncletPad : ColorsForPHIBlock)
1362 FuncletBlocks[FuncletPad].
push_back(NewBlock);
1364 IncomingBlock = NewBlock;
1370 Twine(
V->getName(),
".wineh.reload"),
1377 Twine(
V->getName(),
".wineh.reload"),
1387 "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 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 void calculateSEHStateNumbers(WinEHFuncInfo &FuncInfo, const Instruction *FirstNonPHI, int ParentState)
static bool isTopLevelPadForMSVC(const Instruction *EHPad)
static int addSEHExcept(WinEHFuncInfo &FuncInfo, int ParentState, const Function *Filter, const BasicBlock *Handler)
static const uint32_t IV[8]
an instruction to allocate memory on the stack
Represent the analysis usage information of a pass.
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
SymbolTableList< Instruction >::iterator insertInto(BasicBlock *ParentBB, SymbolTableList< Instruction >::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 std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
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 void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
virtual bool doFinalization(Module &)
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
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.
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.
#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,...
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)
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.
void erase_value(Container &C, ValueType V)
Wrapper function to remove a value from a container:
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::@241 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