75#include <initializer_list>
80#define DEBUG_TYPE "coro-split"
101 if (
auto Invoke = dyn_cast<InvokeInst>(CB)) {
104 Invoke->getUnwindDest(), {Awaiter, FramePtr});
107 std::copy(Invoke->bundle_op_info_begin(), Invoke->bundle_op_info_end(),
108 WrapperInvoke->bundle_op_info_begin());
109 WrapperInvoke->setAttributes(NewAttributes);
110 WrapperInvoke->setDebugLoc(Invoke->getDebugLoc());
111 NewCall = WrapperInvoke;
112 }
else if (
auto Call = dyn_cast<CallInst>(CB)) {
116 WrapperCall->setDebugLoc(Call->getDebugLoc());
117 NewCall = WrapperCall;
123 Intrinsic::coro_await_suspend_handle) {
126 if (
auto *Invoke = dyn_cast<InvokeInst>(CB)) {
128 Builder.
SetInsertPoint(Invoke->getNormalDest()->getFirstInsertionPt());
138 auto *ResumeCall = Builder.
CreateCall(ResumeTy, ResumeAddr, {NewCall});
145 NewCall = ResumeCall;
161 assert(Shape.
ABI == coro::ABI::Retcon || Shape.
ABI == coro::ABI::RetconOnce);
174 auto *EndAsync = dyn_cast<CoroAsyncEndInst>(
End);
180 auto *MustTailCallFunc = EndAsync->getMustTailCallFunction();
181 if (!MustTailCallFunc) {
187 auto *CoroEndBlock =
End->getParent();
188 auto *MustTailCallFuncBlock = CoroEndBlock->getSinglePredecessor();
189 assert(MustTailCallFuncBlock &&
"Must have a single predecessor block");
190 auto It = MustTailCallFuncBlock->getTerminator()->getIterator();
191 auto *MustTailCall = cast<CallInst>(&*std::prev(It));
192 CoroEndBlock->splice(
End->getIterator(), MustTailCallFuncBlock,
193 MustTailCall->getIterator());
201 auto *BB =
End->getParent();
202 BB->splitBasicBlock(
End);
203 BB->getTerminator()->eraseFromParent();
206 assert(InlineRes.isSuccess() &&
"Expected inlining to succeed");
223 case coro::ABI::Switch:
224 assert(!cast<CoroEndInst>(
End)->hasResults() &&
225 "switch coroutine should not return any values");
234 case coro::ABI::Async: {
236 if (!CoroEndBlockNeedsCleanup)
243 case coro::ABI::RetconOnce: {
245 auto *CoroEnd = cast<CoroEndInst>(
End);
248 if (!CoroEnd->hasResults()) {
254 auto *CoroResults = CoroEnd->getResults();
255 unsigned NumReturns = CoroResults->numReturns();
257 if (
auto *RetStructTy = dyn_cast<StructType>(
RetTy)) {
258 assert(RetStructTy->getNumElements() == NumReturns &&
259 "numbers of returns should match resume function singature");
262 for (
Value *RetValEl : CoroResults->return_values())
265 }
else if (NumReturns == 0) {
270 Builder.
CreateRet(*CoroResults->retval_begin());
274 CoroResults->eraseFromParent();
280 case coro::ABI::Retcon: {
281 assert(!cast<CoroEndInst>(
End)->hasResults() &&
282 "retcon coroutine should not return any values");
285 auto RetStructTy = dyn_cast<StructType>(
RetTy);
287 cast<PointerType>(RetStructTy ? RetStructTy->getElementType(0) :
RetTy);
300 auto *BB =
End->getParent();
301 BB->splitBasicBlock(
End);
302 BB->getTerminator()->eraseFromParent();
316 Shape.
ABI == coro::ABI::Switch &&
317 "markCoroutineAsDone is only supported for Switch-Resumed ABI for now.");
336 "The final suspend should only live in the last position of "
354 case coro::ABI::Switch: {
367 case coro::ABI::Async:
370 case coro::ABI::Retcon:
371 case coro::ABI::RetconOnce:
378 auto *FromPad = cast<CleanupPadInst>(Bundle->Inputs[0]);
380 End->getParent()->splitBasicBlock(
End);
381 CleanupRet->getParent()->getTerminator()->eraseFromParent();
395 End->eraseFromParent();
415 auto FinalCaseIt = std::prev(
Switch->case_end());
416 BasicBlock *ResumeBB = FinalCaseIt->getCaseSuccessor();
417 Switch->removeCase(FinalCaseIt);
442 auto *AsyncSuspend = cast<CoroSuspendAsyncInst>(Suspend);
443 auto *StructTy = cast<StructType>(AsyncSuspend->getType());
462 M->getFunctionList().insert(InsertBefore, NewF);
475 auto NewS = VMap[ActiveSuspend];
476 if (NewS->use_empty())
484 for (
auto I = IsAsyncABI ? NewF->arg_begin() : std::next(NewF->arg_begin()),
491 if (!isa<StructType>(NewS->getType())) {
493 NewS->replaceAllUsesWith(Args.front());
499 auto *EVI = dyn_cast<ExtractValueInst>(U.getUser());
500 if (!EVI || EVI->getNumIndices() != 1)
503 EVI->replaceAllUsesWith(Args[EVI->getIndices().front()]);
504 EVI->eraseFromParent();
508 if (NewS->use_empty())
514 Aggr = Builder.CreateInsertValue(Aggr, Arg,
Idx);
520 Value *SuspendResult;
530 SuspendResult = Builder.getInt8(isSwitchDestroyFunction() ? 1 : 0);
547 if (CS == ActiveSuspend)
550 auto *MappedCS = cast<AnyCoroSuspendInst>(VMap[CS]);
551 MappedCS->replaceAllUsesWith(SuspendResult);
552 MappedCS->eraseFromParent();
560 auto *NewCE = cast<AnyCoroEndInst>(VMap[CE]);
569 Value *CachedSlot =
nullptr;
570 auto getSwiftErrorSlot = [&](
Type *ValueTy) ->
Value * {
575 for (
auto &Arg :
F.args()) {
576 if (Arg.isSwiftError()) {
584 F.getEntryBlock().getFirstNonPHIOrDbg());
593 auto MappedOp = VMap ? cast<CallInst>((*VMap)[
Op]) :
Op;
598 if (
Op->arg_empty()) {
599 auto ValueTy =
Op->getType();
600 auto Slot = getSwiftErrorSlot(ValueTy);
601 MappedResult = Builder.
CreateLoad(ValueTy, Slot);
604 auto Value = MappedOp->getArgOperand(0);
606 auto Slot = getSwiftErrorSlot(ValueTy);
611 MappedOp->replaceAllUsesWith(MappedResult);
612 MappedOp->eraseFromParent();
616 if (VMap ==
nullptr) {
629 return DbgVariableRecords;
641 bool UseEntryValue = OrigF.getParent()->getTargetTriple().isArch64Bit();
648 auto IsUnreachableBlock = [&](
BasicBlock *BB) {
653 if (IsUnreachableBlock(DVI->getParent()))
654 DVI->eraseFromParent();
655 else if (isa_and_nonnull<AllocaInst>(DVI->getVariableLocationOp(0))) {
658 for (
auto *
User : DVI->getVariableLocationOp(0)->
users())
659 if (
auto *
I = dyn_cast<Instruction>(
User))
660 if (!isa<AllocaInst>(
I) && !IsUnreachableBlock(
I->getParent()))
663 DVI->eraseFromParent();
666 for_each(DbgVariableRecords, RemoveOne);
676 auto *OldEntry = &NewF->getEntryBlock();
677 Entry->setName(
"entry" + Suffix);
678 Entry->moveBefore(OldEntry);
679 Entry->getTerminator()->eraseFromParent();
684 assert(Entry->hasOneUse());
685 auto BranchToEntry = cast<BranchInst>(Entry->user_back());
686 assert(BranchToEntry->isUnconditional());
687 Builder.SetInsertPoint(BranchToEntry);
688 Builder.CreateUnreachable();
689 BranchToEntry->eraseFromParent();
692 Builder.SetInsertPoint(Entry);
699 Builder.CreateBr(SwitchBB);
700 SwitchBB->moveAfter(Entry);
710 isa<CoroSuspendAsyncInst>(ActiveSuspend)) ||
713 isa<CoroSuspendRetconInst>(ActiveSuspend)));
714 auto *MappedCS = cast<AnyCoroSuspendInst>(VMap[ActiveSuspend]);
715 auto Branch = cast<BranchInst>(MappedCS->getNextNode());
716 assert(Branch->isUnconditional());
717 Builder.CreateBr(Branch->getSuccessor(0));
727 auto *Alloca = dyn_cast<AllocaInst>(&
I);
728 if (!Alloca ||
I.use_empty())
731 !isa<ConstantInt>(Alloca->getArraySize()))
733 I.moveBefore(*Entry, Entry->getFirstInsertionPt());
744 return &*NewF->arg_begin();
751 auto *ActiveAsyncSuspend = cast<CoroSuspendAsyncInst>(ActiveSuspend);
752 auto ContextIdx = ActiveAsyncSuspend->getStorageArgumentIndex() & 0xff;
753 auto *CalleeContext = NewF->getArg(ContextIdx);
754 auto *ProjectionFunc =
755 ActiveAsyncSuspend->getAsyncContextProjectionFunction();
757 cast<CoroSuspendAsyncInst>(VMap[ActiveSuspend])->getDebugLoc();
759 auto *CallerContext = Builder.CreateCall(ProjectionFunc->getFunctionType(),
760 ProjectionFunc, CalleeContext);
761 CallerContext->setCallingConv(ProjectionFunc->getCallingConv());
762 CallerContext->setDebugLoc(DbgLoc);
764 auto &
Context = Builder.getContext();
765 auto *FramePtrAddr = Builder.CreateConstInBoundsGEP1_32(
771 assert(InlineRes.isSuccess());
778 Argument *NewStorage = &*NewF->arg_begin();
786 return Builder.CreateLoad(FramePtrTy, NewStorage);
806 if (SPToUpdate.
getFile() ==
DL->getFile())
807 SPToUpdate.setScopeLine(
DL->getLine());
814 if (
auto *Branch = dyn_cast_or_null<BranchInst>(
Successor);
815 Branch && Branch->isUnconditional())
816 Successor = Branch->getSuccessor(0)->getFirstNonPHIOrDbg();
824 if (!
DL ||
DL.getLine() == 0)
827 if (SPToUpdate.
getFile() ==
DL->getFile()) {
828 SPToUpdate.setScopeLine(
DL.getLine());
837 if (SPToUpdate.
getFile() ==
DL->getFile())
838 SPToUpdate.setScopeLine(
DL->getLine());
843 Align Alignment,
bool NoAlias) {
853 Attrs = Attrs.addParamAttributes(
Context, ParamIndex, ParamAttrs);
857 unsigned ParamIndex) {
860 Attrs = Attrs.addParamAttributes(
Context, ParamIndex, ParamAttrs);
864 unsigned ParamIndex) {
867 Attrs = Attrs.addParamAttributes(
Context, ParamIndex, ParamAttrs);
883 VMap[&
A] = DummyArgs.
back();
890 auto savedVisibility = NewF->getVisibility();
891 auto savedUnnamedAddr = NewF->getUnnamedAddr();
892 auto savedDLLStorageClass = NewF->getDLLStorageClass();
897 auto savedLinkage = NewF->getLinkage();
903 auto &
Context = NewF->getContext();
906 assert(SP != OrigF.getSubprogram() && SP->isDistinct());
912 SP->replaceLinkageName(NewLinkageName);
914 TempDISubprogram NewDecl = Decl->clone();
915 NewDecl->replaceLinkageName(NewLinkageName);
920 NewF->setLinkage(savedLinkage);
921 NewF->setVisibility(savedVisibility);
922 NewF->setUnnamedAddr(savedUnnamedAddr);
923 NewF->setDLLStorageClass(savedDLLStorageClass);
928 NewF->hasMetadata(LLVMContext::MD_func_sanitize))
929 NewF->eraseMetadata(LLVMContext::MD_func_sanitize);
932 auto OrigAttrs = NewF->getAttributes();
939 NewAttrs = NewAttrs.addFnAttributes(
946 auto *ActiveAsyncSuspend = cast<CoroSuspendAsyncInst>(ActiveSuspend);
948 Attribute::SwiftAsync)) {
950 ActiveAsyncSuspend->getStorageArgumentIndex();
951 auto ContextArgIndex = ArgAttributeIndices & 0xff;
956 auto SwiftSelfIndex = ArgAttributeIndices >> 8;
962 auto FnAttrs = OrigF.getAttributes().getFnAttrs();
1006 NewF->setAttributes(NewAttrs);
1010 replaceEntryBlock();
1014 ResumeCall = cast<CallInst>(VMap[ResumeCall]);
1026 Builder.CreateRetVoid();
1030 Builder.SetInsertPoint(&NewF->getEntryBlock().front());
1031 NewFramePtr = deriveNewFramePointer();
1035 NewFramePtr->
takeName(OldFramePtr);
1039 auto *NewVFrame = Builder.CreateBitCast(
1042 if (OldVFrame != NewVFrame)
1049 DummyArg->deleteValue();
1058 handleFinalSuspend();
1065 assert(ActiveSuspend !=
nullptr &&
1066 "no active suspend when lowering a continuation-style coroutine");
1067 replaceRetconOrAsyncSuspendUses();
1072 replaceCoroSuspends();
1101 auto *FuncPtrStruct = cast<ConstantStruct>(
1103 auto *OrigRelativeFunOffset = FuncPtrStruct->getOperand(0);
1104 auto *OrigContextSize = FuncPtrStruct->getOperand(1);
1105 auto *NewContextSize = ConstantInt::get(OrigContextSize->getType(),
1108 FuncPtrStruct->getType(), OrigRelativeFunOffset, NewContextSize);
1115 auto *SizeIntrin = Shape.
CoroSizes.back();
1116 Module *M = SizeIntrin->getModule();
1118 return DL.getTypeAllocSize(Shape.
FrameTy);
1135 auto *SizeIntrin = Shape.
CoroSizes.back();
1136 auto *SizeConstant =
1161 switch (Shape.
ABI) {
1170 AllocInst->replaceAllUsesWith(Builder.
getFalse());
1171 AllocInst->eraseFromParent();
1172 CoroBegin->replaceAllUsesWith(Frame);
1174 CoroBegin->replaceAllUsesWith(CoroBegin->getMem());
1186 CoroBegin->eraseFromParent();
1196 if (isa<IntrinsicInst>(
I))
1199 if (isa<CallBase>(
I))
1215 while (!Worklist.
empty()) {
1219 if (!Set.contains(Pred))
1225 Set.erase(ResDesBB);
1227 for (
auto *BB : Set)
1236 auto *ResumeOrDestroyBB = ResumeOrDestroy->
getParent();
1240 if (SaveBB == ResumeOrDestroyBB)
1249 {ResumeOrDestroyBB->getFirstNonPHIIt(), ResumeOrDestroyIt}))
1265 auto *Pred = Suspend->
getParent()->getSinglePredecessor();
1268 Prev = Pred->getTerminator();
1271 CallBase *CB = dyn_cast<CallBase>(Prev);
1278 auto *SubFn = dyn_cast<CoroSubFnInst>(Callee);
1283 if (SubFn->getFrame() != CoroBegin)
1297 Save->eraseFromParent();
1300 if (
auto *Invoke = dyn_cast<InvokeInst>(CB)) {
1309 if (CalledValue != SubFn && CalledValue->user_empty())
1310 if (
auto *
I = dyn_cast<Instruction>(CalledValue))
1311 I->eraseFromParent();
1314 if (SubFn->user_empty())
1315 SubFn->eraseFromParent();
1327 size_t I = 0,
N = S.size();
1331 size_t ChangedFinalIndex = std::numeric_limits<size_t>::max();
1333 auto SI = cast<CoroSuspendInst>(S[
I]);
1342 if (cast<CoroSuspendInst>(S[
I])->isFinal()) {
1344 ChangedFinalIndex =
I;
1356 if (ChangedFinalIndex <
N) {
1357 assert(cast<CoroSuspendInst>(S[ChangedFinalIndex])->isFinal());
1358 std::swap(S[ChangedFinalIndex], S.back());
1364struct SwitchCoroutineSplitter {
1373 createResumeEntryBlock(
F, Shape);
1375 F,
".resume", Shape, coro::CloneKind::SwitchResume,
TTI);
1377 F,
".destroy", Shape, coro::CloneKind::SwitchUnwind,
TTI);
1379 F,
".cleanup", Shape, coro::CloneKind::SwitchCleanup,
TTI);
1386 updateCoroFrame(Shape, ResumeClone, DestroyClone, CleanupClone);
1396 setCoroInfo(
F, Shape, Clones);
1409 auto *OrigFnTy =
F.getFunctionType();
1410 auto OldParams = OrigFnTy->params();
1413 NewParams.
reserve(OldParams.size() + 1);
1414 NewParams.
append(OldParams.begin(), OldParams.end());
1417 auto *NewFnTy = FunctionType::get(OrigFnTy->getReturnType(), NewParams,
1418 OrigFnTy->isVarArg());
1423 unsigned int Idx = 0;
1424 for (
const auto &
I :
F.args()) {
1429 auto FrameIdx = NoAllocF->
arg_size() - 1;
1432 CloneFunctionChangeType::LocalChangesOnly, Returns);
1435 auto *NewCoroBegin =
1436 cast_if_present<CoroBeginInst>(VMap[Shape.
CoroBegin]);
1437 auto *NewCoroId = cast<CoroIdInst>(NewCoroBegin->getId());
1440 NewCoroBegin->replaceAllUsesWith(NoAllocF->
getArg(FrameIdx));
1441 NewCoroBegin->eraseFromParent();
1445 M->getFunctionList().insert(
M->end(), NoAllocF);
1460 setCoroInfo(
F, Shape, Clones);
1479 bool AddDebugLabels = DIS && DIS->getUnit() &&
1480 (DIS->getUnit()->getEmissionKind() ==
1481 DICompileUnit::DebugEmissionKind::FullDebug);
1497 auto *FrameTy = Shape.
FrameTy;
1498 auto *GepIndex = Builder.CreateStructGEP(
1506 size_t SuspendIndex = 0;
1508 auto *S = cast<CoroSuspendInst>(AnyS);
1514 auto *Save = S->getCoroSave();
1515 Builder.SetInsertPoint(Save);
1521 auto *GepIndex = Builder.CreateStructGEP(
1523 Builder.CreateStore(IndexVal, GepIndex);
1527 Save->eraseFromParent();
1553 auto *SuspendBB = S->getParent();
1555 SuspendBB->splitBasicBlock(S,
"resume." +
Twine(SuspendIndex));
1556 auto *LandingBB = ResumeBB->splitBasicBlock(
1557 S->getNextNode(), ResumeBB->getName() +
Twine(
".landing"));
1558 Switch->addCase(IndexVal, ResumeBB);
1560 cast<BranchInst>(SuspendBB->getTerminator())->setSuccessor(0, LandingBB);
1562 PN->insertBefore(LandingBB->begin());
1563 S->replaceAllUsesWith(PN);
1564 PN->addIncoming(Builder.getInt8(-1), SuspendBB);
1565 PN->addIncoming(S, ResumeBB);
1567 if (AddDebugLabels) {
1568 if (
DebugLoc SuspendLoc = S->getDebugLoc()) {
1569 std::string LabelName =
1570 (
"__coro_resume_" +
Twine(SuspendIndex)).str();
1573 DBuilder.createLabel(DIS, LabelName, DILoc.getFile(),
1574 SuspendLoc.getLine(), SuspendLoc.getCol(),
1578 DBuilder.insertLabel(ResumeLabel, &DILoc, ResumeBB->begin());
1585 Builder.SetInsertPoint(UnreachBB);
1586 Builder.CreateUnreachable();
1587 DBuilder.finalize();
1597 auto *ResumeAddr = Builder.CreateStructGEP(
1600 Builder.CreateStore(ResumeFn, ResumeAddr);
1602 Value *DestroyOrCleanupFn = DestroyFn;
1608 DestroyOrCleanupFn = Builder.CreateSelect(CA, DestroyFn, CleanupFn);
1611 auto *DestroyAddr = Builder.CreateStructGEP(
1614 Builder.CreateStore(DestroyOrCleanupFn, DestroyAddr);
1638 auto *ArrTy = ArrayType::get(Part->
getType(),
Args.size());
1642 GlobalVariable::PrivateLinkage, ConstVal,
1643 F.getName() +
Twine(
".resumers"));
1663 ResumeIntrinsic->eraseFromParent();
1673 for (
auto *paramTy : FnTy->params()) {
1675 if (paramTy != FnArgs[ArgIdx]->
getType())
1694 auto *TailCall = Builder.
CreateCall(FnTy, MustTailCallFn, CallArgs);
1699 TailCall->setDebugLoc(Loc);
1711 F.removeFnAttr(Attribute::NoReturn);
1712 F.removeRetAttr(Attribute::NoAlias);
1713 F.removeRetAttr(Attribute::NonNull);
1725 "async.ctx.frameptr");
1736 auto NextF = std::next(
F.getIterator());
1741 auto *Suspend = cast<CoroSuspendAsyncInst>(CS);
1744 auto ResumeNameSuffix =
".resume.";
1745 auto ProjectionFunctionName =
1746 Suspend->getAsyncContextProjectionFunction()->getName();
1747 bool UseSwiftMangling =
false;
1748 if (ProjectionFunctionName ==
"__swift_async_resume_project_context") {
1749 ResumeNameSuffix =
"TQ";
1750 UseSwiftMangling =
true;
1751 }
else if (ProjectionFunctionName ==
"__swift_async_resume_get_context") {
1752 ResumeNameSuffix =
"TY";
1753 UseSwiftMangling =
true;
1757 UseSwiftMangling ? ResumeNameSuffix +
Twine(
Idx) +
"_"
1764 auto *SuspendBB = Suspend->getParent();
1765 auto *NewSuspendBB = SuspendBB->splitBasicBlock(Suspend);
1766 auto *Branch = cast<BranchInst>(SuspendBB->getTerminator());
1771 Branch->setSuccessor(0, ReturnBB);
1776 auto *Fn = Suspend->getMustTailCallFunction();
1794 auto *Clone = Clones[
Idx];
1809 F.removeFnAttr(Attribute::NoReturn);
1810 F.removeRetAttr(Attribute::NoAlias);
1811 F.removeRetAttr(Attribute::NonNull);
1817 RawFramePtr = Id->getStorage();
1833 Builder.
CreateStore(RawFramePtr, Id->getStorage());
1846 PHINode *ContinuationPhi =
nullptr;
1850 auto NextF = std::next(
F.getIterator());
1855 auto Suspend = cast<CoroSuspendRetconInst>(CS);
1864 auto SuspendBB = Suspend->getParent();
1865 auto NewSuspendBB = SuspendBB->splitBasicBlock(Suspend);
1866 auto Branch = cast<BranchInst>(SuspendBB->getTerminator());
1890 auto RetTy =
F.getReturnType();
1895 auto CastedContinuationTy =
1897 auto *CastedContinuation =
1898 Builder.
CreateBitCast(ContinuationPhi, CastedContinuationTy);
1900 Value *RetV = CastedContinuation;
1901 if (!ReturnPHIs.
empty()) {
1906 for (
auto Phi : ReturnPHIs)
1914 Branch->setSuccessor(0, ReturnBB);
1917 for (
auto [Phi, VUse] :
1919 Phi->addIncoming(VUse, SuspendBB);
1926 auto Clone = Clones[
Idx];
1940 OS <<
"While splitting coroutine ";
1941 F.printAsOperand(
OS,
false,
F.getParent());
1957 End->eraseFromParent();
1963 for (
auto *U :
F.users()) {
1964 if (
auto *CB = dyn_cast<CallBase>(U)) {
1965 auto *Caller = CB->getFunction();
1966 if (Caller && Caller->isPresplitCoroutine() &&
1967 CB->hasFnAttr(llvm::Attribute::CoroElideSafe))
1977 SwitchCoroutineSplitter::split(
F,
Shape, Clones,
TTI);
1982 bool OptimizeFrame) {
1983 PrettyStackTraceFunction prettyStackTrace(
F);
1985 auto &Shape =
ABI.Shape;
1993 ABI.buildCoroutineFrame(OptimizeFrame);
1996 bool isNoSuspendCoroutine = Shape.
CoroSuspends.empty();
1998 bool shouldCreateNoAllocVariant =
2004 if (isNoSuspendCoroutine) {
2007 ABI.splitCoroutine(
F, Shape, Clones,
TTI);
2024 if (shouldCreateNoAllocVariant)
2025 SwitchCoroutineSplitter::createNoAllocVariant(
F, Shape, Clones);
2034 auto *CurrentSCC = &
C;
2035 if (!Clones.
empty()) {
2036 switch (Shape.
ABI) {
2048 if (!Clones.empty())
2080 auto *Cast = dyn_cast<BitCastInst>(U.getUser());
2081 if (!Cast || Cast->getType() != Fn->getType())
2085 Cast->replaceAllUsesWith(Fn);
2086 Cast->eraseFromParent();
2095 while (
auto *Cast = dyn_cast<BitCastInst>(CastFn)) {
2096 if (!Cast->use_empty())
2098 CastFn = Cast->getOperand(0);
2099 Cast->eraseFromParent();
2105 bool Changed =
false;
2108 auto *Prepare = cast<CallInst>(
P.getUser());
2119 auto *PrepareFn = M.getFunction(
Name);
2120 if (PrepareFn && !PrepareFn->use_empty())
2124static std::unique_ptr<coro::BaseABI>
2130 if (CustomABI >= GenCustomABIs.
size())
2132 return GenCustomABIs[CustomABI](
F, S);
2137 return std::make_unique<coro::SwitchABI>(
F, S, IsMatCallback);
2139 return std::make_unique<coro::AsyncABI>(
F, S, IsMatCallback);
2141 return std::make_unique<coro::AnyRetconABI>(
F, S, IsMatCallback);
2143 return std::make_unique<coro::AnyRetconABI>(
F, S, IsMatCallback);
2149 : CreateAndInitABI([](
Function &
F, coro::Shape &S) {
2150 std::unique_ptr<coro::BaseABI> ABI =
2155 OptimizeFrame(OptimizeFrame) {}
2159 : CreateAndInitABI([=](
Function &
F, coro::Shape &S) {
2160 std::unique_ptr<coro::BaseABI> ABI =
2165 OptimizeFrame(OptimizeFrame) {}
2171 : CreateAndInitABI([=](
Function &
F, coro::Shape &S) {
2172 std::unique_ptr<coro::BaseABI> ABI =
2177 OptimizeFrame(OptimizeFrame) {}
2184 : CreateAndInitABI([=](
Function &
F, coro::Shape &S) {
2185 std::unique_ptr<coro::BaseABI> ABI =
2190 OptimizeFrame(OptimizeFrame) {}
2198 Module &M = *
C.begin()->getFunction().getParent();
2210 if (
N.getFunction().isPresplitCoroutine())
2213 if (Coroutines.
empty() && PrepareFns.
empty())
2216 auto *CurrentSCC = &
C;
2220 LLVM_DEBUG(
dbgs() <<
"CoroSplit: Processing coroutine '" <<
F.getName()
2232 F.setSplittedCoroutine();
2240 *
N, Shape, Clones, *CurrentSCC, CG, AM, UR,
FAM);
2245 <<
"Split '" <<
ore::NV(
"function",
F.getName())
2262 for (
auto *PrepareFn : PrepareFns) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
AMDGPU Lower Kernel Arguments
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file provides interfaces used to manipulate a call graph, regardless if it is a "old style" Call...
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static void addSwiftSelfAttrs(AttributeList &Attrs, LLVMContext &Context, unsigned ParamIndex)
static bool hasCallsBetween(Instruction *Save, Instruction *ResumeOrDestroy)
static LazyCallGraph::SCC & updateCallGraphAfterCoroutineSplit(LazyCallGraph::Node &N, const coro::Shape &Shape, const SmallVectorImpl< Function * > &Clones, LazyCallGraph::SCC &C, LazyCallGraph &CG, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, FunctionAnalysisManager &FAM)
static void replaceSwiftErrorOps(Function &F, coro::Shape &Shape, ValueToValueMapTy *VMap)
static void addAsyncContextAttrs(AttributeList &Attrs, LLVMContext &Context, unsigned ParamIndex)
static void maybeFreeRetconStorage(IRBuilder<> &Builder, const coro::Shape &Shape, Value *FramePtr, CallGraph *CG)
static bool hasCallsInBlocksBetween(BasicBlock *SaveBB, BasicBlock *ResDesBB)
static Function * createCloneDeclaration(Function &OrigF, coro::Shape &Shape, const Twine &Suffix, Module::iterator InsertBefore, AnyCoroSuspendInst *ActiveSuspend)
Remove calls to llvm coro end in the original static function void removeCoroEndsFromRampFunction(const coro::Shape &Shape)
static FunctionType * getFunctionTypeFromAsyncSuspend(AnyCoroSuspendInst *Suspend)
static void updateScopeLine(Instruction *ActiveSuspend, DISubprogram &SPToUpdate)
Adjust the scope line of the funclet to the first line number after the suspend point.
static void addPrepareFunction(const Module &M, SmallVectorImpl< Function * > &Fns, StringRef Name)
static SmallVector< DbgVariableRecord * > collectDbgVariableRecords(Function &F)
Returns all debug records in F.
static void simplifySuspendPoints(coro::Shape &Shape)
static void addFramePointerAttrs(AttributeList &Attrs, LLVMContext &Context, unsigned ParamIndex, uint64_t Size, Align Alignment, bool NoAlias)
static bool hasSafeElideCaller(Function &F)
static bool replaceAllPrepares(Function *PrepareFn, LazyCallGraph &CG, LazyCallGraph::SCC &C)
static void replaceFallthroughCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG)
Replace a non-unwind call to llvm.coro.end.
static void replaceFrameSizeAndAlignment(coro::Shape &Shape)
static std::unique_ptr< coro::BaseABI > CreateNewABI(Function &F, coro::Shape &S, std::function< bool(Instruction &)> IsMatCallback, const SmallVector< CoroSplitPass::BaseABITy > GenCustomABIs)
static bool replaceCoroEndAsync(AnyCoroEndInst *End)
Replace an llvm.coro.end.async.
static void doSplitCoroutine(Function &F, SmallVectorImpl< Function * > &Clones, coro::BaseABI &ABI, TargetTransformInfo &TTI, bool OptimizeFrame)
static bool hasCallsInBlockBetween(iterator_range< BasicBlock::iterator > R)
Replace a call to llvm coro prepare static retcon void replacePrepare(CallInst *Prepare, LazyCallGraph &CG, LazyCallGraph::SCC &C)
static void replaceUnwindCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG)
Replace an unwind call to llvm.coro.end.
static bool simplifySuspendPoint(CoroSuspendInst *Suspend, CoroBeginInst *CoroBegin)
static void markCoroutineAsDone(IRBuilder<> &Builder, const coro::Shape &Shape, Value *FramePtr)
static void updateAsyncFuncPointerContextSize(coro::Shape &Shape)
static void replaceCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG)
static void lowerAwaitSuspend(IRBuilder<> &Builder, CoroAwaitSuspendInst *CB, coro::Shape &Shape)
static void lowerAwaitSuspends(Function &F, coro::Shape &Shape)
static void handleNoSuspendCoroutine(coro::Shape &Shape)
static void postSplitCleanup(Function &F)
static TypeSize getFrameSizeForShape(coro::Shape &Shape)
Coerce the arguments in p FnArgs according to p FnTy in p static CallArgs void coerceArguments(IRBuilder<> &Builder, FunctionType *FnTy, ArrayRef< Value * > FnArgs, SmallVectorImpl< Value * > &CallArgs)
static void replaceAsyncResumeFunction(CoroSuspendAsyncInst *Suspend, Value *Continuation)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
Implements a lazy call graph analysis and related passes for the new pass manager.
FunctionAnalysisManager FAM
This file provides a priority worklist.
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
static const unsigned FramePtr
void setSwiftError(bool V)
Specify whether this alloca is used to represent a swifterror.
void setAlignment(Align Align)
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
CoroAllocInst * getCoroAlloc()
Align getStorageAlignment() const
uint64_t getStorageSize() const
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
size_t size() const
size - Get the array size.
LLVM_ABI AttrBuilder & addAlignmentAttr(MaybeAlign Align)
This turns an alignment into the form used internally in Attribute.
LLVM_ABI AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
LLVM_ABI AttrBuilder & addDereferenceableAttr(uint64_t Bytes)
This turns the number of dereferenceable bytes into the form used internally in Attribute.
AttributeList removeParamAttributes(LLVMContext &C, unsigned ArgNo, const AttributeMask &AttrsToRemove) const
Remove the specified attribute at the specified arg index from this attribute list.
LLVM Basic Block Representation.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
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...
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
void setCallingConv(CallingConv::ID CC)
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Value * getCalledOperand() const
void setAttributes(AttributeList A)
Set the attributes for this call.
Value * getArgOperand(unsigned i) const
AttributeList getAttributes() const
Return the attributes for this call.
The basic data container for the call graph of a Module of IR.
This class represents a function call, abstracting a target machine's calling convention.
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
static LLVM_ABI ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
This represents the llvm.coro.align instruction.
This represents the llvm.coro.alloc instruction.
This represents the llvm.coro.await.suspend.{void,bool,handle} instructions.
Value * getAwaiter() const
Function * getWrapperFunction() const
This class represents the llvm.coro.begin or llvm.coro.begin.custom.abi instructions.
AnyCoroIdInst * getId() const
bool hasCustomABI() const
This represents the llvm.coro.id instruction.
void setInfo(Constant *C)
This represents the llvm.coro.size instruction.
This represents the llvm.coro.suspend.async instruction.
CoroAsyncResumeInst * getResumeFunction() const
This represents the llvm.coro.suspend instruction.
CoroSaveInst * getCoroSave() const
Subprogram description. Uses SubclassData1.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
This class represents a freeze function that returns random concrete value if an operand is either a ...
A proxy from a FunctionAnalysisManager to an SCC.
Class to represent function types.
Type * getReturnType() const
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool isCoroOnlyDestroyWhenComplete() const
Argument * getArg(unsigned i) const
void setLinkage(LinkageTypes LT)
Module * getParent()
Get the module that this global value is contained inside of...
PointerType * getType() const
Global values are always pointers.
@ InternalLinkage
Rename collisions when linking (static functions).
@ ExternalLinkage
Externally visible function.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
LLVM_ABI void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
InvokeInst * CreateInvoke(FunctionType *Ty, Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef< Value * > Args, ArrayRef< OperandBundleDef > OpBundles, const Twine &Name="")
Create an invoke instruction.
BasicBlock::iterator GetInsertPoint() const
Value * CreateStructGEP(Type *Ty, Value *Ptr, unsigned Idx, const Twine &Name="")
Value * CreateConstInBoundsGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
CleanupReturnInst * CreateCleanupRet(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB=nullptr)
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Value * CreateBitOrPointerCast(Value *V, Type *DestTy, const Twine &Name="")
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
LLVMContext & getContext() const
ReturnInst * CreateRetVoid()
Create a 'ret void' instruction.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
ConstantInt * getFalse()
Get the constant value for i1 false.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
BranchInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
This class captures the data input to the InlineFunction call, and records the auxiliary results prod...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
This is an important class for using LLVM in a threaded context.
A node in the call graph.
An SCC of the call graph.
A lazily constructed view of the call graph of a module.
LLVM_ABI void addSplitFunction(Function &OriginalFunction, Function &NewFunction)
Add a new function split/outlined from an existing function.
LLVM_ABI void addSplitRefRecursiveFunctions(Function &OriginalFunction, ArrayRef< Function * > NewFunctions)
Add new ref-recursive functions split/outlined from an existing function.
Node & get(Function &F)
Get a graph node for a given function, scanning it to populate the graph data as necessary.
SCC * lookupSCC(Node &N) const
Lookup a function's SCC in the graph.
static std::enable_if_t< std::is_base_of< MDNode, T >::value, T * > replaceWithUniqued(std::unique_ptr< T, TempMDNodeDeleter > N)
Replace a temporary node with a uniqued one.
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
A Module instance is used to store all the information related to an LLVM module.
FunctionListType::iterator iterator
The Function iterators.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PrettyStackTraceEntry - This class is used to represent a frame of the "pretty" stack trace that is d...
Return a value (possibly void), from a function.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
LLVM_ABI Type * getTypeAtIndex(const Value *V) const
Given an index value into the type, return the type of the element.
Analysis pass providing the TargetTransformInfo.
Value handle that tracks a Value across RAUW.
ValueTy * getValPtr() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
void splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl< Function * > &Clones, TargetTransformInfo &TTI) override
void splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl< Function * > &Clones, TargetTransformInfo &TTI) override
void replaceSwiftErrorOps()
Value * deriveNewFramePointer()
Derive the value of the new frame pointer.
void replaceCoroSuspends()
void handleFinalSuspend()
static Function * createClone(Function &OrigF, const Twine &Suffix, coro::Shape &Shape, Function *NewF, AnyCoroSuspendInst *ActiveSuspend, TargetTransformInfo &TTI)
Create a clone for a continuation lowering.
bool isSwitchDestroyFunction()
void replaceRetconOrAsyncSuspendUses()
Replace uses of the active llvm.coro.suspend.retcon/async call with the arguments to the continuation...
virtual void create()
Clone the body of the original function into a resume function of some sort.
void splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl< Function * > &Clones, TargetTransformInfo &TTI) override
static Function * createClone(Function &OrigF, const Twine &Suffix, coro::Shape &Shape, CloneKind FKind, TargetTransformInfo &TTI)
Create a clone for a switch lowering.
void create() override
Clone the body of the original function into a resume function of some sort.
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
@ Async
The "async continuation" lowering, where each suspend point creates a single continuation function.
@ RetconOnce
The "unique returned-continuation" lowering, where each suspend point creates a single continuation f...
@ Retcon
The "returned-continuation" lowering, where each suspend point creates a single continuation function...
@ Switch
The "resume-switch" lowering, where there are separate resume and destroy functions that are shared b...
void suppressCoroAllocs(CoroIdInst *CoroId)
Replaces all @llvm.coro.alloc intrinsics calls associated with a given call @llvm....
void normalizeCoroutine(Function &F, coro::Shape &Shape, TargetTransformInfo &TTI)
CallInst * createMustTailCall(DebugLoc Loc, Function *MustTailCallFn, TargetTransformInfo &TTI, ArrayRef< Value * > Arguments, IRBuilder<> &)
void replaceCoroFree(CoroIdInst *CoroId, bool Elide)
LLVM_ABI bool isTriviallyMaterializable(Instruction &I)
@ SwitchCleanup
The shared cleanup function for a switch lowering.
@ Continuation
An individual continuation function.
void salvageDebugInfo(SmallDenseMap< Argument *, AllocaInst *, 4 > &ArgToAllocaMap, DbgVariableRecord &DVR, bool UseEntryValue)
Attempts to rewrite the location operand of debug records in terms of the coroutine frame pointer,...
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, bool MergeAttributes=false, AAResults *CalleeAAR=nullptr, bool InsertLifetime=true, Function *ForwardVarArgsTo=nullptr, OptimizationRemarkEmitter *ORE=nullptr)
This function inlines the called function into the basic block of the caller.
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
LLVM_ABI bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
LLVM_ABI LazyCallGraph::SCC & updateCGAndAnalysisManagerForFunctionPass(LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, FunctionAnalysisManager &FAM)
Helper to update the call graph after running a function pass.
LLVM_ABI LazyCallGraph::SCC & updateCGAndAnalysisManagerForCGSCCPass(LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, FunctionAnalysisManager &FAM)
Helper to update the call graph after running a CGSCC pass.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI BasicBlock::iterator skipDebugIntrinsics(BasicBlock::iterator It)
Advance It while it points to a debug instruction and return the result.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ABI 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...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
LLVM_ABI void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, ValueToValueMapTy &VMap, CloneFunctionChangeType Changes, SmallVectorImpl< ReturnInst * > &Returns, const char *NameSuffix="", ClonedCodeInfo *CodeInfo=nullptr, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Clone OldFunc into NewFunc, transforming the old arguments into references to VMap values.
auto predecessors(const MachineBasicBlock *BB)
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
LLVM_ABI bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Support structure for SCC passes to communicate updates the call graph back to the CGSCC pass manager...
SmallPriorityWorklist< LazyCallGraph::SCC *, 1 > & CWorklist
Worklist of the SCCs queued for processing.
LLVM_ABI PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
LLVM_ABI CoroSplitPass(bool OptimizeFrame=false)
BaseABITy CreateAndInitABI
CallInst * makeSubFnCall(Value *Arg, int Index, Instruction *InsertPt)
GlobalVariable * AsyncFuncPointer
bool IsFrameInlineInStorage
Function * ResumePrototype
SwitchInst * ResumeSwitch
BasicBlock * ResumeEntryBlock
SmallVector< CallInst *, 2 > SymmetricTransfers
SmallVector< CoroAwaitSuspendInst *, 4 > CoroAwaitSuspends
AsyncLoweringStorage AsyncLowering
FunctionType * getResumeFunctionType() const
IntegerType * getIndexType() const
AnyCoroIdRetconInst * getRetconCoroId() const
PointerType * getSwitchResumePointerType() const
CoroIdInst * getSwitchCoroId() const
SmallVector< CoroSizeInst *, 2 > CoroSizes
CallingConv::ID getResumeFunctionCC() const
SmallVector< AnyCoroSuspendInst *, 4 > CoroSuspends
LLVM_ABI Value * emitAlloc(IRBuilder<> &Builder, Value *Size, CallGraph *CG) const
Allocate memory according to the rules of the active lowering.
ConstantInt * getIndex(uint64_t Value) const
SwitchLoweringStorage SwitchLowering
CoroBeginInst * CoroBegin
BasicBlock::iterator getInsertPtAfterFramePtr() const
ArrayRef< Type * > getRetconResultTypes() const
LLVM_ABI void emitDealloc(IRBuilder<> &Builder, Value *Ptr, CallGraph *CG) const
Deallocate memory according to the rules of the active lowering.
RetconLoweringStorage RetconLowering
SmallVector< CoroAlignInst *, 2 > CoroAligns
CoroIdAsyncInst * getAsyncCoroId() const
SmallVector< AnyCoroEndInst *, 4 > CoroEnds
SmallVector< CallInst *, 2 > SwiftErrorOps
BasicBlock * AllocaSpillBlock
unsigned getSwitchIndexField() const