46 using namespace llvm::PatternMatch;
48 #define DEBUG_TYPE "winehprepare"
67 class LandingPadActions;
79 TheTriple =
TM->getTargetTriple();
82 bool runOnFunction(
Function &Fn)
override;
84 bool doFinalization(
Module &M)
override;
88 const char *getPassName()
const override {
89 return "Windows exception handling preparation";
93 bool prepareExceptionHandlers(
Function &
F,
97 void demoteValuesLiveAcrossHandlers(
Function &F,
99 void findSEHEHReturnPoints(
Function &F,
101 void findCXXEHReturnPoints(
Function &F,
105 void completeNestedLandingPad(
Function *ParentFn,
108 FrameVarInfoMap &VarInfo);
113 FrameVarInfoMap &VarInfo);
114 void addStubInvokeToHandlerIfNeeded(
Function *Handler);
116 void mapLandingPadBlocks(
LandingPadInst *LPad, LandingPadActions &Actions);
118 VisitedBlockSet &VisitedBlocks);
119 void findCleanupHandlers(LandingPadActions &Actions,
BasicBlock *StartBB,
130 CatchHandlerMapTy CatchHandlerMap;
131 CleanupHandlerMapTy CleanupHandlerMap;
167 WinEHFrameVariableMaterializer(
Function *OutlinedFn,
Value *ParentFP,
168 FrameVarInfoMap &FrameVarInfo);
169 ~WinEHFrameVariableMaterializer()
override {}
171 Value *materializeValueFor(
Value *V)
override;
173 void escapeCatchObject(
Value *V);
176 FrameVarInfoMap &FrameVarInfo;
180 class LandingPadMap {
182 LandingPadMap() : OriginLPad(
nullptr) {}
185 bool isInitialized() {
return OriginLPad !=
nullptr; }
187 bool isOriginLandingPadBlock(
const BasicBlock *BB)
const;
188 bool isLandingPadSpecificInst(
const Instruction *Inst)
const;
191 Value *SelectorValue)
const;
203 WinEHCloningDirectorBase(
Function *HandlerFn,
Value *ParentFP,
204 FrameVarInfoMap &VarInfo, LandingPadMap &LPadMap)
205 : Materializer(HandlerFn, ParentFP, VarInfo),
208 LPadMap(LPadMap), ParentFP(ParentFP) {}
242 WinEHFrameVariableMaterializer Materializer;
243 Type *SelectorIDType;
245 LandingPadMap &LPadMap;
251 class WinEHCatchDirector :
public WinEHCloningDirectorBase {
255 FrameVarInfoMap &VarInfo, LandingPadMap &LPadMap,
258 : WinEHCloningDirectorBase(CatchFn, ParentFP, VarInfo, LPadMap),
260 ExceptionObjectVar(
nullptr), NestedLPtoOriginalLP(NestedLPads),
261 DT(DT), EHBlocks(EHBlocks) {}
284 Value *getExceptionVar() {
return ExceptionObjectVar; }
288 Value *CurrentSelector;
290 Value *ExceptionObjectVar;
300 class WinEHCleanupDirector :
public WinEHCloningDirectorBase {
303 FrameVarInfoMap &VarInfo, LandingPadMap &LPadMap)
304 : WinEHCloningDirectorBase(CleanupFn, ParentFP, VarInfo,
329 class LandingPadActions {
331 LandingPadActions() : HasCleanupHandlers(
false) {}
333 void insertCatchHandler(
CatchHandler *Action) { Actions.push_back(Action); }
335 Actions.push_back(Action);
336 HasCleanupHandlers =
true;
339 bool includesCleanup()
const {
return HasCleanupHandlers; }
350 bool HasCleanupHandlers;
360 return new WinEHPrepare(TM);
363 bool WinEHPrepare::runOnFunction(
Function &Fn) {
371 if (
auto *LP = BB.getLandingPadInst())
373 if (
auto *Resume = dyn_cast<ResumeInst>(BB.getTerminator()))
388 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
389 LibInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
392 prepareExceptionHandlers(Fn, LPads);
396 bool WinEHPrepare::doFinalization(
Module &M) {
return false; }
398 void WinEHPrepare::getAnalysisUsage(
AnalysisUsage &AU)
const {
411 while (!Worklist.
empty()) {
415 if (StopPoints && StopPoints->
count(BB))
418 if (!ReachableBBs.
insert(BB).second)
423 Worklist.
insert(II->getNormalDest());
441 if (II == FirstNonPHI)
453 while (I == Op0 || I == Op1) {
456 if (I == FirstNonPHI)
460 I = I->getPrevNode();
471 void WinEHPrepare::findCXXEHReturnPoints(
473 for (
auto BBI = F.
begin(), BBE = F.
end(); BBI != BBE; ++BBI) {
476 if (
match(&
I, m_Intrinsic<Intrinsic::eh_begincatch>())) {
488 if (
match(&
I, m_Intrinsic<Intrinsic::eh_endcatch>())) {
493 if (!Br || !Br->isUnconditional() ||
494 isa<PHINode>(Br->getSuccessor(0)->begin())) {
495 DEBUG(
dbgs() <<
"splitting block " << BB->getName()
496 <<
" with llvm.eh.endcatch\n");
500 EHReturnBlocks.
insert(BB->getTerminator()->getSuccessor(0));
512 return (N > 0 && LP->
isCatch(N - 1) &&
513 isa<ConstantPointerNull>(LP->
getClause(N - 1)));
518 void WinEHPrepare::findSEHEHReturnPoints(
520 for (
auto BBI = F.
begin(), BBE = F.
end(); BBI != BBE; ++BBI) {
528 EHReturnBlocks.
insert(BB);
540 <<
" to " << CatchHandler->
getName() <<
'\n');
544 EHReturnBlocks.
insert(CatchHandler);
549 void WinEHPrepare::identifyEHBlocks(
Function &F,
551 DEBUG(
dbgs() <<
"Demoting values live across exception handlers in function "
562 findCXXEHReturnPoints(F, EHReturnBlocks);
564 findSEHEHReturnPoints(F, EHReturnBlocks);
567 dbgs() <<
"identified the following blocks as EH return points:\n";
577 "non-lpad EH return block has phi");
583 Worklist = EHReturnBlocks;
587 dbgs() <<
"marked the following blocks as normal:\n";
595 for (
auto *LPI : LPads)
596 Worklist.insert(LPI->getParent());
599 dbgs() <<
"marked the following blocks as exceptional:\n";
611 void WinEHPrepare::demoteValuesLiveAcrossHandlers(
613 DEBUG(
dbgs() <<
"Demoting values live across exception handlers in function "
617 assert(!NormalBlocks.empty());
633 if (
auto *PN = dyn_cast<PHINode>(U2))
642 bool IsNormalBB = NormalBlocks.
count(&BB);
643 bool IsEHBB = EHBlocks.count(&BB);
644 if (!IsNormalBB && !IsEHBB)
647 for (
Value *Op :
I.operands()) {
649 if (isa<Constant>(Op) || isa<BasicBlock>(Op) || isa<InlineAsm>(Op))
652 if (AI && AI->isStaticAlloca())
655 if (
auto *Arg = dyn_cast<Argument>(Op)) {
657 DEBUG(
dbgs() <<
"Demoting argument " << *Arg
658 <<
" used by EH instr: " <<
I <<
"\n");
665 auto *OpI = cast<Instruction>(Op);
666 if (EHVals.count(OpI))
674 bool IsOpNormalBB = NormalBlocks.count(OpBB);
675 bool IsOpEHBB = EHBlocks.count(OpBB);
676 if (IsNormalBB != IsOpNormalBB || IsEHBB != IsOpEHBB) {
678 dbgs() <<
"Demoting instruction live in-out from EH:\n";
679 dbgs() <<
"Instr: " << *OpI <<
'\n';
680 dbgs() <<
"User: " <<
I <<
'\n';
682 InstrsToDemote.
insert(OpI);
692 Instruction *AllocaInsertPt = F.getEntryBlock().getFirstInsertionPt();
697 for (
Argument *Arg : ArgsToDemote) {
699 Arg->getName() +
".reg2mem", AllocaInsertPt);
703 if (
I && EHBlocks.count(
I->getParent())) {
704 auto *Reload =
new LoadInst(Slot, Arg->getName() +
".reload",
false,
I);
708 new StoreInst(Arg, Slot, AllocaInsertPt);
715 while (
auto *Phi = dyn_cast<PHINode>(BB->
begin()))
719 DEBUG(
dbgs() <<
"Demoted " << InstrsToDemote.size() <<
" instructions and "
720 << ArgsToDemote.size() <<
" arguments for WinEHPrepare\n\n");
723 bool WinEHPrepare::prepareExceptionHandlers(
729 if (
match(&Inst, m_Intrinsic<Intrinsic::eh_actions>()))
733 identifyEHBlocks(F, LPads);
734 demoteValuesLiveAcrossHandlers(F, LPads);
739 FrameVarInfoMap FrameVarInfo;
741 bool HandlersOutlined =
false;
753 SEHExceptionCodeSlot =
754 new AllocaInst(Int8PtrType,
nullptr,
"seh_exception_code",
763 std::sort(LPads.begin(), LPads.end(),
765 return DT->properlyDominates(R->getParent(), L->
getParent());
778 bool LPadHasActionList =
false;
781 if (
match(&Inst, m_Intrinsic<Intrinsic::eh_actions>())) {
782 LPadHasActionList =
true;
789 if (LPadHasActionList)
794 promoteLandingPadValues(LPad);
796 LandingPadActions Actions;
797 mapLandingPadBlocks(LPad, Actions);
799 HandlersOutlined |= !Actions.actions().empty();
801 if (Action->hasBeenProcessed())
803 BasicBlock *StartBB = Action->getStartBlock();
809 if (
auto *CatchAction = dyn_cast<CatchHandler>(Action)) {
810 processSEHCatchHandler(CatchAction, StartBB);
815 outlineHandler(Action, &F, LPad, StartBB, FrameVarInfo);
820 assert(!isa<PHINode>(LPadBB->begin()) &&
"lpad phi not removed");
833 assert(E->getNumIndices() == 1 &&
834 "Unexpected operation: extracting both landing pad values");
836 assert((Idx == 0 || Idx == 1) &&
"unexpected index");
844 E->eraseFromParent();
849 while (!SEHCodeUses.
empty()) {
854 for (
Use *U : Uses) {
855 auto *
I = cast<Instruction>(U->getUser());
856 if (isa<ResumeInst>(
I))
858 if (
auto *Phi = dyn_cast<PHINode>(
I))
861 U->set(
new LoadInst(SEHExceptionCodeSlot,
"sehcode",
false,
I));
868 std::vector<Value *> ActionArgs;
871 if (
auto *CatchAction = dyn_cast<CatchHandler>(Action)) {
873 ActionArgs.push_back(CatchAction->getSelector());
876 int FrameEscapeIdx = -1;
877 Value *EHObj =
const_cast<Value *
>(CatchAction->getExceptionVar());
878 if (EHObj && !isa<ConstantPointerNull>(EHObj)) {
879 auto I = FrameVarInfo.find(EHObj);
880 assert(
I != FrameVarInfo.end() &&
881 "failed to map llvm.eh.begincatch var");
882 FrameEscapeIdx = std::distance(FrameVarInfo.begin(),
I);
888 ActionArgs.push_back(Action->getHandlerBlockOrFunc());
895 if (
auto *CatchAction = dyn_cast<CatchHandler>(Action)) {
896 const auto &CatchTargets = CatchAction->getReturnTargets();
897 ReturnTargets.
insert(CatchTargets.begin(), CatchTargets.end());
908 LPadImpls.
push_back(std::make_pair(Recover, Branch));
914 if (!HandlersOutlined)
920 for (
auto &LPadPair : NestedLPtoOriginalLP)
921 completeNestedLandingPad(&F, LPadPair.first, LPadPair.second, FrameVarInfo);
922 NestedLPtoOriginalLP.clear();
927 for (
auto &LPadImplPair : LPadImpls) {
928 IntrinsicInst *Recover = cast<IntrinsicInst>(LPadImplPair.first);
936 for (
const auto &Action : ActionList) {
937 if (
auto *CA = dyn_cast<CatchHandler>(Action.get())) {
938 Function *Handler = cast<Function>(CA->getHandlerBlockOrFunc());
939 getPossibleReturnTargets(&F, Handler, ReturnTargets);
944 for (
unsigned int I = 0, E = Branch->getNumDestinations();
I < E; ++
I) {
945 BasicBlock *KnownTarget = Branch->getDestination(
I);
946 if (ReturnTargets.
count(KnownTarget))
947 ReturnTargets.
remove(KnownTarget);
950 Branch->addDestination(
Target);
957 if (Br && Br->isUnconditional() &&
958 Br !=
Target->getFirstNonPHIOrDbgOrLifetime()) {
960 if (
match(cast<Value>(Prev), m_Intrinsic<Intrinsic::eh_endcatch>()))
987 if (II && II->getIntrinsicID() == Intrinsic::localescape) {
989 AllocasToEscape.
append(Args.begin(), Args.end());
990 II->eraseFromParent();
997 for (
auto &VarInfoEntry : FrameVarInfo) {
998 Value *ParentVal = VarInfoEntry.first;
1000 AllocaInst *ParentAlloca = cast<AllocaInst>(ParentVal);
1007 AllocasToEscape.
push_back(ParentAlloca);
1011 if (TempAlloca == getCatchObjectSentinel())
1018 Builder.SetInsertPoint(TempAlloca);
1019 Builder.SetCurrentDebugLocation(TempAlloca->getDebugLoc());
1020 Value *RecoverArgs[] = {
1021 Builder.CreateBitCast(&F, Int8PtrType,
""), FP,
1024 Builder.CreateCall(RecoverFrameFn, RecoverArgs);
1027 if (RecoveredAlloca->getType() != TempAlloca->getType()) {
1028 RecoveredAlloca->
setName(
Twine(TempAlloca->getName()) +
".i8");
1029 RecoveredAlloca = cast<Instruction>(
1030 Builder.CreateBitCast(RecoveredAlloca, TempAlloca->getType()));
1032 TempAlloca->replaceAllUsesWith(RecoveredAlloca);
1033 TempAlloca->removeFromParent();
1034 RecoveredAlloca->takeName(TempAlloca);
1042 Builder.CreateCall(FrameEscapeFn, AllocasToEscape);
1044 if (SEHExceptionCodeSlot) {
1047 for (
User *U : SEHExceptionCodeSlot->
users()) {
1048 if (
auto *Inst = dyn_cast<Instruction>(U))
1049 UserBlocks.
insert(Inst->getParent());
1060 CatchHandlerMap.clear();
1062 CleanupHandlerMap.clear();
1063 HandlerToParentFP.clear();
1066 SEHExceptionCodeSlot =
nullptr;
1068 NormalBlocks.clear();
1069 EHReturnBlocks.clear();
1071 return HandlersOutlined;
1074 void WinEHPrepare::promoteLandingPadValues(
LandingPadInst *LPad) {
1084 for (
auto *U : LPad->
users()) {
1089 for (
auto *EU : Extract->
users()) {
1090 if (
auto *
Store = dyn_cast<StoreInst>(EU)) {
1091 auto *AV = cast<AllocaInst>(
Store->getPointerOperand());
1100 if (!EHAllocas.
empty()) {
1107 for (
auto *U : Users)
1111 void WinEHPrepare::getPossibleReturnTargets(
Function *ParentF,
1119 IntrinsicInst *Recover = cast<IntrinsicInst>(LPI->getNextNode());
1122 for (
const auto &Action : ActionList) {
1123 if (
auto *CH = dyn_cast<CatchHandler>(Action.get())) {
1124 Function *NestedF = cast<Function>(
CH->getHandlerBlockOrFunc());
1125 getPossibleReturnTargets(ParentF, NestedF, Targets);
1147 void WinEHPrepare::completeNestedLandingPad(
Function *ParentFn,
1150 FrameVarInfoMap &FrameVarInfo) {
1166 assert(&OutlinedBB->
back() == OutlinedLPad);
1180 const IntrinsicInst *EHActions = cast<IntrinsicInst>(Recover);
1184 SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList;
1186 for (
const auto &Action : ActionList) {
1197 for (
BasicBlock &NestedHandlerBB : *Handler) {
1218 assert(MappedBB->
getParent() == OutlinedHandlerFn);
1220 Ret->eraseFromParent();
1222 ActionTargets.push_back(NewBA);
1232 for (
auto *
Target : ActionTargets)
1242 for (
auto *
Target : ActionTargets)
1262 m_Intrinsic<Intrinsic::eh_typeid_for>(
m_Constant(Selector))) &&
1263 !
match(RHS, m_Intrinsic<Intrinsic::eh_typeid_for>(
m_Constant(Selector))))
1284 if (
match(cast<Value>(II), m_Intrinsic<Intrinsic::eh_begincatch>()))
1303 Builder.
CreateCall(ActionIntrin, {},
"recover");
1314 void WinEHPrepare::addStubInvokeToHandlerIfNeeded(
Function *Handler) {
1334 assert(Ret || Unreached);
1363 Type *ArgTys[2] = {Int8PtrType, Int8PtrType};
1383 Builder.CreateCall(FrameAddressFn, {Builder.getInt32(1)},
"ebp");
1384 Value *ParentI8Fn = Builder.CreateBitCast(ParentFn, Int8PtrType);
1385 ParentFP = Builder.CreateCall(RecoverFPFn, {ParentI8Fn, EBP});
1392 FrameVarInfoMap &VarInfo) {
1401 Handler = createHandlerFunc(SrcFn, Int8PtrType, SrcFn->
getName() +
".catch", M,
1405 SrcFn->
getName() +
".cleanup", M, ParentFP);
1408 HandlerToParentFP[Handler] = ParentFP;
1414 Builder.SetInsertPoint(Entry);
1415 Builder.SetCurrentDebugLocation(LPad->
getDebugLoc());
1417 std::unique_ptr<WinEHCloningDirectorBase> Director;
1421 LandingPadMap &LPadMap = LPadMaps[LPad];
1422 if (!LPadMap.isInitialized())
1423 LPadMap.mapLandingPad(LPad);
1424 if (
auto *CatchAction = dyn_cast<CatchHandler>(Action)) {
1425 Constant *Sel = CatchAction->getSelector();
1426 Director.reset(
new WinEHCatchDirector(Handler, ParentFP, Sel, VarInfo,
1427 LPadMap, NestedLPtoOriginalLP, DT,
1433 new WinEHCleanupDirector(Handler, ParentFP, VarInfo, LPadMap));
1443 while (
auto *PN = dyn_cast<PHINode>(II)) {
1444 bool Mapped =
false;
1446 for (
Value *Val : PN->incoming_values()) {
1447 if (VMap.
count(Val)) {
1448 VMap[PN] = VMap[Val];
1468 &OutlinedFunctionInfo, Director.get());
1480 assert(ClonedEntryBB);
1485 addStubInvokeToHandlerIfNeeded(Handler);
1487 if (
auto *CatchAction = dyn_cast<CatchHandler>(Action)) {
1488 WinEHCatchDirector *CatchDirector =
1489 reinterpret_cast<WinEHCatchDirector *
>(Director.get());
1490 CatchAction->setExceptionVar(CatchDirector->getExceptionVar());
1491 CatchAction->setReturnTargets(CatchDirector->getReturnTargets());
1502 for (
const auto MapEntry : VMap) {
1505 if (!isa<BasicBlock>(MapEntry.first) || MapEntry.second ==
nullptr)
1507 const BasicBlock *MappedBB = cast<BasicBlock>(MapEntry.first);
1508 for (
auto *Pred :
predecessors(const_cast<BasicBlock *>(MappedBB))) {
1510 if (!Branch || !Branch->isUnconditional() || Pred->size() <= 1)
1514 if (
match(cast<Value>(II), m_Intrinsic<Intrinsic::eh_endcatch>())) {
1517 assert(!LPadTargetBlocks.count(MappedBB));
1518 LPadTargetBlocks[MappedBB] = cast<BasicBlock>(MapEntry.second);
1532 void WinEHPrepare::processSEHCatchHandler(CatchHandler *CatchAction,
1544 "expected catch EH dispatch");
1550 IRBuilder<> Builder(HandlerBB->getFirstInsertionPt());
1553 Value *
Code = Builder.CreateCall(EHCodeFn, {},
"sehcode");
1554 Code = Builder.CreateIntToPtr(Code, SEHExceptionCodeSlot->getAllocatedType());
1555 Builder.CreateStore(Code, SEHExceptionCodeSlot);
1564 assert(OriginLPad ==
nullptr || OriginLPad == LPad);
1567 if (OriginLPad == LPad)
1576 for (
auto *U : LPad->
users()) {
1581 "Unexpected operation: extracting both landing pad values");
1582 unsigned int Idx = *(Extract->
idx_begin());
1583 assert((Idx == 0 || Idx == 1) &&
1584 "Unexpected operation: extracting an unknown landing pad element");
1586 ExtractedEHPtrs.push_back(Extract);
1587 }
else if (Idx == 1) {
1588 ExtractedSelectors.push_back(Extract);
1593 bool LandingPadMap::isOriginLandingPadBlock(
const BasicBlock *BB)
const {
1597 bool LandingPadMap::isLandingPadSpecificInst(
const Instruction *Inst)
const {
1598 if (Inst == OriginLPad)
1600 for (
auto *Extract : ExtractedEHPtrs) {
1601 if (Inst == Extract)
1604 for (
auto *Extract : ExtractedSelectors) {
1605 if (Inst == Extract)
1612 Value *SelectorValue)
const {
1614 for (
auto *Extract : ExtractedEHPtrs)
1615 VMap[Extract] = EHPtrValue;
1616 for (
auto *Extract : ExtractedSelectors)
1617 VMap[Extract] = SelectorValue;
1621 return match(const_cast<Value *>(V), m_Intrinsic<Intrinsic::localaddress>());
1628 if (LPadMap.isLandingPadSpecificInst(Inst))
1636 if (
auto *LPad = dyn_cast<LandingPadInst>(Inst)) {
1637 return handleLandingPad(VMap, LPad, NewBB);
1643 if (
auto *IBr = dyn_cast<IndirectBrInst>(Inst)) {
1644 return handleIndirectBr(VMap, IBr, NewBB);
1647 if (
auto *Invoke = dyn_cast<InvokeInst>(Inst))
1648 return handleInvoke(VMap, Invoke, NewBB);
1650 if (
auto *Resume = dyn_cast<ResumeInst>(Inst))
1651 return handleResume(VMap, Resume, NewBB);
1653 if (
auto *Cmp = dyn_cast<CmpInst>(Inst))
1654 return handleCompare(VMap, Cmp, NewBB);
1656 if (
match(Inst, m_Intrinsic<Intrinsic::eh_begincatch>()))
1657 return handleBeginCatch(VMap, Inst, NewBB);
1658 if (
match(Inst, m_Intrinsic<Intrinsic::eh_endcatch>()))
1659 return handleEndCatch(VMap, Inst, NewBB);
1660 if (
match(Inst, m_Intrinsic<Intrinsic::eh_typeid_for>()))
1661 return handleTypeIdFor(VMap, Inst, NewBB);
1666 VMap[Inst] = ParentFP;
1683 if (
match(NextI, m_Intrinsic<Intrinsic::eh_actions>()))
1694 NestedLPtoOriginalLP[cast<LandingPadInst>(NewInst)] = LPad;
1695 VMap[LPad] = NewInst;
1712 assert(ExceptionObjectVar ==
nullptr &&
"Multiple calls to "
1713 "llvm.eh.begincatch found while "
1714 "outlining catch handler.");
1716 if (isa<ConstantPointerNull>(ExceptionObjectVar))
1718 assert(cast<AllocaInst>(ExceptionObjectVar)->isStaticAlloca() &&
1719 "catch parameter is not static alloca");
1720 Materializer.escapeCatchObject(ExceptionObjectVar);
1738 auto *ParentBB = IntrinCall->
getParent();
1739 if (ParentBB->isLandingPad() && !LPadMap.isOriginLandingPadBlock(ParentBB))
1752 ContinueBB =
SplitBlock(const_cast<BasicBlock *>(ParentBB),
1753 const_cast<Instruction *>(cast<Instruction>(Next)));
1759 ReturnTargets.push_back(ContinueBB);
1773 if (Selector == CurrentSelector)
1795 NestedLPtoOriginalLP[cast<LandingPadInst>(VMap[LPad])] = LPad;
1805 if (EHBlocks.count(const_cast<BasicBlock*>(TargetBB)) &&
1806 DT->dominates(ParentBB, TargetBB)) {
1807 DEBUG(
dbgs() <<
" Adding destination " << TargetBB->getName() <<
"\n");
1808 ReturnTargets.insert(TargetBB);
1813 ReturnTargets.size(), NewBB);
1814 for (
auto *
Target : ReturnTargets)
1843 if (
match(Compare->
getOperand(0), m_Intrinsic<Intrinsic::eh_typeid_for>())) {
1846 m_Intrinsic<Intrinsic::eh_typeid_for>())) {
1871 VMap[LPad] = NewInst;
1903 CatchHandler, Selector, NextBB)) {
1931 VMap[Invoke] = NewCall;
1960 if (
match(Compare->
getOperand(0), m_Intrinsic<Intrinsic::eh_typeid_for>()) ||
1961 match(Compare->
getOperand(1), m_Intrinsic<Intrinsic::eh_typeid_for>())) {
1968 WinEHFrameVariableMaterializer::WinEHFrameVariableMaterializer(
1969 Function *OutlinedFn,
Value *ParentFP, FrameVarInfoMap &FrameVarInfo)
1970 : FrameVarInfo(FrameVarInfo), Builder(OutlinedFn->getContext()) {
1976 if (
auto *FPInst = dyn_cast<Instruction>(ParentFP))
1978 Builder.SetInsertPoint(EntryBB, InsertPoint);
1981 Value *WinEHFrameVariableMaterializer::materializeValueFor(
Value *V) {
1986 if (
auto *AV = dyn_cast<AllocaInst>(V)) {
1987 assert(AV->isStaticAlloca() &&
1988 "cannot materialize un-demoted dynamic alloca");
1990 Builder.Insert(NewAlloca, AV->getName());
1991 FrameVarInfo[AV].push_back(NewAlloca);
1995 if (isa<Instruction>(V) || isa<Argument>(V)) {
1996 Function *Parent = isa<Instruction>(V)
1997 ? cast<Instruction>(V)->
getParent()->getParent()
2000 <<
"Failed to demote instruction used in exception handler of function "
2001 << GlobalValue::getRealLinkageName(Parent->
getName()) <<
":\n";
2002 errs() <<
" " << *V <<
'\n';
2010 void WinEHFrameVariableMaterializer::escapeCatchObject(
Value *V) {
2016 FrameVarInfo[V].push_back(getCatchObjectSentinel());
2048 LandingPadActions &Actions) {
2050 unsigned int HandlersFound = 0;
2055 if (NumClauses == 0) {
2056 findCleanupHandlers(Actions, BB,
nullptr);
2060 VisitedBlockSet VisitedBlocks;
2062 while (HandlersFound != NumClauses) {
2066 if (LPad->
isFilter(HandlersFound)) {
2075 if (isa<ConstantPointerNull>(ExpectedSelector)) {
2077 assert(HandlersFound == NumClauses - 1);
2084 DEBUG(
dbgs() <<
" Found extra catch dispatch in block "
2085 << CatchBlock->
getName() <<
"\n");
2090 CatchHandler *Action =
nullptr;
2091 if (CatchHandlerMap.count(BB) && CatchHandlerMap[BB] !=
nullptr) {
2093 Action = CatchHandlerMap[BB];
2094 assert(Action->
getSelector() == ExpectedSelector);
2100 Action = findCatchHandler(BB, NextBB, VisitedBlocks);
2107 if (Personality == EHPersonality::MSVC_CXX)
2108 findCleanupHandlers(Actions, BB, BB);
2116 Action =
new CatchHandler(BB, ExpectedSelector,
nullptr);
2117 CatchHandlerMap[BB] = Action;
2120 Actions.insertCatchHandler(Action);
2129 CatchHandler *CatchAction = findCatchHandler(BB, NextBB, VisitedBlocks);
2130 assert(CatchAction);
2133 findCleanupHandlers(Actions, BB, CatchAction->
getStartBlock());
2142 DEBUG(
dbgs() <<
" Found catch dispatch in block "
2144 Actions.insertCatchHandler(CatchAction);
2152 if (isa<ConstantPointerNull>(
2154 DEBUG(
dbgs() <<
" Applying early catch-all handler in block "
2156 <<
" to all remaining clauses.\n");
2157 Actions.insertCatchHandler(CatchAction);
2161 DEBUG(
dbgs() <<
" Found extra catch dispatch in block "
2171 findCleanupHandlers(Actions, BB, BB);
2178 if (Actions.includesCleanup() && !LPad->
isCleanup())
2187 CatchHandler *WinEHPrepare::findCatchHandler(
BasicBlock *BB,
2189 VisitedBlockSet &VisitedBlocks) {
2193 if (CatchHandlerMap.count(BB) && CatchHandlerMap[BB] !=
nullptr) {
2194 CatchHandler *Action = cast<CatchHandler>(CatchHandlerMap[BB]);
2202 VisitedBlocks.insert(BB);
2209 if (!CatchHandlerMap.count(BB)) {
2211 CatchHandler *Action =
new CatchHandler(BB, Selector, NextBB);
2212 CatchHandlerMap[BB] = Action;
2222 Constant *NullSelector = ConstantPointerNull::get(Int8PtrTy);
2223 CatchHandler *Action =
new CatchHandler(BB, NullSelector,
nullptr);
2224 CatchHandlerMap[BB] = Action;
2233 if (VisitedBlocks.count(Succ))
2236 CatchHandler *Action = findCatchHandler(Succ, NextBB, VisitedBlocks);
2245 CleanupHandlerMapTy &CleanupHandlerMap,
2248 CleanupHandlerMap[BB] = Action;
2249 Actions.insertCleanupHandler(Action);
2250 DEBUG(
dbgs() <<
" Found cleanup code in block "
2262 if (!FinallyCall || FinallyCall.
arg_size() != 2)
2275 if (Br && Br->isUnconditional())
2276 BB = Br->getSuccessor(0);
2287 void WinEHPrepare::findCleanupHandlers(LandingPadActions &Actions,
2312 if (CleanupHandlerMap.count(BB)) {
2313 if (
auto *Action = CleanupHandlerMap[BB]) {
2314 Actions.insertCleanupHandler(Action);
2315 DEBUG(
dbgs() <<
" Found cleanup code in block "
2332 if (SuccBB == BB || SuccBB == EndBB)
2342 CleanupHandlerMap[BB] =
nullptr;
2347 LandingPadMap *LPadMap =
nullptr;
2348 if (BB->isLandingPad()) {
2350 LPadMap = &LPadMaps[LPad];
2351 if (!LPadMap->isInitialized())
2352 LPadMap->mapLandingPad(LPad);
2359 if (
auto *Resume = dyn_cast<ResumeInst>(Terminator)) {
2366 if (!isa<PHINode>(ResumeVal) && !isa<LandingPadInst>(ResumeVal)) {
2377 if (LPadMap && LPadMap->isLandingPadSpecificInst(Inst))
2379 if (Inst == Insert1 || Inst == Insert2 || Inst == Resume)
2401 if (LPadMap && LPadMap->isLandingPadSpecificInst(Inst))
2403 if (Inst == Compare || Inst == Branch)
2405 if (
match(Inst, m_Intrinsic<Intrinsic::eh_typeid_for>()))
2410 assert(BB == EndBB);
2417 Instruction *MaybeCall = BB->getFirstNonPHIOrDbg();
2419 while (MaybeCall != BB->getTerminator() &&
2420 LPadMap->isLandingPadSpecificInst(MaybeCall))
2426 if (TheTriple.getArch() == Triple::x86_64) {
2428 Function *Fin = FinallyCall.getCalledFunction();
2429 assert(Fin &&
"outlined finally call should be direct");
2432 Actions.insertCleanupHandler(Action);
2433 CleanupHandlerMap[BB] = Action;
2434 DEBUG(
dbgs() <<
" Found frontend-outlined finally call to "
2435 << Fin->
getName() <<
" in block "
2441 if (FinallyCall.getInstruction() != BB->getTerminator() &&
2442 FinallyCall.getInstruction()->getNextNode() !=
2443 BB->getTerminator()) {
2445 SplitBlock(BB, FinallyCall.getInstruction()->getNextNode(), DT);
2447 if (FinallyCall.isInvoke()) {
2448 SuccBB = cast<InvokeInst>(FinallyCall.getInstruction())
2451 SuccBB = BB->getUniqueSuccessor();
2453 "splitOutlinedFinallyCalls didn't insert a branch");
2468 if (LPadMap && LPadMap->isLandingPadSpecificInst(Inst))
2474 if (
match(Inst, m_Intrinsic<Intrinsic::eh_begincatch>()))
2477 if (
match(Inst, m_Intrinsic<Intrinsic::eh_endcatch>()))
2497 "attempted to parse non eh.actions intrinsic");
2499 uint64_t ActionKind =
2501 if (ActionKind == 1) {
2507 auto CH = make_unique<CatchHandler>(
nullptr, Selector,
2509 CH->setHandlerBlockOrFunc(Handler);
2510 CH->setExceptionVarIndex(EHObjIndexVal);
2511 Actions.push_back(std::move(
CH));
2512 }
else if (ActionKind == 0) {
2515 auto CH = make_unique<CleanupHandler>(
nullptr);
2516 CH->setHandlerBlockOrFunc(Handler);
2517 Actions.push_back(std::move(
CH));
2522 std::reverse(Actions.begin(), Actions.end());
2526 struct WinEHNumbering {
2527 WinEHNumbering(
WinEHFuncInfo &FuncInfo) : FuncInfo(FuncInfo),
2528 CurrentBaseState(-1), NextState(0) {}
2531 int CurrentBaseState;
2534 SmallVector<std::unique_ptr<ActionHandler>, 4> HandlerStack;
2537 int currentEHNumber()
const {
2538 return HandlerStack.
empty() ? CurrentBaseState : HandlerStack.back()->getEHState();
2542 void createTryBlockMapEntry(
int TryLow,
int TryHigh,
2544 void processCallSite(
MutableArrayRef<std::unique_ptr<ActionHandler>> Actions,
2546 void popUnmatchedActions(
int FirstMismatch);
2547 void calculateStateNumbers(
const Function &F);
2548 void findActionRootLPads(
const Function &F);
2552 void WinEHNumbering::createUnwindMapEntry(
int ToState,
ActionHandler *AH) {
2555 if (
auto *CH = dyn_cast_or_null<CleanupHandler>(AH))
2556 UME.
Cleanup = cast<Function>(
CH->getHandlerBlockOrFunc());
2559 FuncInfo.UnwindMap.push_back(UME);
2562 void WinEHNumbering::createTryBlockMapEntry(
int TryLow,
int TryHigh,
2567 int NumHandlers = Handlers.
size();
2568 auto I = FuncInfo.TryBlockMap.begin();
2569 auto E = FuncInfo.TryBlockMap.end();
2570 for ( ;
I != E; ++
I) {
2572 if (Entry.HandlerArray.
size() != (size_t)NumHandlers)
2575 for (N = 0; N < NumHandlers; ++
N) {
2576 if (Entry.HandlerArray[N].Handler != Handlers[N]->getHandlerBlockOrFunc())
2580 if (N == NumHandlers) {
2597 FuncInfo.TryBlockMap.erase(
I);
2598 FuncInfo.TryBlockMap.push_back(Entry);
2607 for (CatchHandler *CH : Handlers) {
2609 if (
CH->getSelector()->isNullValue()) {
2613 auto *GV = cast<GlobalVariable>(
CH->getSelector()->stripPointerCasts());
2616 auto *
CS = cast<ConstantStruct>(GV->getInitializer());
2618 cast<ConstantInt>(CS->getAggregateElement(0U))->getZExtValue();
2620 cast<GlobalVariable>(CS->getAggregateElement(1)->stripPointerCasts());
2622 HT.
Handler = cast<Function>(
CH->getHandlerBlockOrFunc());
2626 FuncInfo.TryBlockMap.push_back(TBME);
2636 if (
const auto *F = dyn_cast<Function>(V))
2643 void WinEHNumbering::processCallSite(
2646 DEBUG(
dbgs() <<
"processCallSite (EH state = " << currentEHNumber()
2652 for (
int I = 0, E = HandlerStack.size();
I < E; ++
I) {
2654 print_name(HandlerStack[
I]->getHandlerBlockOrFunc());
2658 for (
int I = 0, E = Actions.size();
I < E; ++
I) {
2663 int FirstMismatch = 0;
2664 for (
int E =
std::min(HandlerStack.size(), Actions.size()); FirstMismatch < E;
2666 if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
2667 Actions[FirstMismatch]->getHandlerBlockOrFunc())
2672 popUnmatchedActions(FirstMismatch);
2674 DEBUG(
dbgs() <<
"Pushing actions for CallSite: ");
2678 bool LastActionWasCatch =
false;
2680 for (
size_t I = FirstMismatch;
I != Actions.size(); ++
I) {
2682 bool CurrActionIsCatch = isa<CatchHandler>(Actions[
I].get());
2683 auto *Handler = cast<Function>(Actions[
I]->getHandlerBlockOrFunc());
2687 if (FuncInfo.HandlerEnclosedState.count(Handler)) {
2689 Actions[
I]->setEHState(FuncInfo.HandlerEnclosedState[Handler]);
2693 if (CurrActionIsCatch && LastActionWasCatch && RootLPad == LastRootLPad) {
2694 DEBUG(
dbgs() <<
"setEHState for handler to " << currentEHNumber() <<
"\n");
2695 Actions[
I]->setEHState(currentEHNumber());
2697 DEBUG(
dbgs() <<
"createUnwindMapEntry(" << currentEHNumber() <<
", ");
2699 DEBUG(
dbgs() <<
") with EH state " << NextState <<
"\n");
2700 createUnwindMapEntry(currentEHNumber(), Actions[
I].
get());
2701 DEBUG(
dbgs() <<
"setEHState for handler to " << NextState <<
"\n");
2702 Actions[
I]->setEHState(NextState);
2705 HandlerStack.push_back(std::move(Actions[
I]));
2706 LastActionWasCatch = CurrActionIsCatch;
2707 LastRootLPad = RootLPad;
2713 for (
int I = 0, E = HandlerStack.size();
I < E; ++
I) {
2714 auto *Handler = cast<Function>(HandlerStack[
I]->getHandlerBlockOrFunc());
2715 if (FuncInfo.LastInvoke[Handler] != cast<InvokeInst>(CS.
getInstruction()))
2717 FuncInfo.LastInvokeVisited[Handler] =
true;
2720 DEBUG(
dbgs() <<
" has been visited.\n");
2724 DEBUG(
dbgs() <<
"In EHState " << currentEHNumber() <<
" for CallSite: ");
2729 void WinEHNumbering::popUnmatchedActions(
int FirstMismatch) {
2733 for (
int I = HandlerStack.size() - 1;
I >= FirstMismatch; --
I) {
2734 std::unique_ptr<ActionHandler> Handler = HandlerStack.
pop_back_val();
2735 if (isa<CatchHandler>(Handler.get()))
2736 PoppedCatches.
push_back(cast<CatchHandler>(Handler.release()));
2739 int TryHigh = NextState - 1;
2740 int LastTryLowIdx = 0;
2741 for (
int I = 0, E = PoppedCatches.
size();
I != E; ++
I) {
2742 CatchHandler *
CH = PoppedCatches[
I];
2744 if (
I + 1 == E || CH->
getEHState() != PoppedCatches[
I + 1]->getEHState()) {
2747 makeArrayRef(&PoppedCatches[LastTryLowIdx],
I - LastTryLowIdx + 1);
2748 DEBUG(
dbgs() <<
"createTryBlockMapEntry(" << TryLow <<
", " << TryHigh);
2749 for (
size_t J = 0; J < Handlers.size(); ++J) {
2751 print_name(Handlers[J]->getHandlerBlockOrFunc());
2754 createTryBlockMapEntry(TryLow, TryHigh, Handlers);
2755 LastTryLowIdx =
I + 1;
2759 for (CatchHandler *CH : PoppedCatches) {
2761 if (FuncInfo.LastInvokeVisited[F]) {
2762 DEBUG(
dbgs() <<
"Assigning base state " << NextState <<
" to ");
2765 FuncInfo.HandlerBaseState[
F] = NextState;
2766 DEBUG(
dbgs() <<
"createUnwindMapEntry(" << currentEHNumber()
2768 createUnwindMapEntry(currentEHNumber(),
nullptr);
2770 calculateStateNumbers(*F);
2773 DEBUG(
dbgs() <<
"Deferring handling of ");
2775 DEBUG(
dbgs() <<
" until last invoke visited.\n");
2782 void WinEHNumbering::calculateStateNumbers(
const Function &F) {
2783 auto I = VisitedHandlers.insert(&F);
2787 int OldBaseState = CurrentBaseState;
2788 if (FuncInfo.HandlerBaseState.count(&F)) {
2789 CurrentBaseState = FuncInfo.HandlerBaseState[&
F];
2792 size_t SavedHandlerStackSize = HandlerStack.size();
2795 SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList;
2799 if (!CI || CI->doesNotThrow())
2801 processCallSite(
None, CI);
2811 if (ActionList.empty())
2813 processCallSite(ActionList, II);
2815 FuncInfo.LandingPadStateMap[LPI] = currentEHNumber();
2816 DEBUG(
dbgs() <<
"Assigning state " << currentEHNumber()
2822 popUnmatchedActions(SavedHandlerStackSize);
2824 DEBUG(
dbgs() <<
"Assigning max state " << NextState - 1
2825 <<
" to " << F.getName() <<
'\n');
2826 FuncInfo.CatchHandlerMaxState[&
F] = NextState - 1;
2828 CurrentBaseState = OldBaseState;
2834 void WinEHNumbering::findActionRootLPads(
const Function &F) {
2835 auto I = VisitedHandlers.insert(&F);
2839 SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList;
2849 assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions);
2851 if (ActionList.
empty())
2853 for (
int I = 0, E = ActionList.
size();
I < E; ++
I) {
2855 = dyn_cast<Function>(ActionList[
I]->getHandlerBlockOrFunc())) {
2856 FuncInfo.LastInvoke[Handler] = II;
2859 if (FuncInfo.RootLPad.count(Handler) &&
2860 FuncInfo.RootLPad[Handler]->getParent()->getParent() != &
F)
2862 DEBUG(
dbgs() <<
"Setting root lpad for ");
2865 FuncInfo.RootLPad[Handler] = LPI;
2871 for (
int I = 0, E = ActionList.
size();
I < E; ++
I)
2873 = dyn_cast<Function>(ActionList[
I]->getHandlerBlockOrFunc()))
2874 findActionRootLPads(*Handler);
2885 WinEHNumbering Num(FuncInfo);
2886 Num.findActionRootLPads(*ParentFn);
2889 Num.VisitedHandlers.clear();
2890 Num.calculateStateNumbers(*ParentFn);
2894 while (!Num.HandlerStack.empty())
void DeleteContainerSeconds(Container &C)
In a container of pairs (usually a map) whose second element is a pointer, deletes the second element...
void setPersonalityFn(Constant *C)
ReturnInst - Return a value (possibly void), from a function.
ActionType getType() const
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
AllocaInst * DemoteRegToStack(Instruction &X, bool VolatileLoads=false, Instruction *AllocaPoint=nullptr)
DemoteRegToStack - This function takes a virtual register computed by an Instruction and replaces it ...
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
This class is the base class for the comparison instructions.
iterator_range< use_iterator > uses()
SmallVector< WinEHHandlerType, 1 > HandlerArray
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, const Instruction *StartingInst, ValueToValueMapTy &VMap, bool ModuleLevelChanges, SmallVectorImpl< ReturnInst * > &Returns, const char *NameSuffix="", ClonedCodeInfo *CodeInfo=nullptr, CloningDirector *Director=nullptr)
This works like CloneAndPruneFunctionInto, except that it does not clone the entire function...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
LLVM Argument representation.
Value * getAggregateOperand()
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
const Instruction & back() const
BasicBlock * SplitBlock(BasicBlock *Old, Instruction *SplitPt, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
SplitBlock - Split the specified block at the specified instruction - every thing before SplitPt stay...
ValTy * getArgument(unsigned ArgNo) const
A Module instance is used to store all the information related to an LLVM module. ...
Constant * getClause(unsigned Idx) const
Get the value of the clause at index Idx.
InstrTy * getInstruction() const
Intrinsic::ID getIntrinsicID() const
getIntrinsicID - Return the intrinsic ID of this intrinsic.
static Instruction * findBeginCatchSplitPoint(BasicBlock *BB, IntrinsicInst *II)
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
CallInst - This class represents a function call, abstracting a target machine's calling convention...
static CallSite matchOutlinedFinallyCall(BasicBlock *BB, Instruction *MaybeCall)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
FunctionPass * createWinEHPass(const TargetMachine *TM)
createWinEHPass - Prepares personality functions used by MSVC on Windows, in addition to the Itanium ...
const_iterator begin(StringRef path)
Get begin iterator over path.
This class implements a map that also provides access to all stored values in a deterministic order...
const Function * getParent() const
Return the enclosing method, or null if none.
bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr)
SimplifyInstructionsInBlock - Scan the specified basic block and try to simplify any instructions in ...
LoadInst - an instruction for reading from memory.
iv Induction Variable Users
INITIALIZE_TM_PASS(WinEHPrepare,"winehprepare","Prepare Windows exceptions", false, false) FunctionPass *llvm
TinyPtrVector - This class is specialized for cases where there are normally 0 or 1 element in a vect...
BasicBlock * getNextBB() const
size_type size() const
Determine the number of elements in the SetVector.
bool isEquality() const
This is just a convenience that dispatches to the subclasses.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
static bool isSelectorDispatch(BasicBlock *BB, BasicBlock *&CatchHandler, Constant *&Selector, BasicBlock *&NextBB)
StringRef getName() const
Return a constant reference to the value's name.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
iterator begin()
Instruction iterator methods.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
Instruction * getFirstNonPHIOrDbg()
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic...
BlockAddress - The address of a basic block.
bool match(Val *V, const Pattern &P)
static bool isCatchAllLandingPad(const BasicBlock *BB)
AnalysisUsage & addRequired()
bool isUnconditional() const
void push_back(NodeTy *val)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
NodeTy * getNextNode()
Get the next node, or 0 for the list tail.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A Use represents the edge between a Value definition and its users.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
unsigned getNumArgOperands() const
getNumArgOperands - Return the number of call arguments.
Instruction * getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const Value * getCalledValue() const
getCalledValue - Get a pointer to the function that is invoked by this instruction ...
NodeTy * getPrevNode()
Get the previous node, or 0 for the list head.
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
void setName(const Twine &Name)
Change the name of the value.
Instruction * clone() const
clone() - Create a copy of 'this' instruction that is identical in all ways except the following: ...
bool remove(const value_type &X)
Remove an item from the set vector.
BasicBlock * getDestination(unsigned i)
getDestination - Return the specified destination.
void addFnAttr(Attribute::AttrKind N)
Add function attributes to this function.
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
void setHandlerBlockOrFunc(Constant *F)
void PromoteMemToReg(ArrayRef< AllocaInst * > Allocas, DominatorTree &DT, AliasSetTracker *AST=nullptr, AssumptionCache *AC=nullptr)
Promote the specified list of alloca instructions into scalar registers, inserting PHI nodes as appro...
FunctionType - Class to represent function types.
void setCleanup(bool V)
setCleanup - Indicate that this landingpad instruction is a cleanup.
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
ValTy * getCalledValue() const
getCalledValue - Return the pointer to function that is being called.
UnreachableInst * CreateUnreachable()
BasicBlock * getSuccessor(unsigned i) const
bool empty() const
Determine if the SetVector is empty or not.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
FunctionType::get - This static method is the primary way of constructing a FunctionType.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
unsigned getNumClauses() const
getNumClauses - Get the number of clauses for this landing pad.
StoreInst - an instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
size_t size() const
size - Get the array size.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
BasicBlock * getNormalDest() const
PointerType - Class to represent pointers.
Interval::succ_iterator succ_end(Interval *I)
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
A helper class used with CloneAndPruneIntoFromInst to change the default behavior while instructions ...
DenseMap< const LandingPadInst *, int > LandingPadStateMap
BasicBlock * SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions())
SplitCriticalEdge - If this edge is a critical edge, insert a new node to split the critical edge...
bool isFilter(unsigned Idx) const
isFilter - Return 'true' if the clause and index Idx is a filter clause.
ValueMaterializer - This is a class that can be implemented by clients to materialize Values on deman...
friend const_iterator end(StringRef path)
Get end iterator over path.
LandingPadInst - The landingpad instruction holds all of the information necessary to generate correc...
Subclasses of this class are all able to terminate a basic block.
Constant * stripPointerCasts()
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
BranchInst - Conditional or Unconditional Branch instruction.
static BlockAddress * get(Function *F, BasicBlock *BB)
get - Return a BlockAddress for the specified function and basic block.
UnreachableInst - This function has undefined behavior.
This is an important base class in LLVM.
ResumeInst - Resume the propagation of an exception.
Continue cloning the instruction (default behavior).
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
IndirectBrInst - Indirect Branch Instruction.
LandingPadInst * getLandingPadInst()
Return the landingpad instruction associated with the landing pad.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
const DebugLoc & getDebugLoc() const
getDebugLoc - Return the debug location for this node as a DebugLoc.
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
brc_match< Cond_t > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
const InstListType & getInstList() const
Return the underlying instruction list container.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
bool pred_empty(const BasicBlock *BB)
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
static UndefValue * get(Type *T)
get() - Static factory methods - Return an 'undef' object of the specified type.
bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr)
RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a trivially dead instruction...
CallInst * CreateCall(Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="")
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
static void findReachableBlocks(SmallPtrSetImpl< BasicBlock * > &ReachableBBs, SetVector< BasicBlock * > &Worklist, const SetVector< BasicBlock * > *StopPoints)
static IndirectBrInst * Create(Value *Address, unsigned NumDests, Instruction *InsertBefore=nullptr)
Triple - Helper class for working with autoconf configuration names.
CallingConv::ID getCallingConv() const
getCallingConv/setCallingConv - Get or set the calling convention of this function call...
void dump() const
Support for debugging, callable in GDB: V->dump()
bool isConditional() const
void calculateWinCXXEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which describes the state number...
static InvokeInst * Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
const BasicBlockListType & getBasicBlockList() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
StructType::get - This static method is the primary way to create a literal StructType.
friend const_iterator begin(StringRef path)
Get begin iterator over path.
Constant * getHandlerBlockOrFunc()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Instruction * user_back()
user_back - Specialize the methods defined in Value, as we know that an instruction can only be used ...
static BasicBlock * followSingleUnconditionalBranches(BasicBlock *BB)
Provides information about what library functions are available for the current target.
void push_front(NodeTy *val)
unsigned arg_size() const
BasicBlock * getBasicBlock() const
Value * stripPointerCasts()
Strip off pointer casts, all-zero GEPs, and aliases.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
static void createCleanupHandler(LandingPadActions &Actions, CleanupHandlerMapTy &CleanupHandlerMap, BasicBlock *BB)
pred_range predecessors(BasicBlock *BB)
const BasicBlock & getEntryBlock() const
bool isNullValue() const
isNullValue - Return true if this is the value that would be returned by getNullValue.
void splice(iterator where, iplist &L2)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
Target - Wrapper for Target specific information.
static void print_name(const Value *V)
iterator_range< user_iterator > users()
BasicBlock * getSinglePredecessor()
Return the predecessor of this block if it has a single predecessor block.
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
RemapInstruction - Convert the instruction operands from referencing the current values into those sp...
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Skip this instruction and stop cloning the current basic block.
GlobalVariable * TypeDescriptor
static bool isLocalAddressCall(const Value *V)
Don't clone the terminator but clone the current block's successors.
Value * getCondition() const
const AttributeSet & getAttributes() const
getAttributes - Return the parameter attributes for this invoke.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
static IntegerType * getInt32Ty(LLVMContext &C)
void setReturnTargets(TinyPtrVector< BasicBlock * > &Targets)
Constant * getPersonalityFn() const
ImmutableCallSite - establish a view to a call site for examination.
bool isCatch(unsigned Idx) const
isCatch - Return 'true' if the clause and index Idx is a catch clause.
iplist< BasicBlock >::iterator eraseFromParent()
Unlink 'this' from the containing function and delete it.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
bool isLandingPad() const
Return true if this basic block is a landing pad.
bool hasOneUse() const
Return true if there is exactly one user of this value.
BasicBlock * getStartBlock() const
ClonedCodeInfo - This struct can be used to capture information about code being cloned, while it is being cloned.
Rename collisions when linking (static functions).
void addDestination(BasicBlock *Dest)
addDestination - Add a destination.
iterator_range< op_iterator > arg_operands()
arg_operands - iteration adapter for range-for loops.
CloningAction
This enumeration describes the way CloneAndPruneIntoFromInst should proceed after the CloningDirector...
Function * getFunction() const
user_iterator user_begin()
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
const BasicBlock & front() const
LLVMContext & getContext() const
Get the context in which this basic block lives.
AllocaInst * DemotePHIToStack(PHINode *P, Instruction *AllocaPoint=nullptr)
DemotePHIToStack - This function takes a virtual register computed by a phi node and replaces it with...
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
succ_range successors(BasicBlock *BB)
static bool isCatchBlock(BasicBlock *BB)
const ArgumentListType & getArgumentList() const
Get the underlying elements of the Function...
A vector that has set insertion semantics.
static const Function * getParent(const Value *V)
InvokeInst - Invoke instruction.
Primary interface to the complete machine description for the target machine.
bool isCleanup() const
isCleanup - Return 'true' if this landingpad instruction is a cleanup.
bool removeUnreachableBlocks(Function &F)
Remove all blocks that can not be reached from the function's entry.
Constant * getSelector() const
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N="", Module *M=nullptr)
Legacy analysis pass which computes a DominatorTree.
iterator getFirstInsertionPt()
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
specific_intval m_SpecificInt(uint64_t V)
Match a specific integer value or vector with all elements equal to the value.
bool isInvoke() const
isInvoke - true if a InvokeInst is enclosed.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
LandingPadInst * CreateLandingPad(Type *Ty, unsigned NumClauses, const Twine &Name="")
static BasicBlock * createStubLandingPad(Function *Handler)
unsigned getNumDestinations() const
getNumDestinations - return the number of possible destinations in this indirectbr instruction...
void removeDestination(unsigned i)
removeDestination - This method removes the specified successor from the indirectbr instruction...
const BasicBlock * getParent() const
bool isMSVCEHPersonality(EHPersonality Pers)
Returns true if this is an MSVC personality function.
IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic functions.
void parseEHActions(const IntrinsicInst *II, SmallVectorImpl< std::unique_ptr< ActionHandler >> &Actions)
LLVMContext & getContext() const
Get the global data context.
AllocaInst - an instruction to allocate memory on the stack.
InsertValueInst - This instruction inserts a struct field of array element value into an aggregate va...
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)