75#include <initializer_list>
80#define DEBUG_TYPE "coro-split"
92 Builder.SetInsertPoint(CB);
98 AttributeList NewAttributes =
103 Builder.CreateInvoke(
Wrapper, Invoke->getNormalDest(),
104 Invoke->getUnwindDest(), {Awaiter, FramePtr});
106 WrapperInvoke->setCallingConv(Invoke->getCallingConv());
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;
115 WrapperCall->setAttributes(NewAttributes);
116 WrapperCall->setDebugLoc(
Call->getDebugLoc());
117 NewCall = WrapperCall;
123 Intrinsic::coro_await_suspend_handle) {
128 Builder.SetInsertPoint(Invoke->getNormalDest()->getFirstInsertionPt());
133 &*Builder.GetInsertPoint());
138 auto *ResumeCall = Builder.CreateCall(ResumeTy, ResumeAddr, {NewCall});
144 NewCall = ResumeCall;
175 Builder.CreateRetVoid();
179 auto *MustTailCallFunc = EndAsync->getMustTailCallFunction();
180 if (!MustTailCallFunc) {
181 Builder.CreateRetVoid();
187 auto *MustTailCallFuncBlock = CoroEndBlock->getSinglePredecessor();
188 assert(MustTailCallFuncBlock &&
"Must have a single predecessor block");
189 auto It = MustTailCallFuncBlock->getTerminator()->getIterator();
191 CoroEndBlock->splice(End->
getIterator(), MustTailCallFuncBlock,
192 MustTailCall->getIterator());
195 Builder.SetInsertPoint(End);
196 Builder.CreateRetVoid();
201 BB->splitBasicBlock(End);
202 BB->getTerminator()->eraseFromParent();
205 assert(InlineRes.isSuccess() &&
"Expected inlining to succeed");
224 "switch coroutine should not return any values");
229 Builder.CreateRetVoid();
235 if (!CoroEndBlockNeedsCleanup)
247 if (!CoroEnd->hasResults()) {
248 assert(RetTy->isVoidTy());
249 Builder.CreateRetVoid();
253 auto *CoroResults = CoroEnd->getResults();
254 unsigned NumReturns = CoroResults->numReturns();
257 assert(RetStructTy->getNumElements() == NumReturns &&
258 "numbers of returns should match resume function singature");
261 for (
Value *RetValEl : CoroResults->return_values())
262 ReturnValue = Builder.CreateInsertValue(ReturnValue, RetValEl, Idx++);
263 Builder.CreateRet(ReturnValue);
264 }
else if (NumReturns == 0) {
265 assert(RetTy->isVoidTy());
266 Builder.CreateRetVoid();
269 Builder.CreateRet(*CoroResults->retval_begin());
271 CoroResults->replaceAllUsesWith(
273 CoroResults->eraseFromParent();
281 "retcon coroutine should not return any values");
293 Builder.CreateRet(ReturnValue);
300 BB->splitBasicBlock(End);
301 BB->getTerminator()->eraseFromParent();
309 return Builder.CreateInBoundsPtrAdd(
FramePtr,
Offset,
"index.addr");
324 "markCoroutineAsDone is only supported for Switch-Resumed ABI for now.");
327 Builder.CreateStore(NullPtr,
FramePtr);
340 "The final suspend should only live in the last position of "
344 Builder.CreateStore(IndexVal, FinalIndex);
380 auto *CleanupRet = Builder.CreateCleanupRet(FromPad,
nullptr);
382 CleanupRet->getParent()->getTerminator()->eraseFromParent();
406 Shape.SwitchLowering.HasFinalSuspend);
412 auto FinalCaseIt = std::prev(
Switch->case_end());
413 BasicBlock *ResumeBB = FinalCaseIt->getCaseSuccessor();
414 Switch->removeCase(FinalCaseIt);
420 if (
NewF->isCoroOnlyDestroyWhenComplete()) {
439 auto &Context = Suspend->
getParent()->getParent()->getContext();
457 M->getFunctionList().insert(InsertBefore, NewF);
471 if (NewS->use_empty())
479 for (
auto I = IsAsyncABI ?
NewF->arg_begin() : std::next(
NewF->arg_begin()),
488 NewS->replaceAllUsesWith(Args.front());
495 if (!EVI || EVI->getNumIndices() != 1)
498 EVI->replaceAllUsesWith(Args[EVI->getIndices().front()]);
499 EVI->eraseFromParent();
503 if (NewS->use_empty())
509 Aggr =
Builder.CreateInsertValue(Aggr, Arg, Idx);
511 NewS->replaceAllUsesWith(Aggr);
515 Value *SuspendResult;
546 MappedCS->replaceAllUsesWith(SuspendResult);
547 MappedCS->eraseFromParent();
561 auto &Ctx =
OrigF.getContext();
562 for (
auto *
II :
Shape.CoroIsInRampInsts) {
565 NewII->eraseFromParent();
573 Value *CachedSlot =
nullptr;
574 auto getSwiftErrorSlot = [&](
Type *ValueTy) ->
Value * {
579 for (
auto &Arg :
F.args()) {
580 if (Arg.isSwiftError()) {
588 F.getEntryBlock().getFirstNonPHIOrDbg());
589 auto Alloca = Builder.CreateAlloca(ValueTy);
590 Alloca->setSwiftError(
true);
602 if (
Op->arg_empty()) {
603 auto ValueTy =
Op->getType();
604 auto Slot = getSwiftErrorSlot(ValueTy);
605 MappedResult = Builder.CreateLoad(ValueTy, Slot);
608 auto Value = MappedOp->getArgOperand(0);
610 auto Slot = getSwiftErrorSlot(ValueTy);
611 Builder.CreateStore(
Value, Slot);
616 MappedOp->eraseFromParent();
620 if (VMap ==
nullptr) {
633 return DbgVariableRecords;
645 bool UseEntryValue =
OrigF.getParent()->getTargetTriple().isArch64Bit();
652 auto IsUnreachableBlock = [&](
BasicBlock *BB) {
657 if (IsUnreachableBlock(DVI->getParent()))
658 DVI->eraseFromParent();
662 for (
auto *
User : DVI->getVariableLocationOp(0)->
users())
667 DVI->eraseFromParent();
670 for_each(DbgVariableRecords, RemoveOne);
680 auto *OldEntry = &
NewF->getEntryBlock();
681 Entry->setName(
"entry" +
Suffix);
682 Entry->moveBefore(OldEntry);
683 Entry->getTerminator()->eraseFromParent();
688 assert(Entry->hasOneUse());
690 Builder.SetInsertPoint(BranchToEntry);
692 BranchToEntry->eraseFromParent();
703 SwitchBB->moveAfter(Entry);
719 Builder.CreateBr(Branch->getSuccessor(0));
730 if (!Alloca ||
I.use_empty())
735 I.moveBefore(*Entry, Entry->getFirstInsertionPt());
746 return &*
NewF->arg_begin();
754 auto ContextIdx = ActiveAsyncSuspend->getStorageArgumentIndex() & 0xff;
755 auto *CalleeContext =
NewF->getArg(ContextIdx);
756 auto *ProjectionFunc =
757 ActiveAsyncSuspend->getAsyncContextProjectionFunction();
761 auto *CallerContext =
Builder.CreateCall(ProjectionFunc->getFunctionType(),
762 ProjectionFunc, CalleeContext);
763 CallerContext->setCallingConv(ProjectionFunc->getCallingConv());
764 CallerContext->setDebugLoc(DbgLoc);
766 auto &Context =
Builder.getContext();
767 auto *FramePtrAddr =
Builder.CreateInBoundsPtrAdd(
770 Shape.AsyncLowering.FrameOffset),
771 "async.ctx.frameptr");
775 assert(InlineRes.isSuccess());
786 if (
Shape.RetconLowering.IsFrameInlineInStorage)
790 return Builder.CreateLoad(FramePtrTy, NewStorage);
810 if (SPToUpdate.
getFile() ==
DL->getFile())
811 SPToUpdate.setScopeLine(
DL->getLine());
819 for (
unsigned Repeat = 0; Repeat < 2; Repeat++) {
823 Successor = Branch->getSuccessor()->getFirstNonPHIOrDbg();
832 if (!
DL ||
DL.getLine() == 0)
835 if (SPToUpdate.
getFile() ==
DL->getFile()) {
836 SPToUpdate.setScopeLine(
DL.getLine());
845 if (SPToUpdate.
getFile() ==
DL->getFile())
846 SPToUpdate.setScopeLine(
DL->getLine());
851 Align Alignment,
bool NoAlias) {
852 AttrBuilder ParamAttrs(Context);
853 ParamAttrs.addAttribute(Attribute::NonNull);
854 ParamAttrs.addAttribute(Attribute::NoUndef);
857 ParamAttrs.addAttribute(Attribute::NoAlias);
859 ParamAttrs.addAlignmentAttr(Alignment);
860 ParamAttrs.addDereferenceableAttr(
Size);
861 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs);
865 unsigned ParamIndex) {
866 AttrBuilder ParamAttrs(Context);
867 ParamAttrs.addAttribute(Attribute::SwiftAsync);
868 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs);
872 unsigned ParamIndex) {
873 AttrBuilder ParamAttrs(Context);
874 ParamAttrs.addAttribute(Attribute::SwiftSelf);
875 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs);
898 auto savedVisibility =
NewF->getVisibility();
899 auto savedUnnamedAddr =
NewF->getUnnamedAddr();
900 auto savedDLLStorageClass =
NewF->getDLLStorageClass();
905 auto savedLinkage =
NewF->getLinkage();
911 auto &Context =
NewF->getContext();
914 assert(SP !=
OrigF.getSubprogram() && SP->isDistinct());
920 SP->replaceLinkageName(NewLinkageName);
922 TempDISubprogram NewDecl = Decl->clone();
923 NewDecl->replaceLinkageName(NewLinkageName);
928 NewF->setLinkage(savedLinkage);
929 NewF->setVisibility(savedVisibility);
930 NewF->setUnnamedAddr(savedUnnamedAddr);
931 NewF->setDLLStorageClass(savedDLLStorageClass);
936 NewF->hasMetadata(LLVMContext::MD_func_sanitize))
937 NewF->eraseMetadata(LLVMContext::MD_func_sanitize);
940 auto OrigAttrs =
NewF->getAttributes();
941 auto NewAttrs = AttributeList();
947 NewAttrs = NewAttrs.addFnAttributes(
948 Context, AttrBuilder(Context, OrigAttrs.getFnAttrs()));
951 Shape.FrameAlign,
false);
955 if (
OrigF.hasParamAttribute(
Shape.AsyncLowering.ContextArgNo,
956 Attribute::SwiftAsync)) {
958 ActiveAsyncSuspend->getStorageArgumentIndex();
959 auto ContextArgIndex = ArgAttributeIndices & 0xff;
964 auto SwiftSelfIndex = ArgAttributeIndices >> 8;
970 auto FnAttrs =
OrigF.getAttributes().getFnAttrs();
971 NewAttrs = NewAttrs.addFnAttributes(Context, AttrBuilder(Context, FnAttrs));
978 NewAttrs =
Shape.RetconLowering.ResumePrototype->getAttributes();
982 Shape.getRetconCoroId()->getStorageSize(),
983 Shape.getRetconCoroId()->getStorageAlignment(),
1014 NewF->setAttributes(NewAttrs);
1015 NewF->setCallingConv(
Shape.getResumeFunctionCC());
1023 if (
TTI.supportsTailCallFor(ResumeCall)) {
1038 Builder.SetInsertPoint(&
NewF->getEntryBlock().front());
1047 auto *NewVFrame =
Builder.CreateBitCast(
1050 if (OldVFrame != NewVFrame)
1057 DummyArg->deleteValue();
1060 switch (
Shape.ABI) {
1065 if (
Shape.SwitchLowering.HasFinalSuspend)
1074 "no active suspend when lowering a continuation-style coroutine");
1112 auto *OrigRelativeFunOffset = FuncPtrStruct->getOperand(0);
1113 auto *OrigContextSize = FuncPtrStruct->getOperand(1);
1114 auto *NewContextSize = ConstantInt::get(OrigContextSize->getType(),
1117 FuncPtrStruct->getType(), OrigRelativeFunOffset, NewContextSize);
1136 auto *SizeIntrin = Shape.
CoroSizes.back();
1137 auto *SizeConstant = ConstantInt::get(SizeIntrin->getType(),
1162 switch (Shape.
ABI) {
1171 auto *Frame = Builder.CreateAlloca(
1172 FrameTy,
nullptr, AllocInst->getFunction()->getName() +
".Frame");
1174 AllocInst->replaceAllUsesWith(Builder.getFalse());
1175 AllocInst->eraseFromParent();
1176 CoroBegin->replaceAllUsesWith(Frame);
1178 CoroBegin->replaceAllUsesWith(CoroBegin->getMem());
1219 while (!Worklist.
empty()) {
1223 if (!Set.contains(Pred))
1229 Set.erase(ResDesBB);
1231 for (
auto *BB : Set)
1240 auto *ResumeOrDestroyBB = ResumeOrDestroy->
getParent();
1244 if (SaveBB == ResumeOrDestroyBB)
1253 {ResumeOrDestroyBB->getFirstNonPHIIt(), ResumeOrDestroyIt}))
1269 auto *Pred = Suspend->
getParent()->getSinglePredecessor();
1272 Prev = Pred->getTerminator();
1287 if (SubFn->getFrame() != CoroBegin)
1301 Save->eraseFromParent();
1313 if (CalledValue != SubFn && CalledValue->user_empty())
1315 I->eraseFromParent();
1318 if (SubFn->user_empty())
1319 SubFn->eraseFromParent();
1331 size_t I = 0,
N = S.size();
1335 size_t ChangedFinalIndex = std::numeric_limits<size_t>::max();
1348 ChangedFinalIndex =
I;
1360 if (ChangedFinalIndex <
N) {
1362 std::swap(S[ChangedFinalIndex], S.back());
1368struct SwitchCoroutineSplitter {
1369 static void split(Function &
F, coro::Shape &Shape,
1370 SmallVectorImpl<Function *> &Clones,
1371 TargetTransformInfo &
TTI) {
1377 createResumeEntryBlock(
F, Shape);
1379 F,
".resume", Shape, coro::CloneKind::SwitchResume,
TTI);
1381 F,
".destroy", Shape, coro::CloneKind::SwitchUnwind,
TTI);
1383 F,
".cleanup", Shape, coro::CloneKind::SwitchCleanup,
TTI);
1390 updateCoroFrame(Shape, ResumeClone, DestroyClone, CleanupClone);
1400 setCoroInfo(
F, Shape, Clones);
1410 static Function *createNoAllocVariant(Function &
F, coro::Shape &Shape,
1411 SmallVectorImpl<Function *> &Clones) {
1413 auto *OrigFnTy =
F.getFunctionType();
1414 auto OldParams = OrigFnTy->params();
1417 NewParams.
reserve(OldParams.size() + 1);
1418 NewParams.
append(OldParams.begin(), OldParams.end());
1421 auto *NewFnTy = FunctionType::get(OrigFnTy->getReturnType(), NewParams,
1422 OrigFnTy->isVarArg());
1424 NewFnTy,
F.getLinkage(),
F.getAddressSpace(),
F.getName() +
".noalloc");
1427 unsigned int Idx = 0;
1428 for (
const auto &
I :
F.args()) {
1429 VMap[&
I] = NoAllocF->
getArg(Idx++);
1433 auto FrameIdx = NoAllocF->
arg_size() - 1;
1436 CloneFunctionChangeType::LocalChangesOnly, Returns);
1439 auto *NewCoroBegin =
1443 NewCoroBegin->replaceAllUsesWith(NoAllocF->
getArg(FrameIdx));
1444 NewCoroBegin->eraseFromParent();
1448 M->getFunctionList().insert(
M->end(), NoAllocF);
1463 setCoroInfo(
F, Shape, Clones);
1474 static void createResumeEntryBlock(Function &
F, coro::Shape &Shape) {
1477 DIBuilder DBuilder(*
F.getParent(),
false);
1478 DISubprogram *DIS =
F.getSubprogram();
1482 bool AddDebugLabels = DIS && DIS->getUnit() &&
1483 (DIS->getUnit()->getEmissionKind() ==
1484 DICompileUnit::DebugEmissionKind::FullDebug);
1503 Builder.CreateSwitch(Index, UnreachBB, Shape.
CoroSuspends.size());
1507 size_t SuspendIndex = 0;
1510 ConstantInt *IndexVal = Shape.
getIndex(SuspendIndex);
1515 auto *Save = S->getCoroSave();
1516 Builder.SetInsertPoint(Save);
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);
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();
1576 DILocation *DILoc = SuspendLoc;
1577 while (DILocation *InlinedAt = DILoc->getInlinedAt())
1580 DILabel *ResumeLabel =
1581 DBuilder.createLabel(DIS, LabelName, DILoc->getFile(),
1582 SuspendLoc.getLine(), SuspendLoc.getCol(),
1586 DBuilder.insertLabel(ResumeLabel, DILoc, ResumeBB->begin());
1593 Builder.SetInsertPoint(UnreachBB);
1594 Builder.CreateUnreachable();
1595 DBuilder.finalize();
1601 static void updateCoroFrame(coro::Shape &Shape, Function *ResumeFn,
1602 Function *DestroyFn, Function *CleanupFn) {
1608 Builder.CreateStore(ResumeFn, ResumeAddr);
1610 Value *DestroyOrCleanupFn = DestroyFn;
1616 DestroyOrCleanupFn = Builder.CreateSelect(CA, DestroyFn, CleanupFn);
1620 Value *DestroyAddr = Builder.CreateInBoundsPtrAdd(
1622 ConstantInt::get(Type::getInt64Ty(
C),
1625 Builder.CreateStore(DestroyOrCleanupFn, DestroyAddr);
1641 static void setCoroInfo(Function &
F, coro::Shape &Shape,
1645 SmallVector<Constant *, 4>
Args(Fns);
1649 auto *ArrTy = ArrayType::get(Part->
getType(),
Args.size());
1652 auto *GV =
new GlobalVariable(*M, ConstVal->getType(),
true,
1653 GlobalVariable::PrivateLinkage, ConstVal,
1654 F.getName() + Twine(
".resumers"));
1657 LLVMContext &
C =
F.getContext();
1668 auto &Context = Suspend->
getParent()->getParent()->getContext();
1672 auto *Val = Builder.CreateBitOrPointerCast(
Continuation, Int8PtrTy);
1673 ResumeIntrinsic->replaceAllUsesWith(Val);
1674 ResumeIntrinsic->eraseFromParent();
1684 for (
auto *paramTy : FnTy->params()) {
1686 if (paramTy != FnArgs[ArgIdx]->
getType())
1688 Builder.CreateBitOrPointerCast(FnArgs[ArgIdx], paramTy));
1705 auto *TailCall = Builder.CreateCall(FnTy, MustTailCallFn, CallArgs);
1707 if (
TTI.supportsTailCallFor(TailCall)) {
1710 TailCall->setDebugLoc(
Loc);
1722 F.removeFnAttr(Attribute::NoReturn);
1723 F.removeRetAttr(Attribute::NoAlias);
1724 F.removeRetAttr(Attribute::NonNull);
1726 auto &Context =
F.getContext();
1729 auto *Id =
Shape.getAsyncCoroId();
1734 FramePtr = Builder.CreateInBoundsPtrAdd(
1737 Shape.AsyncLowering.FrameOffset),
1738 "async.ctx.frameptr");
1749 auto NextF = std::next(
F.getIterator());
1757 auto ResumeNameSuffix =
".resume.";
1758 auto ProjectionFunctionName =
1759 Suspend->getAsyncContextProjectionFunction()->getName();
1760 bool UseSwiftMangling =
false;
1761 if (ProjectionFunctionName ==
"__swift_async_resume_project_context") {
1762 ResumeNameSuffix =
"TQ";
1763 UseSwiftMangling =
true;
1764 }
else if (ProjectionFunctionName ==
"__swift_async_resume_get_context") {
1765 ResumeNameSuffix =
"TY";
1766 UseSwiftMangling =
true;
1770 UseSwiftMangling ? ResumeNameSuffix +
Twine(Idx) +
"_"
1771 : ResumeNameSuffix +
Twine(Idx),
1777 auto *SuspendBB = Suspend->getParent();
1778 auto *NewSuspendBB = SuspendBB->splitBasicBlock(Suspend);
1784 Branch->setSuccessor(0, ReturnBB);
1789 auto *Fn = Suspend->getMustTailCallFunction();
1795 Builder.CreateRetVoid();
1807 auto *Clone = Clones[Idx];
1822 F.removeFnAttr(Attribute::NoReturn);
1823 F.removeRetAttr(Attribute::NoAlias);
1824 F.removeRetAttr(Attribute::NonNull);
1827 auto *Id =
Shape.getRetconCoroId();
1829 if (
Shape.RetconLowering.IsFrameInlineInStorage) {
1830 RawFramePtr = Id->getStorage();
1834 auto FrameSize = Builder.getInt64(
Shape.FrameSize);
1839 RawFramePtr =
Shape.emitAlloc(Builder, FrameSize,
nullptr);
1841 Builder.CreateBitCast(RawFramePtr,
Shape.CoroBegin->getType());
1844 Builder.CreateStore(RawFramePtr, Id->getStorage());
1851 Shape.CoroBegin->replaceAllUsesWith(RawFramePtr);
1857 PHINode *ContinuationPhi =
nullptr;
1861 auto NextF = std::next(
F.getIterator());
1870 F,
Shape,
".resume." +
Twine(Idx), NextF,
nullptr);
1875 auto SuspendBB = Suspend->getParent();
1876 auto NewSuspendBB = SuspendBB->splitBasicBlock(Suspend);
1884 Shape.RetconLowering.ReturnBlock = ReturnBB;
1896 for (
auto *ResultTy :
Shape.getRetconResultTypes())
1898 Builder.CreatePHI(ResultTy,
Shape.CoroSuspends.size()));
1901 auto RetTy =
F.getReturnType();
1906 auto CastedContinuationTy =
1907 (ReturnPHIs.
empty() ? RetTy : RetTy->getStructElementType(0));
1908 auto *CastedContinuation =
1909 Builder.CreateBitCast(ContinuationPhi, CastedContinuationTy);
1911 Value *RetV = CastedContinuation;
1912 if (!ReturnPHIs.
empty()) {
1915 RetV = Builder.CreateInsertValue(RetV, CastedContinuation, ValueIdx++);
1917 for (
auto Phi : ReturnPHIs)
1918 RetV = Builder.CreateInsertValue(RetV, Phi, ValueIdx++);
1921 Builder.CreateRet(RetV);
1925 Branch->setSuccessor(0, ReturnBB);
1928 for (
auto [Phi, VUse] :
1930 Phi->addIncoming(VUse, SuspendBB);
1937 auto Clone = Clones[Idx];
1951 OS <<
"While splitting coroutine ";
1952 F.printAsOperand(OS,
false,
F.getParent());
1972 auto &Ctx =
II->getContext();
1974 II->eraseFromParent();
1979 for (
auto *U :
F.users()) {
1981 auto *Caller = CB->getFunction();
1982 if (Caller && Caller->isPresplitCoroutine() &&
1983 CB->hasFnAttr(llvm::Attribute::CoroElideSafe))
1993 SwitchCoroutineSplitter::split(
F,
Shape, Clones,
TTI);
1998 bool OptimizeFrame) {
1999 PrettyStackTraceFunction prettyStackTrace(
F);
2001 auto &Shape = ABI.
Shape;
2009 ABI.buildCoroutineFrame(OptimizeFrame);
2012 bool isNoSuspendCoroutine = Shape.
CoroSuspends.empty();
2014 bool shouldCreateNoAllocVariant =
2020 if (isNoSuspendCoroutine) {
2023 ABI.splitCoroutine(
F, Shape, Clones,
TTI);
2041 if (shouldCreateNoAllocVariant)
2042 SwitchCoroutineSplitter::createNoAllocVariant(
F, Shape, Clones);
2051 auto *CurrentSCC = &
C;
2052 if (!Clones.
empty()) {
2053 switch (Shape.
ABI) {
2065 if (!Clones.empty())
2098 if (!Cast || Cast->getType() != Fn->getType())
2102 Cast->replaceAllUsesWith(Fn);
2103 Cast->eraseFromParent();
2113 if (!Cast->use_empty())
2115 CastFn = Cast->getOperand(0);
2116 Cast->eraseFromParent();
2136 auto *PrepareFn = M.getFunction(Name);
2137 if (PrepareFn && !PrepareFn->use_empty())
2141static std::unique_ptr<coro::BaseABI>
2147 if (CustomABI >= GenCustomABIs.
size())
2149 return GenCustomABIs[CustomABI](
F, S);
2154 return std::make_unique<coro::SwitchABI>(
F, S, IsMatCallback);
2156 return std::make_unique<coro::AsyncABI>(
F, S, IsMatCallback);
2158 return std::make_unique<coro::AnyRetconABI>(
F, S, IsMatCallback);
2160 return std::make_unique<coro::AnyRetconABI>(
F, S, IsMatCallback);
2167 std::unique_ptr<coro::BaseABI> ABI =
2172 OptimizeFrame(OptimizeFrame) {}
2177 std::unique_ptr<coro::BaseABI> ABI =
2182 OptimizeFrame(OptimizeFrame) {}
2189 std::unique_ptr<coro::BaseABI> ABI =
2194 OptimizeFrame(OptimizeFrame) {}
2202 std::unique_ptr<coro::BaseABI> ABI =
2207 OptimizeFrame(OptimizeFrame) {}
2215 Module &M = *
C.begin()->getFunction().getParent();
2227 if (
N.getFunction().isPresplitCoroutine())
2230 if (Coroutines.
empty() && PrepareFns.
empty())
2233 auto *CurrentSCC = &
C;
2237 LLVM_DEBUG(
dbgs() <<
"CoroSplit: Processing coroutine '" <<
F.getName()
2249 F.setSplittedCoroutine();
2257 *
N, Shape, Clones, *CurrentSCC, CG, AM, UR,
FAM);
2262 <<
"Split '" <<
ore::NV(
"function",
F.getName())
2279 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 replaceFallthroughCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InRamp, CallGraph *CG)
Replace a non-unwind call to llvm.coro.end.
static void replaceSwiftErrorOps(Function &F, coro::Shape &Shape, ValueToValueMapTy *VMap)
static void replaceCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InRamp, CallGraph *CG)
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)
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 removeCoroIsInRampFromRampFunction(const coro::Shape &Shape)
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 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)
static bool simplifySuspendPoint(CoroSuspendInst *Suspend, CoroBeginInst *CoroBegin)
static Value * createSwitchIndexPtr(const coro::Shape &Shape, IRBuilder<> &Builder, Value *FramePtr)
Create a pointer to the switch index field in the coroutine frame.
static void removeCoroEndsFromRampFunction(const coro::Shape &Shape)
Remove calls to llvm.coro.end in the original function.
static void markCoroutineAsDone(IRBuilder<> &Builder, const coro::Shape &Shape, Value *FramePtr)
static void updateAsyncFuncPointerContextSize(coro::Shape &Shape)
static void coerceArguments(IRBuilder<> &Builder, FunctionType *FnTy, ArrayRef< Value * > FnArgs, SmallVectorImpl< Value * > &CallArgs)
Coerce the arguments in FnArgs according to FnTy in CallArgs.
static void replaceUnwindCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InRamp, CallGraph *CG)
Replace an unwind call to llvm.coro.end.
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 void replacePrepare(CallInst *Prepare, LazyCallGraph &CG, LazyCallGraph::SCC &C)
Replace a call to llvm.coro.prepare.retcon.
static void replaceAsyncResumeFunction(CoroSuspendAsyncInst *Suspend, Value *Continuation)
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.
Machine Check Debug Module
uint64_t IntrinsicInst * II
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
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
CoroAllocInst * getCoroAlloc()
This class represents an incoming formal argument to a Function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM Basic Block Representation.
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
const Function * getParent() const
Return the enclosing method, or null if none.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Value * getCalledOperand() const
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.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.
bool hasCustomABI() const
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.
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.
Argument * getArg(unsigned i) const
void setLinkage(LinkageTypes LT)
unsigned getAddressSpace() const
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 ...
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.
Represent a constant reference to a string, i.e.
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...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
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.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
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()
AnyCoroSuspendInst * ActiveSuspend
The active suspend instruction; meaningful only for continuation and async ABIs.
Value * deriveNewFramePointer()
Derive the value of the new frame pointer.
void replaceCoroSuspends()
void handleFinalSuspend()
TargetTransformInfo & TTI
static Function * createClone(Function &OrigF, const Twine &Suffix, coro::Shape &Shape, Function *NewF, AnyCoroSuspendInst *ActiveSuspend, TargetTransformInfo &TTI)
Create a clone for a continuation lowering.
void replaceCoroIsInRamp()
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.
@ 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<> &)
LLVM_ABI bool isTriviallyMaterializable(Instruction &I)
@ SwitchCleanup
The shared cleanup function for a switch lowering.
@ Continuation
An individual continuation function.
void elideCoroFree(Value *FramePtr)
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.
FunctionAddr VTableAddr Value
auto cast_if_present(const Y &Val)
cast_if_present<X> - Functionally identical to cast, except that a null value is accepted.
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
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,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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...
bool isa_and_nonnull(const Y &Val)
LLVM_ABI InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, bool MergeAttributes=false, AAResults *CalleeAAR=nullptr, bool InsertLifetime=true, bool TrackInlineHistory=false, Function *ForwardVarArgsTo=nullptr, OptimizationRemarkEmitter *ORE=nullptr)
This function inlines the called function into the basic block of the caller.
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
auto dyn_cast_or_null(const Y &Val)
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)
iterator_range< SplittingIterator > split(StringRef Str, StringRef Separator)
Split the specified string over a separator and return a range-compatible iterable over its partition...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
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.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr, const CycleInfo *CI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
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.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
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.
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.
constexpr 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
SwitchInst * ResumeSwitch
BasicBlock * ResumeEntryBlock
SmallVector< CallInst *, 2 > SymmetricTransfers
SmallVector< CoroAwaitSuspendInst *, 4 > CoroAwaitSuspends
AsyncLoweringStorage AsyncLowering
FunctionType * getResumeFunctionType() const
IntegerType * getIndexType() const
PointerType * getSwitchResumePointerType() const
CoroIdInst * getSwitchCoroId() const
SmallVector< CoroSizeInst *, 2 > CoroSizes
SmallVector< AnyCoroSuspendInst *, 4 > CoroSuspends
ConstantInt * getIndex(uint64_t Value) const
SwitchLoweringStorage SwitchLowering
CoroBeginInst * CoroBegin
BasicBlock::iterator getInsertPtAfterFramePtr() const
SmallVector< CoroIsInRampInst *, 2 > CoroIsInRampInsts
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
SmallVector< AnyCoroEndInst *, 4 > CoroEnds
SmallVector< CallInst *, 2 > SwiftErrorOps