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) {
224 if (isa<InvokeInst>(TI))
226 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
227 if (CatchSwitch->getParentPad() != ParentPad)
232 auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
233 if (CleanupPad->getParentPad() != ParentPad)
235 return CleanupPad->getParent();
247 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
249 "shouldn't revist catch funclets!");
252 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
253 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
260 CatchSwitch->getParentPad())))
266 int TryHigh = CatchLow - 1;
275 unsigned TBMEIdx = FuncInfo.
TryBlockMap.size() - 1;
277 for (
const auto *CatchPad : Handlers) {
279 for (
const User *U : CatchPad->users()) {
280 const auto *UserI = cast<Instruction>(U);
281 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
282 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
283 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
286 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
291 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
299 FuncInfo.
TryBlockMap[TBMEIdx].CatchHigh = CatchHigh;
309 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
318 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
322 CleanupPad->getParentPad()))) {
327 for (
const User *U : CleanupPad->users()) {
328 const auto *UserI = cast<Instruction>(U);
329 if (UserI->isEHPad())
331 "contain exceptional actions");
339 Entry.ToState = ParentState;
340 Entry.IsFinally =
false;
342 Entry.Handler = Handler;
350 Entry.ToState = ParentState;
351 Entry.IsFinally =
true;
352 Entry.Filter =
nullptr;
353 Entry.Handler = Handler;
367 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
369 "shouldn't revist catch funclets!");
373 assert(CatchSwitch->getNumHandlers() == 1 &&
374 "SEH doesn't have multiple handlers per __try");
375 const auto *CatchPad =
376 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHI());
379 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
382 "unexpected filter value");
388 << CatchPadBB->
getName() <<
'\n');
391 CatchSwitch->getParentPad())))
397 for (
const User *U : CatchPad->users()) {
398 const auto *UserI = cast<Instruction>(U);
399 if (
auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
400 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
401 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
404 if (
auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
409 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
414 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
423 LLVM_DEBUG(
dbgs() <<
"Assigning state #" << CleanupState <<
" to BB "
430 for (
const User *U : CleanupPad->users()) {
431 const auto *UserI = cast<Instruction>(U);
432 if (UserI->isEHPad())
434 "contain exceptional actions");
440 if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
441 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
442 CatchSwitch->unwindsToCaller();
443 if (
auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
444 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
446 if (isa<CatchPadInst>(EHPad))
460 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
478 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
491 Entry.HandlerParentState = HandlerParentState;
492 Entry.TryParentState = TryParentState;
493 Entry.Handler = Handler;
494 Entry.HandlerType = HandlerType;
495 Entry.TypeToken = TypeToken;
532 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
533 const Value *ParentPad;
534 if (
const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI))
535 ParentPad = CPI->getParentPad();
536 else if (
const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI))
537 ParentPad = CSI->getParentPad();
540 if (isa<ConstantTokenNone>(ParentPad))
550 while (!Worklist.
empty()) {
552 int HandlerParentState;
553 std::tie(Pad, HandlerParentState) = Worklist.
pop_back_val();
555 if (
const auto *
Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
559 (
Cleanup->arg_size() ? ClrHandlerType::Fault
560 : ClrHandlerType::Finally);
565 if (
const auto *
I = dyn_cast<Instruction>(U))
573 const auto *CatchSwitch = cast<CatchSwitchInst>(Pad);
574 int CatchState = -1, FollowerState = -1;
579 const auto *
Catch = cast<CatchPadInst>(CatchBlock->getFirstNonPHI());
581 cast<ConstantInt>(
Catch->getArgOperand(0))->getZExtValue());
584 ClrHandlerType::Catch, TypeToken, CatchBlock);
587 if (
const auto *
I = dyn_cast<Instruction>(U))
592 FollowerState = CatchState;
595 assert(CatchSwitch->getNumHandlers());
605 Entry.Handler.get<
const BasicBlock *>()->getFirstNonPHI();
609 if (
const auto *
Catch = dyn_cast<CatchPadInst>(Pad)) {
615 if (Entry.TryParentState != -1)
618 UnwindDest =
Catch->getCatchSwitch()->getUnwindDest();
620 const auto *
Cleanup = cast<CleanupPadInst>(Pad);
621 UnwindDest =
nullptr;
623 if (
auto *CleanupRet = dyn_cast<CleanupReturnInst>(U)) {
626 UnwindDest = CleanupRet->getUnwindDest();
632 if (
auto *Invoke = dyn_cast<InvokeInst>(U)) {
633 UserUnwindDest = Invoke->getUnwindDest();
634 }
else if (
auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) {
635 UserUnwindDest = CatchSwitch->getUnwindDest();
636 }
else if (
auto *ChildCleanup = dyn_cast<CleanupPadInst>(U)) {
638 int UserUnwindState =
640 if (UserUnwindState != -1)
655 const Value *UserUnwindParent;
656 if (
auto *CSI = dyn_cast<CatchSwitchInst>(UserUnwindPad))
657 UserUnwindParent = CSI->getParentPad();
660 cast<CleanupPadInst>(UserUnwindPad)->getParentPad();
664 if (UserUnwindParent ==
Cleanup)
668 UnwindDest = UserUnwindDest;
687 UnwindDestState = -1;
692 Entry.TryParentState = UnwindDestState;
699void WinEHPrepare::colorFunclets(
Function &
F) {
710void WinEHPrepare::demotePHIsOnFunclets(
Function &
F,
711 bool DemoteCatchSwitchPHIOnly) {
717 if (DemoteCatchSwitchPHIOnly && !isa<CatchSwitchInst>(BB.getFirstNonPHI()))
721 auto *PN = dyn_cast<PHINode>(&
I);
728 insertPHIStores(PN, SpillSlot);
734 for (
auto *PN : PHINodes) {
737 PN->eraseFromParent();
741void WinEHPrepare::cloneCommonBlocks(
Function &
F) {
745 for (
auto &Funclets : FuncletBlocks) {
747 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
749 if (FuncletPadBB == &
F.getEntryBlock())
754 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
759 size_t NumColorsForBB = ColorsForBB.
size();
760 if (NumColorsForBB == 1)
764 dbgs() <<
" Cloning block \'" << BB->getName()
765 <<
"\' for funclet \'" << FuncletPadBB->
getName()
779 Orig2Clone.emplace_back(BB, CBB);
783 if (Orig2Clone.empty())
788 for (
auto &BBMapping : Orig2Clone) {
792 BlocksInFunclet.push_back(NewBlock);
794 assert(NewColors.
empty() &&
"A new block should only have one color!");
798 dbgs() <<
" Assigned color \'" << FuncletPadBB->
getName()
799 <<
"\' to block \'" << NewBlock->
getName()
807 dbgs() <<
" Removed color \'" << FuncletPadBB->
getName()
808 <<
"\' from block \'" << OldBlock->
getName()
823 for (
auto &BBMapping : Orig2Clone) {
827 FixupCatchrets.
clear();
829 if (
auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
830 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
834 CatchRet->setSuccessor(NewBlock);
837 auto UpdatePHIOnClonedBlock = [&](
PHINode *PN,
bool IsForOldBlock) {
839 for (
unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
842 bool EdgeTargetsFunclet;
845 EdgeTargetsFunclet = (CRI->getCatchSwitchParentPad() == FuncletToken);
847 ColorVector &IncomingColors = BlockColors[IncomingBlock];
848 assert(!IncomingColors.
empty() &&
"Block not colored!");
851 "Cloning should leave this funclet's blocks monochromatic");
852 EdgeTargetsFunclet = (IncomingColors.
front() == FuncletPadBB);
854 if (IsForOldBlock != EdgeTargetsFunclet)
863 for (
auto &BBMapping : Orig2Clone) {
867 UpdatePHIOnClonedBlock(&OldPN,
true);
870 UpdatePHIOnClonedBlock(&NewPN,
false);
876 for (
auto &BBMapping : Orig2Clone) {
880 for (
PHINode &SuccPN : SuccBB->phis()) {
883 int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock);
884 if (OldBlockIdx == -1)
886 Value *
IV = SuccPN.getIncomingValue(OldBlockIdx);
889 if (
auto *Inst = dyn_cast<Instruction>(
IV)) {
895 SuccPN.addIncoming(
IV, NewBlock);
908 auto *OldI = dyn_cast<Instruction>(
const_cast<Value *
>(VT.first));
911 auto *NewI = cast<Instruction>(VT.second);
917 ColorVector &ColorsForUserBB = BlockColors[UserBB];
919 if (ColorsForUserBB.
size() > 1 ||
920 *ColorsForUserBB.
begin() != FuncletPadBB)
926 if (UsesToRename.
empty())
933 SSAUpdate.
Initialize(OldI->getType(), OldI->getName());
937 while (!UsesToRename.
empty())
943void WinEHPrepare::removeImplausibleInstructions(
Function &
F) {
945 for (
auto &Funclet : FuncletBlocks) {
947 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
949 auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
950 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
951 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
955 auto *CB = dyn_cast<CallBase>(&
I);
959 Value *FuncletBundleOperand =
nullptr;
961 FuncletBundleOperand = BU->Inputs.front();
963 if (FuncletBundleOperand == FuncletPad)
968 dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
969 if (CalledFn && ((CalledFn->isIntrinsic() && CB->doesNotThrow()) ||
974 if (isa<InvokeInst>(CB)) {
979 std::prev(BB->getTerminator()->getIterator());
980 auto *CI = cast<CallInst>(&*CallI);
993 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
995 bool IsUnreachableCatchret =
false;
996 if (
auto *CRI = dyn_cast<CatchReturnInst>(TI))
997 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
999 bool IsUnreachableCleanupret =
false;
1000 if (
auto *CRI = dyn_cast<CleanupReturnInst>(TI))
1001 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
1002 if (IsUnreachableRet || IsUnreachableCatchret ||
1003 IsUnreachableCleanupret) {
1005 }
else if (isa<InvokeInst>(TI)) {
1006 if (Personality == EHPersonality::MSVC_CXX && CleanupPad) {
1017void WinEHPrepare::cleanupPreparedFunclets(
Function &
F) {
1032void WinEHPrepare::verifyPreparedFunclets(
Function &
F) {
1034 size_t NumColors = BlockColors[&BB].size();
1035 assert(NumColors == 1 &&
"Expected monochromatic BB!");
1041 "EH Pad still has a PHI!");
1046bool WinEHPrepare::prepareExplicitEH(
Function &
F) {
1055 cloneCommonBlocks(
F);
1058 demotePHIsOnFunclets(
F, DemoteCatchSwitchPHIOnly ||
1063 removeImplausibleInstructions(
F);
1066 cleanupPreparedFunclets(
F);
1074 BlockColors.clear();
1075 FuncletBlocks.clear();
1092 &
F.getEntryBlock().front());
1104 auto *UsingInst = cast<Instruction>(
U.getUser());
1105 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
1110 replaceUseWithLoad(PN, U, SpillSlot, Loads,
F);
1119void WinEHPrepare::insertPHIStores(
PHINode *OriginalPHI,
1127 while (!Worklist.
empty()) {
1132 PHINode *PN = dyn_cast<PHINode>(InVal);
1141 if (isa<UndefValue>(PredVal))
1150 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1156void WinEHPrepare::insertPHIStore(
1162 Worklist.
push_back({PredBlock, PredVal});
1175 SpillSlot =
new AllocaInst(
V->getType(),
DL->getAllocaAddrSpace(),
nullptr,
1176 Twine(
V->getName(),
".wineh.spillslot"),
1177 &
F.getEntryBlock().front());
1179 auto *UsingInst = cast<Instruction>(
U.getUser());
1180 if (
auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1190 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
1191 if (
auto *CatchRet =
1192 dyn_cast<CatchReturnInst>(IncomingBlock->
getTerminator())) {
1214 CatchRet->removeFromParent();
1215 CatchRet->insertInto(IncomingBlock, IncomingBlock->
end());
1218 CatchRet->setSuccessor(NewBlock);
1223 ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
1224 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
1225 ColorsForNewBlock = ColorsForPHIBlock;
1226 for (
BasicBlock *FuncletPad : ColorsForPHIBlock)
1227 FuncletBlocks[FuncletPad].
push_back(NewBlock);
1229 IncomingBlock = NewBlock;
1235 Twine(
V->getName(),
".wineh.reload"),
1242 Twine(
V->getName(),
".wineh.reload"),
1252 "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.
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
bool hasPersonalityFn() const
Check whether this function has a personality function.
Constant * getPersonalityFn() const
Get the personality function associated with this function.
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.
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.
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 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)
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 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
GlobalVariable * TypeDescriptor
const AllocaInst * Alloca
union llvm::WinEHHandlerType::@239 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
SmallVector< WinEHHandlerType, 1 > HandlerArray