LLVM 23.0.0git
CoroSplit.cpp
Go to the documentation of this file.
1//===- CoroSplit.cpp - Converts a coroutine into a state machine ----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8// This pass builds the coroutine frame and outlines resume and destroy parts
9// of the coroutine into separate functions.
10//
11// We present a coroutine to an LLVM as an ordinary function with suspension
12// points marked up with intrinsics. We let the optimizer party on the coroutine
13// as a single function for as long as possible. Shortly before the coroutine is
14// eligible to be inlined into its callers, we split up the coroutine into parts
15// corresponding to an initial, resume and destroy invocations of the coroutine,
16// add them to the current SCC and restart the IPO pipeline to optimize the
17// coroutine subfunctions we extracted before proceeding to the caller of the
18// coroutine.
19//===----------------------------------------------------------------------===//
20
22#include "CoroCloner.h"
23#include "CoroInternal.h"
24#include "llvm/ADT/DenseMap.h"
26#include "llvm/ADT/STLExtras.h"
30#include "llvm/ADT/StringRef.h"
31#include "llvm/ADT/Twine.h"
32#include "llvm/Analysis/CFG.h"
39#include "llvm/IR/Argument.h"
40#include "llvm/IR/Attributes.h"
41#include "llvm/IR/BasicBlock.h"
42#include "llvm/IR/CFG.h"
43#include "llvm/IR/CallingConv.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DIBuilder.h"
46#include "llvm/IR/DataLayout.h"
47#include "llvm/IR/DebugInfo.h"
49#include "llvm/IR/Dominators.h"
50#include "llvm/IR/GlobalValue.h"
53#include "llvm/IR/InstrTypes.h"
54#include "llvm/IR/Instruction.h"
57#include "llvm/IR/LLVMContext.h"
58#include "llvm/IR/Module.h"
59#include "llvm/IR/Type.h"
60#include "llvm/IR/Value.h"
61#include "llvm/IR/Verifier.h"
63#include "llvm/Support/Debug.h"
72#include <cassert>
73#include <cstddef>
74#include <cstdint>
75#include <initializer_list>
76#include <iterator>
77
78using namespace llvm;
79
80#define DEBUG_TYPE "coro-split"
81
82// FIXME:
83// Lower the intrinisc in CoroEarly phase if coroutine frame doesn't escape
84// and it is known that other transformations, for example, sanitizers
85// won't lead to incorrect code.
87 coro::Shape &Shape) {
88 auto Wrapper = CB->getWrapperFunction();
89 auto Awaiter = CB->getAwaiter();
90 auto FramePtr = CB->getFrame();
91
92 Builder.SetInsertPoint(CB);
93
94 CallBase *NewCall = nullptr;
95 // await_suspend has only 2 parameters, awaiter and handle.
96 // Copy parameter attributes from the intrinsic call, but remove the last,
97 // because the last parameter now becomes the function that is being called.
98 AttributeList NewAttributes =
99 CB->getAttributes().removeParamAttributes(CB->getContext(), 2);
100
101 if (auto Invoke = dyn_cast<InvokeInst>(CB)) {
102 auto WrapperInvoke =
103 Builder.CreateInvoke(Wrapper, Invoke->getNormalDest(),
104 Invoke->getUnwindDest(), {Awaiter, FramePtr});
105
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;
112 } else if (auto Call = dyn_cast<CallInst>(CB)) {
113 auto WrapperCall = Builder.CreateCall(Wrapper, {Awaiter, FramePtr});
114
115 WrapperCall->setAttributes(NewAttributes);
116 WrapperCall->setDebugLoc(Call->getDebugLoc());
117 NewCall = WrapperCall;
118 } else {
119 llvm_unreachable("Unexpected coro_await_suspend invocation method");
120 }
121
122 if (CB->getCalledFunction()->getIntrinsicID() ==
123 Intrinsic::coro_await_suspend_handle) {
124 // Follow the lowered await_suspend call above with a lowered resume call
125 // to the returned coroutine.
126 if (auto *Invoke = dyn_cast<InvokeInst>(CB)) {
127 // If the await_suspend call is an invoke, we continue in the next block.
128 Builder.SetInsertPoint(Invoke->getNormalDest()->getFirstInsertionPt());
129 }
130
131 coro::LowererBase LB(*Wrapper->getParent());
132 auto *ResumeAddr = LB.makeSubFnCall(NewCall, CoroSubFnInst::ResumeIndex,
133 &*Builder.GetInsertPoint());
134
135 LLVMContext &Ctx = Builder.getContext();
137 Type::getVoidTy(Ctx), PointerType::getUnqual(Ctx), false);
138 auto *ResumeCall = Builder.CreateCall(ResumeTy, ResumeAddr, {NewCall});
139 ResumeCall->setCallingConv(CallingConv::Fast);
140
141 // We can't insert the 'ret' instruction and adjust the cc until the
142 // function has been split, so remember this for later.
143 Shape.SymmetricTransfers.push_back(ResumeCall);
144
145 NewCall = ResumeCall;
146 }
147
148 CB->replaceAllUsesWith(NewCall);
149 CB->eraseFromParent();
150}
151
153 IRBuilder<> Builder(F.getContext());
154 for (auto *AWS : Shape.CoroAwaitSuspends)
155 lowerAwaitSuspend(Builder, AWS, Shape);
156}
157
159 const coro::Shape &Shape, Value *FramePtr,
160 CallGraph *CG) {
163 return;
164
165 Shape.emitDealloc(Builder, FramePtr, CG);
166}
167
168/// Replace an llvm.coro.end.async.
169/// Will inline the must tail call function call if there is one.
170/// \returns true if cleanup of the coro.end block is needed, false otherwise.
172 IRBuilder<> Builder(End);
173
174 auto *EndAsync = dyn_cast<CoroAsyncEndInst>(End);
175 if (!EndAsync) {
176 Builder.CreateRetVoid();
177 return true /*needs cleanup of coro.end block*/;
178 }
179
180 auto *MustTailCallFunc = EndAsync->getMustTailCallFunction();
181 if (!MustTailCallFunc) {
182 Builder.CreateRetVoid();
183 return true /*needs cleanup of coro.end block*/;
184 }
185
186 // Move the must tail call from the predecessor block into the end block.
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());
194
195 // Insert the return instruction.
196 Builder.SetInsertPoint(End);
197 Builder.CreateRetVoid();
198 InlineFunctionInfo FnInfo;
199
200 // Remove the rest of the block, by splitting it into an unreachable block.
201 auto *BB = End->getParent();
202 BB->splitBasicBlock(End);
203 BB->getTerminator()->eraseFromParent();
204
205 auto InlineRes = InlineFunction(*MustTailCall, FnInfo);
206 assert(InlineRes.isSuccess() && "Expected inlining to succeed");
207 (void)InlineRes;
208
209 // We have cleaned up the coro.end block above.
210 return false;
211}
212
213/// Replace a non-unwind call to llvm.coro.end.
215 const coro::Shape &Shape, Value *FramePtr,
216 bool InRamp, CallGraph *CG) {
217 // Start inserting right before the coro.end.
218 IRBuilder<> Builder(End);
219
220 // Create the return instruction.
221 switch (Shape.ABI) {
222 // The cloned functions in switch-lowering always return void.
224 assert(!cast<CoroEndInst>(End)->hasResults() &&
225 "switch coroutine should not return any values");
226 // coro.end doesn't immediately end the coroutine in the main function
227 // in this lowering, because we need to deallocate the coroutine.
228 if (InRamp)
229 return;
230 Builder.CreateRetVoid();
231 break;
232
233 // In async lowering this returns.
234 case coro::ABI::Async: {
235 bool CoroEndBlockNeedsCleanup = replaceCoroEndAsync(End);
236 if (!CoroEndBlockNeedsCleanup)
237 return;
238 break;
239 }
240
241 // In unique continuation lowering, the continuations always return void.
242 // But we may have implicitly allocated storage.
244 maybeFreeRetconStorage(Builder, Shape, FramePtr, CG);
245 auto *CoroEnd = cast<CoroEndInst>(End);
246 auto *RetTy = Shape.getResumeFunctionType()->getReturnType();
247
248 if (!CoroEnd->hasResults()) {
249 assert(RetTy->isVoidTy());
250 Builder.CreateRetVoid();
251 break;
252 }
253
254 auto *CoroResults = CoroEnd->getResults();
255 unsigned NumReturns = CoroResults->numReturns();
256
257 if (auto *RetStructTy = dyn_cast<StructType>(RetTy)) {
258 assert(RetStructTy->getNumElements() == NumReturns &&
259 "numbers of returns should match resume function singature");
260 Value *ReturnValue = PoisonValue::get(RetStructTy);
261 unsigned Idx = 0;
262 for (Value *RetValEl : CoroResults->return_values())
263 ReturnValue = Builder.CreateInsertValue(ReturnValue, RetValEl, Idx++);
264 Builder.CreateRet(ReturnValue);
265 } else if (NumReturns == 0) {
266 assert(RetTy->isVoidTy());
267 Builder.CreateRetVoid();
268 } else {
269 assert(NumReturns == 1);
270 Builder.CreateRet(*CoroResults->retval_begin());
271 }
272 CoroResults->replaceAllUsesWith(
273 ConstantTokenNone::get(CoroResults->getContext()));
274 CoroResults->eraseFromParent();
275 break;
276 }
277
278 // In non-unique continuation lowering, we signal completion by returning
279 // a null continuation.
280 case coro::ABI::Retcon: {
281 assert(!cast<CoroEndInst>(End)->hasResults() &&
282 "retcon coroutine should not return any values");
283 maybeFreeRetconStorage(Builder, Shape, FramePtr, CG);
284 auto RetTy = Shape.getResumeFunctionType()->getReturnType();
285 auto RetStructTy = dyn_cast<StructType>(RetTy);
286 PointerType *ContinuationTy =
287 cast<PointerType>(RetStructTy ? RetStructTy->getElementType(0) : RetTy);
288
289 Value *ReturnValue = ConstantPointerNull::get(ContinuationTy);
290 if (RetStructTy) {
291 ReturnValue = Builder.CreateInsertValue(PoisonValue::get(RetStructTy),
292 ReturnValue, 0);
293 }
294 Builder.CreateRet(ReturnValue);
295 break;
296 }
297 }
298
299 // Remove the rest of the block, by splitting it into an unreachable block.
300 auto *BB = End->getParent();
301 BB->splitBasicBlock(End);
302 BB->getTerminator()->eraseFromParent();
303}
304
305/// Create a pointer to the switch index field in the coroutine frame.
307 IRBuilder<> &Builder, Value *FramePtr) {
308 auto *Offset = ConstantInt::get(Type::getInt64Ty(FramePtr->getContext()),
310 return Builder.CreateInBoundsPtrAdd(FramePtr, Offset, "index.addr");
311}
312
313// Mark a coroutine as done, which implies that the coroutine is finished and
314// never gets resumed.
315//
316// In resume-switched ABI, the done state is represented by storing zero in
317// ResumeFnAddr.
318//
319// NOTE: We couldn't omit the argument `FramePtr`. It is necessary because the
320// pointer to the frame in splitted function is not stored in `Shape`.
321static void markCoroutineAsDone(IRBuilder<> &Builder, const coro::Shape &Shape,
322 Value *FramePtr) {
323 assert(
324 Shape.ABI == coro::ABI::Switch &&
325 "markCoroutineAsDone is only supported for Switch-Resumed ABI for now.");
326 // Resume function pointer is always first
328 Builder.CreateStore(NullPtr, FramePtr);
329
330 // If the coroutine don't have unwind coro end, we could omit the store to
331 // the final suspend point since we could infer the coroutine is suspended
332 // at the final suspend point by the nullness of ResumeFnAddr.
333 // However, we can't skip it if the coroutine have unwind coro end. Since
334 // the coroutine reaches unwind coro end is considered suspended at the
335 // final suspend point (the ResumeFnAddr is null) but in fact the coroutine
336 // didn't complete yet. We need the IndexVal for the final suspend point
337 // to make the states clear.
340 assert(cast<CoroSuspendInst>(Shape.CoroSuspends.back())->isFinal() &&
341 "The final suspend should only live in the last position of "
342 "CoroSuspends.");
343 ConstantInt *IndexVal = Shape.getIndex(Shape.CoroSuspends.size() - 1);
344 Value *FinalIndex = createSwitchIndexPtr(Shape, Builder, FramePtr);
345 Builder.CreateStore(IndexVal, FinalIndex);
346 }
347}
348
349/// Replace an unwind call to llvm.coro.end.
350static void replaceUnwindCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape,
351 Value *FramePtr, bool InRamp, CallGraph *CG) {
352 IRBuilder<> Builder(End);
353
354 switch (Shape.ABI) {
355 // In switch-lowering, this does nothing in the main function.
356 case coro::ABI::Switch: {
357 // In C++'s specification, the coroutine should be marked as done
358 // if promise.unhandled_exception() throws. The frontend will
359 // call coro.end(true) along this path.
360 //
361 // FIXME: We should refactor this once there is other language
362 // which uses Switch-Resumed style other than C++.
363 markCoroutineAsDone(Builder, Shape, FramePtr);
364 if (InRamp)
365 return;
366 break;
367 }
368 // In async lowering this does nothing.
369 case coro::ABI::Async:
370 break;
371 // In continuation-lowering, this frees the continuation storage.
374 maybeFreeRetconStorage(Builder, Shape, FramePtr, CG);
375 break;
376 }
377
378 // If coro.end has an associated bundle, add cleanupret instruction.
379 if (auto Bundle = End->getOperandBundle(LLVMContext::OB_funclet)) {
380 auto *FromPad = cast<CleanupPadInst>(Bundle->Inputs[0]);
381 auto *CleanupRet = Builder.CreateCleanupRet(FromPad, nullptr);
382 End->getParent()->splitBasicBlock(End);
383 CleanupRet->getParent()->getTerminator()->eraseFromParent();
384 }
385}
386
387static void replaceCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape,
388 Value *FramePtr, bool InRamp, CallGraph *CG) {
389 if (End->isUnwind())
390 replaceUnwindCoroEnd(End, Shape, FramePtr, InRamp, CG);
391 else
392 replaceFallthroughCoroEnd(End, Shape, FramePtr, InRamp, CG);
393 End->eraseFromParent();
394}
395
396// In the resume function, we remove the last case (when coro::Shape is built,
397// the final suspend point (if present) is always the last element of
398// CoroSuspends array) since it is an undefined behavior to resume a coroutine
399// suspended at the final suspend point.
400// In the destroy function, if it isn't possible that the ResumeFnAddr is NULL
401// and the coroutine doesn't suspend at the final suspend point actually (this
402// is possible since the coroutine is considered suspended at the final suspend
403// point if promise.unhandled_exception() exits via an exception), we can
404// remove the last case.
407 Shape.SwitchLowering.HasFinalSuspend);
408
409 if (isSwitchDestroyFunction() && Shape.SwitchLowering.HasUnwindCoroEnd)
410 return;
411
412 auto *Switch = cast<SwitchInst>(VMap[Shape.SwitchLowering.ResumeSwitch]);
413 auto FinalCaseIt = std::prev(Switch->case_end());
414 BasicBlock *ResumeBB = FinalCaseIt->getCaseSuccessor();
415 Switch->removeCase(FinalCaseIt);
417 BasicBlock *OldSwitchBB = Switch->getParent();
418 auto *NewSwitchBB = OldSwitchBB->splitBasicBlock(Switch, "Switch");
419 Builder.SetInsertPoint(OldSwitchBB->getTerminator());
420
421 if (NewF->isCoroOnlyDestroyWhenComplete()) {
422 // When the coroutine can only be destroyed when complete, we don't need
423 // to generate code for other cases.
424 Builder.CreateBr(ResumeBB);
425 } else {
426 // Resume function pointer is always first
427 auto *Load =
428 Builder.CreateLoad(Shape.getSwitchResumePointerType(), NewFramePtr);
429 auto *Cond = Builder.CreateIsNull(Load);
430 Builder.CreateCondBr(Cond, ResumeBB, NewSwitchBB);
431 }
432 OldSwitchBB->getTerminator()->eraseFromParent();
433 }
434}
435
436static FunctionType *
438 auto *AsyncSuspend = cast<CoroSuspendAsyncInst>(Suspend);
439 auto *StructTy = cast<StructType>(AsyncSuspend->getType());
440 auto &Context = Suspend->getParent()->getParent()->getContext();
441 auto *VoidTy = Type::getVoidTy(Context);
442 return FunctionType::get(VoidTy, StructTy->elements(), false);
443}
444
446 const Twine &Suffix,
447 Module::iterator InsertBefore,
448 AnyCoroSuspendInst *ActiveSuspend) {
449 Module *M = OrigF.getParent();
450 auto *FnTy = (Shape.ABI != coro::ABI::Async)
451 ? Shape.getResumeFunctionType()
452 : getFunctionTypeFromAsyncSuspend(ActiveSuspend);
453
454 Function *NewF =
456 OrigF.getName() + Suffix);
457
458 M->getFunctionList().insert(InsertBefore, NewF);
459
460 return NewF;
461}
462
463/// Replace uses of the active llvm.coro.suspend.retcon/async call with the
464/// arguments to the continuation function.
465///
466/// This assumes that the builder has a meaningful insertion point.
469 Shape.ABI == coro::ABI::Async);
470
471 auto NewS = VMap[ActiveSuspend];
472 if (NewS->use_empty())
473 return;
474
475 // Copy out all the continuation arguments after the buffer pointer into
476 // an easily-indexed data structure for convenience.
478 // The async ABI includes all arguments -- including the first argument.
479 bool IsAsyncABI = Shape.ABI == coro::ABI::Async;
480 for (auto I = IsAsyncABI ? NewF->arg_begin() : std::next(NewF->arg_begin()),
481 E = NewF->arg_end();
482 I != E; ++I)
483 Args.push_back(&*I);
484
485 // If the suspend returns a single scalar value, we can just do a simple
486 // replacement.
487 if (!isa<StructType>(NewS->getType())) {
488 assert(Args.size() == 1);
489 NewS->replaceAllUsesWith(Args.front());
490 return;
491 }
492
493 // Try to peephole extracts of an aggregate return.
494 for (Use &U : llvm::make_early_inc_range(NewS->uses())) {
495 auto *EVI = dyn_cast<ExtractValueInst>(U.getUser());
496 if (!EVI || EVI->getNumIndices() != 1)
497 continue;
498
499 EVI->replaceAllUsesWith(Args[EVI->getIndices().front()]);
500 EVI->eraseFromParent();
501 }
502
503 // If we have no remaining uses, we're done.
504 if (NewS->use_empty())
505 return;
506
507 // Otherwise, we need to create an aggregate.
508 Value *Aggr = PoisonValue::get(NewS->getType());
509 for (auto [Idx, Arg] : llvm::enumerate(Args))
510 Aggr = Builder.CreateInsertValue(Aggr, Arg, Idx);
511
512 NewS->replaceAllUsesWith(Aggr);
513}
514
516 Value *SuspendResult;
517
518 switch (Shape.ABI) {
519 // In switch lowering, replace coro.suspend with the appropriate value
520 // for the type of function we're extracting.
521 // Replacing coro.suspend with (0) will result in control flow proceeding to
522 // a resume label associated with a suspend point, replacing it with (1) will
523 // result in control flow proceeding to a cleanup label associated with this
524 // suspend point.
526 SuspendResult = Builder.getInt8(isSwitchDestroyFunction() ? 1 : 0);
527 break;
528
529 // In async lowering there are no uses of the result.
530 case coro::ABI::Async:
531 return;
532
533 // In returned-continuation lowering, the arguments from earlier
534 // continuations are theoretically arbitrary, and they should have been
535 // spilled.
538 return;
539 }
540
541 for (AnyCoroSuspendInst *CS : Shape.CoroSuspends) {
542 // The active suspend was handled earlier.
543 if (CS == ActiveSuspend)
544 continue;
545
546 auto *MappedCS = cast<AnyCoroSuspendInst>(VMap[CS]);
547 MappedCS->replaceAllUsesWith(SuspendResult);
548 MappedCS->eraseFromParent();
549 }
550}
551
553 for (AnyCoroEndInst *CE : Shape.CoroEnds) {
554 // We use a null call graph because there's no call graph node for
555 // the cloned function yet. We'll just be rebuilding that later.
556 auto *NewCE = cast<AnyCoroEndInst>(VMap[CE]);
557 replaceCoroEnd(NewCE, Shape, NewFramePtr, /*in ramp*/ false, nullptr);
558 }
559}
560
562 auto &Ctx = OrigF.getContext();
563 for (auto *II : Shape.CoroIsInRampInsts) {
564 auto *NewII = cast<CoroIsInRampInst>(VMap[II]);
565 NewII->replaceAllUsesWith(ConstantInt::getFalse(Ctx));
566 NewII->eraseFromParent();
567 }
568}
569
571 ValueToValueMapTy *VMap) {
572 if (Shape.ABI == coro::ABI::Async && Shape.CoroSuspends.empty())
573 return;
574 Value *CachedSlot = nullptr;
575 auto getSwiftErrorSlot = [&](Type *ValueTy) -> Value * {
576 if (CachedSlot)
577 return CachedSlot;
578
579 // Check if the function has a swifterror argument.
580 for (auto &Arg : F.args()) {
581 if (Arg.isSwiftError()) {
582 CachedSlot = &Arg;
583 return &Arg;
584 }
585 }
586
587 // Create a swifterror alloca.
588 IRBuilder<> Builder(&F.getEntryBlock(),
589 F.getEntryBlock().getFirstNonPHIOrDbg());
590 auto Alloca = Builder.CreateAlloca(ValueTy);
591 Alloca->setSwiftError(true);
592
593 CachedSlot = Alloca;
594 return Alloca;
595 };
596
597 for (CallInst *Op : Shape.SwiftErrorOps) {
598 auto MappedOp = VMap ? cast<CallInst>((*VMap)[Op]) : Op;
599 IRBuilder<> Builder(MappedOp);
600
601 // If there are no arguments, this is a 'get' operation.
602 Value *MappedResult;
603 if (Op->arg_empty()) {
604 auto ValueTy = Op->getType();
605 auto Slot = getSwiftErrorSlot(ValueTy);
606 MappedResult = Builder.CreateLoad(ValueTy, Slot);
607 } else {
608 assert(Op->arg_size() == 1);
609 auto Value = MappedOp->getArgOperand(0);
610 auto ValueTy = Value->getType();
611 auto Slot = getSwiftErrorSlot(ValueTy);
612 Builder.CreateStore(Value, Slot);
613 MappedResult = Slot;
614 }
615
616 MappedOp->replaceAllUsesWith(MappedResult);
617 MappedOp->eraseFromParent();
618 }
619
620 // If we're updating the original function, we've invalidated SwiftErrorOps.
621 if (VMap == nullptr) {
622 Shape.SwiftErrorOps.clear();
623 }
624}
625
626/// Returns all debug records in F.
629 SmallVector<DbgVariableRecord *> DbgVariableRecords;
630 for (auto &I : instructions(F)) {
631 for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange()))
632 DbgVariableRecords.push_back(&DVR);
633 }
634 return DbgVariableRecords;
635}
636
640
642 auto DbgVariableRecords = collectDbgVariableRecords(*NewF);
644
645 // Only 64-bit ABIs have a register we can refer to with the entry value.
646 bool UseEntryValue = OrigF.getParent()->getTargetTriple().isArch64Bit();
647 for (DbgVariableRecord *DVR : DbgVariableRecords)
648 coro::salvageDebugInfo(ArgToAllocaMap, *DVR, UseEntryValue);
649
650 // Remove all salvaged dbg.declare intrinsics that became
651 // either unreachable or stale due to the CoroSplit transformation.
652 DominatorTree DomTree(*NewF);
653 auto IsUnreachableBlock = [&](BasicBlock *BB) {
654 return !isPotentiallyReachable(&NewF->getEntryBlock(), BB, nullptr,
655 &DomTree);
656 };
657 auto RemoveOne = [&](DbgVariableRecord *DVI) {
658 if (IsUnreachableBlock(DVI->getParent()))
659 DVI->eraseFromParent();
660 else if (isa_and_nonnull<AllocaInst>(DVI->getVariableLocationOp(0))) {
661 // Count all non-debuginfo uses in reachable blocks.
662 unsigned Uses = 0;
663 for (auto *User : DVI->getVariableLocationOp(0)->users())
664 if (auto *I = dyn_cast<Instruction>(User))
665 if (!isa<AllocaInst>(I) && !IsUnreachableBlock(I->getParent()))
666 ++Uses;
667 if (!Uses)
668 DVI->eraseFromParent();
669 }
670 };
671 for_each(DbgVariableRecords, RemoveOne);
672}
673
675 // In the original function, the AllocaSpillBlock is a block immediately
676 // following the allocation of the frame object which defines GEPs for
677 // all the allocas that have been moved into the frame, and it ends by
678 // branching to the original beginning of the coroutine. Make this
679 // the entry block of the cloned function.
680 auto *Entry = cast<BasicBlock>(VMap[Shape.AllocaSpillBlock]);
681 auto *OldEntry = &NewF->getEntryBlock();
682 Entry->setName("entry" + Suffix);
683 Entry->moveBefore(OldEntry);
684 Entry->getTerminator()->eraseFromParent();
685
686 // Clear all predecessors of the new entry block. There should be
687 // exactly one predecessor, which we created when splitting out
688 // AllocaSpillBlock to begin with.
689 assert(Entry->hasOneUse());
690 auto BranchToEntry = cast<BranchInst>(Entry->user_back());
691 assert(BranchToEntry->isUnconditional());
692 Builder.SetInsertPoint(BranchToEntry);
693 Builder.CreateUnreachable();
694 BranchToEntry->eraseFromParent();
695
696 // Branch from the entry to the appropriate place.
697 Builder.SetInsertPoint(Entry);
698 switch (Shape.ABI) {
699 case coro::ABI::Switch: {
700 // In switch-lowering, we built a resume-entry block in the original
701 // function. Make the entry block branch to this.
702 auto *SwitchBB =
703 cast<BasicBlock>(VMap[Shape.SwitchLowering.ResumeEntryBlock]);
704 Builder.CreateBr(SwitchBB);
705 SwitchBB->moveAfter(Entry);
706 break;
707 }
708 case coro::ABI::Async:
711 // In continuation ABIs, we want to branch to immediately after the
712 // active suspend point. Earlier phases will have put the suspend in its
713 // own basic block, so just thread our jump directly to its successor.
714 assert((Shape.ABI == coro::ABI::Async &&
716 ((Shape.ABI == coro::ABI::Retcon ||
720 auto Branch = cast<BranchInst>(MappedCS->getNextNode());
721 assert(Branch->isUnconditional());
722 Builder.CreateBr(Branch->getSuccessor(0));
723 break;
724 }
725 }
726
727 // Any static alloca that's still being used but not reachable from the new
728 // entry needs to be moved to the new entry.
729 Function *F = OldEntry->getParent();
730 DominatorTree DT{*F};
732 auto *Alloca = dyn_cast<AllocaInst>(&I);
733 if (!Alloca || I.use_empty())
734 continue;
735 if (DT.isReachableFromEntry(I.getParent()) ||
736 !isa<ConstantInt>(Alloca->getArraySize()))
737 continue;
738 I.moveBefore(*Entry, Entry->getFirstInsertionPt());
739 }
740}
741
742/// Derive the value of the new frame pointer.
744 // Builder should be inserting to the front of the new entry block.
745
746 switch (Shape.ABI) {
747 // In switch-lowering, the argument is the frame pointer.
749 return &*NewF->arg_begin();
750 // In async-lowering, one of the arguments is an async context as determined
751 // by the `llvm.coro.id.async` intrinsic. We can retrieve the async context of
752 // the resume function from the async context projection function associated
753 // with the active suspend. The frame is located as a tail to the async
754 // context header.
755 case coro::ABI::Async: {
756 auto *ActiveAsyncSuspend = cast<CoroSuspendAsyncInst>(ActiveSuspend);
757 auto ContextIdx = ActiveAsyncSuspend->getStorageArgumentIndex() & 0xff;
758 auto *CalleeContext = NewF->getArg(ContextIdx);
759 auto *ProjectionFunc =
760 ActiveAsyncSuspend->getAsyncContextProjectionFunction();
761 auto DbgLoc =
763 // Calling i8* (i8*)
764 auto *CallerContext = Builder.CreateCall(ProjectionFunc->getFunctionType(),
765 ProjectionFunc, CalleeContext);
766 CallerContext->setCallingConv(ProjectionFunc->getCallingConv());
767 CallerContext->setDebugLoc(DbgLoc);
768 // The frame is located after the async_context header.
769 auto &Context = Builder.getContext();
770 auto *FramePtrAddr = Builder.CreateInBoundsPtrAdd(
771 CallerContext,
772 ConstantInt::get(Type::getInt64Ty(Context),
773 Shape.AsyncLowering.FrameOffset),
774 "async.ctx.frameptr");
775 // Inline the projection function.
777 auto InlineRes = InlineFunction(*CallerContext, InlineInfo);
778 assert(InlineRes.isSuccess());
779 (void)InlineRes;
780 return FramePtrAddr;
781 }
782 // In continuation-lowering, the argument is the opaque storage.
785 Argument *NewStorage = &*NewF->arg_begin();
786 auto FramePtrTy = PointerType::getUnqual(Shape.FramePtr->getContext());
787
788 // If the storage is inline, just bitcast to the storage to the frame type.
789 if (Shape.RetconLowering.IsFrameInlineInStorage)
790 return NewStorage;
791
792 // Otherwise, load the real frame from the opaque storage.
793 return Builder.CreateLoad(FramePtrTy, NewStorage);
794 }
795 }
796 llvm_unreachable("bad ABI");
797}
798
799/// Adjust the scope line of the funclet to the first line number after the
800/// suspend point. This avoids a jump in the line table from the function
801/// declaration (where prologue instructions are attributed to) to the suspend
802/// point.
803/// Only adjust the scope line when the files are the same.
804/// If no candidate line number is found, fallback to the line of ActiveSuspend.
805static void updateScopeLine(Instruction *ActiveSuspend,
806 DISubprogram &SPToUpdate) {
807 if (!ActiveSuspend)
808 return;
809
810 // No subsequent instruction -> fallback to the location of ActiveSuspend.
811 if (!ActiveSuspend->getNextNode()) {
812 if (auto DL = ActiveSuspend->getDebugLoc())
813 if (SPToUpdate.getFile() == DL->getFile())
814 SPToUpdate.setScopeLine(DL->getLine());
815 return;
816 }
817
819 // Corosplit splits the BB around ActiveSuspend, so the meaningful
820 // instructions are not in the same BB.
821 while (auto *Branch = dyn_cast_or_null<BranchInst>(Successor)) {
822 if (!Branch->isUnconditional())
823 break;
824 Successor = Branch->getSuccessor(0)->getFirstNonPHIOrDbg();
825 }
826
827 // Find the first successor of ActiveSuspend with a non-zero line location.
828 // If that matches the file of ActiveSuspend, use it.
829 BasicBlock *PBB = Successor->getParent();
830 for (; Successor != PBB->end(); Successor = std::next(Successor)) {
832 auto DL = Successor->getDebugLoc();
833 if (!DL || DL.getLine() == 0)
834 continue;
835
836 if (SPToUpdate.getFile() == DL->getFile()) {
837 SPToUpdate.setScopeLine(DL.getLine());
838 return;
839 }
840
841 break;
842 }
843
844 // If the search above failed, fallback to the location of ActiveSuspend.
845 if (auto DL = ActiveSuspend->getDebugLoc())
846 if (SPToUpdate.getFile() == DL->getFile())
847 SPToUpdate.setScopeLine(DL->getLine());
848}
849
850static void addFramePointerAttrs(AttributeList &Attrs, LLVMContext &Context,
851 unsigned ParamIndex, uint64_t Size,
852 Align Alignment, bool NoAlias) {
853 AttrBuilder ParamAttrs(Context);
854 ParamAttrs.addAttribute(Attribute::NonNull);
855 ParamAttrs.addAttribute(Attribute::NoUndef);
856
857 if (NoAlias)
858 ParamAttrs.addAttribute(Attribute::NoAlias);
859
860 ParamAttrs.addAlignmentAttr(Alignment);
861 ParamAttrs.addDereferenceableAttr(Size);
862 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs);
863}
864
865static void addAsyncContextAttrs(AttributeList &Attrs, LLVMContext &Context,
866 unsigned ParamIndex) {
867 AttrBuilder ParamAttrs(Context);
868 ParamAttrs.addAttribute(Attribute::SwiftAsync);
869 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs);
870}
871
872static void addSwiftSelfAttrs(AttributeList &Attrs, LLVMContext &Context,
873 unsigned ParamIndex) {
874 AttrBuilder ParamAttrs(Context);
875 ParamAttrs.addAttribute(Attribute::SwiftSelf);
876 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs);
877}
878
879/// Clone the body of the original function into a resume function of
880/// some sort.
882 assert(NewF);
883
884 // Replace all args with dummy instructions. If an argument is the old frame
885 // pointer, the dummy will be replaced by the new frame pointer once it is
886 // computed below. Uses of all other arguments should have already been
887 // rewritten by buildCoroutineFrame() to use loads/stores on the coroutine
888 // frame.
890 for (Argument &A : OrigF.args()) {
891 DummyArgs.push_back(new FreezeInst(PoisonValue::get(A.getType())));
892 VMap[&A] = DummyArgs.back();
893 }
894
896
897 // Ignore attempts to change certain attributes of the function.
898 // TODO: maybe there should be a way to suppress this during cloning?
899 auto savedVisibility = NewF->getVisibility();
900 auto savedUnnamedAddr = NewF->getUnnamedAddr();
901 auto savedDLLStorageClass = NewF->getDLLStorageClass();
902
903 // NewF's linkage (which CloneFunctionInto does *not* change) might not
904 // be compatible with the visibility of OrigF (which it *does* change),
905 // so protect against that.
906 auto savedLinkage = NewF->getLinkage();
908
911
912 auto &Context = NewF->getContext();
913
914 if (DISubprogram *SP = NewF->getSubprogram()) {
915 assert(SP != OrigF.getSubprogram() && SP->isDistinct());
917
918 // Update the linkage name and the function name to reflect the modified
919 // name.
920 MDString *NewLinkageName = MDString::get(Context, NewF->getName());
921 SP->replaceLinkageName(NewLinkageName);
922 if (DISubprogram *Decl = SP->getDeclaration()) {
923 TempDISubprogram NewDecl = Decl->clone();
924 NewDecl->replaceLinkageName(NewLinkageName);
925 SP->replaceDeclaration(MDNode::replaceWithUniqued(std::move(NewDecl)));
926 }
927 }
928
929 NewF->setLinkage(savedLinkage);
930 NewF->setVisibility(savedVisibility);
931 NewF->setUnnamedAddr(savedUnnamedAddr);
932 NewF->setDLLStorageClass(savedDLLStorageClass);
933 // The function sanitizer metadata needs to match the signature of the
934 // function it is being attached to. However this does not hold for split
935 // functions here. Thus remove the metadata for split functions.
936 if (Shape.ABI == coro::ABI::Switch &&
937 NewF->hasMetadata(LLVMContext::MD_func_sanitize))
938 NewF->eraseMetadata(LLVMContext::MD_func_sanitize);
939
940 // Replace the attributes of the new function:
941 auto OrigAttrs = NewF->getAttributes();
942 auto NewAttrs = AttributeList();
943
944 switch (Shape.ABI) {
946 // Bootstrap attributes by copying function attributes from the
947 // original function. This should include optimization settings and so on.
948 NewAttrs = NewAttrs.addFnAttributes(
949 Context, AttrBuilder(Context, OrigAttrs.getFnAttrs()));
950
951 addFramePointerAttrs(NewAttrs, Context, 0, Shape.FrameSize,
952 Shape.FrameAlign, /*NoAlias=*/false);
953 break;
954 case coro::ABI::Async: {
955 auto *ActiveAsyncSuspend = cast<CoroSuspendAsyncInst>(ActiveSuspend);
956 if (OrigF.hasParamAttribute(Shape.AsyncLowering.ContextArgNo,
957 Attribute::SwiftAsync)) {
958 uint32_t ArgAttributeIndices =
959 ActiveAsyncSuspend->getStorageArgumentIndex();
960 auto ContextArgIndex = ArgAttributeIndices & 0xff;
961 addAsyncContextAttrs(NewAttrs, Context, ContextArgIndex);
962
963 // `swiftasync` must preceed `swiftself` so 0 is not a valid index for
964 // `swiftself`.
965 auto SwiftSelfIndex = ArgAttributeIndices >> 8;
966 if (SwiftSelfIndex)
967 addSwiftSelfAttrs(NewAttrs, Context, SwiftSelfIndex);
968 }
969
970 // Transfer the original function's attributes.
971 auto FnAttrs = OrigF.getAttributes().getFnAttrs();
972 NewAttrs = NewAttrs.addFnAttributes(Context, AttrBuilder(Context, FnAttrs));
973 break;
974 }
977 // If we have a continuation prototype, just use its attributes,
978 // full-stop.
979 NewAttrs = Shape.RetconLowering.ResumePrototype->getAttributes();
980
981 /// FIXME: Is it really good to add the NoAlias attribute?
982 addFramePointerAttrs(NewAttrs, Context, 0,
983 Shape.getRetconCoroId()->getStorageSize(),
984 Shape.getRetconCoroId()->getStorageAlignment(),
985 /*NoAlias=*/true);
986
987 break;
988 }
989
990 switch (Shape.ABI) {
991 // In these ABIs, the cloned functions always return 'void', and the
992 // existing return sites are meaningless. Note that for unique
993 // continuations, this includes the returns associated with suspends;
994 // this is fine because we can't suspend twice.
997 // Remove old returns.
998 for (ReturnInst *Return : Returns)
999 changeToUnreachable(Return);
1000 break;
1001
1002 // With multi-suspend continuations, we'll already have eliminated the
1003 // original returns and inserted returns before all the suspend points,
1004 // so we want to leave any returns in place.
1005 case coro::ABI::Retcon:
1006 break;
1007 // Async lowering will insert musttail call functions at all suspend points
1008 // followed by a return.
1009 // Don't change returns to unreachable because that will trip up the verifier.
1010 // These returns should be unreachable from the clone.
1011 case coro::ABI::Async:
1012 break;
1013 }
1014
1015 NewF->setAttributes(NewAttrs);
1016 NewF->setCallingConv(Shape.getResumeFunctionCC());
1017
1018 // Set up the new entry block.
1020
1021 // Turn symmetric transfers into musttail calls.
1022 for (CallInst *ResumeCall : Shape.SymmetricTransfers) {
1023 ResumeCall = cast<CallInst>(VMap[ResumeCall]);
1024 if (TTI.supportsTailCallFor(ResumeCall)) {
1025 // FIXME: Could we support symmetric transfer effectively without
1026 // musttail?
1027 ResumeCall->setTailCallKind(CallInst::TCK_MustTail);
1028 }
1029
1030 // Put a 'ret void' after the call, and split any remaining instructions to
1031 // an unreachable block.
1032 BasicBlock *BB = ResumeCall->getParent();
1033 BB->splitBasicBlock(ResumeCall->getNextNode());
1034 Builder.SetInsertPoint(BB->getTerminator());
1035 Builder.CreateRetVoid();
1037 }
1038
1039 Builder.SetInsertPoint(&NewF->getEntryBlock().front());
1041
1042 // Remap frame pointer.
1043 Value *OldFramePtr = VMap[Shape.FramePtr];
1044 NewFramePtr->takeName(OldFramePtr);
1045 OldFramePtr->replaceAllUsesWith(NewFramePtr);
1046
1047 // Remap vFrame pointer.
1048 auto *NewVFrame = Builder.CreateBitCast(
1049 NewFramePtr, PointerType::getUnqual(Builder.getContext()), "vFrame");
1050 Value *OldVFrame = cast<Value>(VMap[Shape.CoroBegin]);
1051 if (OldVFrame != NewVFrame)
1052 OldVFrame->replaceAllUsesWith(NewVFrame);
1053
1054 // All uses of the arguments should have been resolved by this point,
1055 // so we can safely remove the dummy values.
1056 for (Instruction *DummyArg : DummyArgs) {
1057 DummyArg->replaceAllUsesWith(PoisonValue::get(DummyArg->getType()));
1058 DummyArg->deleteValue();
1059 }
1060
1061 switch (Shape.ABI) {
1062 case coro::ABI::Switch:
1063 // Rewrite final suspend handling as it is not done via switch (allows to
1064 // remove final case from the switch, since it is undefined behavior to
1065 // resume the coroutine suspended at the final suspend point.
1066 if (Shape.SwitchLowering.HasFinalSuspend)
1068 break;
1069 case coro::ABI::Async:
1070 case coro::ABI::Retcon:
1072 // Replace uses of the active suspend with the corresponding
1073 // continuation-function arguments.
1074 assert(ActiveSuspend != nullptr &&
1075 "no active suspend when lowering a continuation-style coroutine");
1077 break;
1078 }
1079
1080 // Handle suspends.
1082
1083 // Handle swifterror.
1085
1086 // Remove coro.end intrinsics.
1088
1090
1091 // Salvage debug info that points into the coroutine frame.
1093}
1094
1096 // Create a new function matching the original type
1097 NewF = createCloneDeclaration(OrigF, Shape, Suffix, OrigF.getParent()->end(),
1099
1100 // Clone the function
1102
1103 // Eliminate coro.free from the clones, replacing it with 'null' in cleanup,
1104 // to suppress deallocation code.
1105 coro::replaceCoroFree(cast<CoroIdInst>(VMap[Shape.CoroBegin->getId()]),
1107}
1108
1110 assert(Shape.ABI == coro::ABI::Async);
1111
1112 auto *FuncPtrStruct = cast<ConstantStruct>(
1114 auto *OrigRelativeFunOffset = FuncPtrStruct->getOperand(0);
1115 auto *OrigContextSize = FuncPtrStruct->getOperand(1);
1116 auto *NewContextSize = ConstantInt::get(OrigContextSize->getType(),
1118 auto *NewFuncPtrStruct = ConstantStruct::get(
1119 FuncPtrStruct->getType(), OrigRelativeFunOffset, NewContextSize);
1120
1121 Shape.AsyncLowering.AsyncFuncPointer->setInitializer(NewFuncPtrStruct);
1122}
1123
1125 if (Shape.ABI == coro::ABI::Async)
1127
1128 for (CoroAlignInst *CA : Shape.CoroAligns) {
1130 ConstantInt::get(CA->getType(), Shape.FrameAlign.value()));
1131 CA->eraseFromParent();
1132 }
1133
1134 if (Shape.CoroSizes.empty())
1135 return;
1136
1137 // In the same function all coro.sizes should have the same result type.
1138 auto *SizeIntrin = Shape.CoroSizes.back();
1139 auto *SizeConstant = ConstantInt::get(SizeIntrin->getType(),
1141
1142 for (CoroSizeInst *CS : Shape.CoroSizes) {
1143 CS->replaceAllUsesWith(SizeConstant);
1144 CS->eraseFromParent();
1145 }
1146}
1147
1150
1151#ifndef NDEBUG
1152 // For now, we do a mandatory verification step because we don't
1153 // entirely trust this pass. Note that we don't want to add a verifier
1154 // pass to FPM below because it will also verify all the global data.
1155 if (verifyFunction(F, &errs()))
1156 report_fatal_error("Broken function");
1157#endif
1158}
1159
1160// Coroutine has no suspend points. Remove heap allocation for the coroutine
1161// frame if possible.
1163 auto *CoroBegin = Shape.CoroBegin;
1164 switch (Shape.ABI) {
1165 case coro::ABI::Switch: {
1166 auto SwitchId = Shape.getSwitchCoroId();
1167 auto *AllocInst = SwitchId->getCoroAlloc();
1168 coro::replaceCoroFree(SwitchId, /*Elide=*/AllocInst != nullptr);
1169 if (AllocInst) {
1170 IRBuilder<> Builder(AllocInst);
1171 // Create an alloca for a byte array of the frame size
1172 auto *FrameTy = ArrayType::get(Type::getInt8Ty(Builder.getContext()),
1173 Shape.FrameSize);
1174 auto *Frame = Builder.CreateAlloca(
1175 FrameTy, nullptr, AllocInst->getFunction()->getName() + ".Frame");
1176 Frame->setAlignment(Shape.FrameAlign);
1177 AllocInst->replaceAllUsesWith(Builder.getFalse());
1178 AllocInst->eraseFromParent();
1179 CoroBegin->replaceAllUsesWith(Frame);
1180 } else {
1181 CoroBegin->replaceAllUsesWith(CoroBegin->getMem());
1182 }
1183
1184 break;
1185 }
1186 case coro::ABI::Async:
1187 case coro::ABI::Retcon:
1189 CoroBegin->replaceAllUsesWith(PoisonValue::get(CoroBegin->getType()));
1190 break;
1191 }
1192
1193 CoroBegin->eraseFromParent();
1194 Shape.CoroBegin = nullptr;
1195}
1196
1197// SimplifySuspendPoint needs to check that there is no calls between
1198// coro_save and coro_suspend, since any of the calls may potentially resume
1199// the coroutine and if that is the case we cannot eliminate the suspend point.
1201 for (Instruction &I : R) {
1202 // Assume that no intrinsic can resume the coroutine.
1203 if (isa<IntrinsicInst>(I))
1204 continue;
1205
1206 if (isa<CallBase>(I))
1207 return true;
1208 }
1209 return false;
1210}
1211
1212static bool hasCallsInBlocksBetween(BasicBlock *SaveBB, BasicBlock *ResDesBB) {
1215
1216 Set.insert(SaveBB);
1217 Worklist.push_back(ResDesBB);
1218
1219 // Accumulate all blocks between SaveBB and ResDesBB. Because CoroSaveIntr
1220 // returns a token consumed by suspend instruction, all blocks in between
1221 // will have to eventually hit SaveBB when going backwards from ResDesBB.
1222 while (!Worklist.empty()) {
1223 auto *BB = Worklist.pop_back_val();
1224 Set.insert(BB);
1225 for (auto *Pred : predecessors(BB))
1226 if (!Set.contains(Pred))
1227 Worklist.push_back(Pred);
1228 }
1229
1230 // SaveBB and ResDesBB are checked separately in hasCallsBetween.
1231 Set.erase(SaveBB);
1232 Set.erase(ResDesBB);
1233
1234 for (auto *BB : Set)
1235 if (hasCallsInBlockBetween({BB->getFirstNonPHIIt(), BB->end()}))
1236 return true;
1237
1238 return false;
1239}
1240
1241static bool hasCallsBetween(Instruction *Save, Instruction *ResumeOrDestroy) {
1242 auto *SaveBB = Save->getParent();
1243 auto *ResumeOrDestroyBB = ResumeOrDestroy->getParent();
1244 BasicBlock::iterator SaveIt = Save->getIterator();
1245 BasicBlock::iterator ResumeOrDestroyIt = ResumeOrDestroy->getIterator();
1246
1247 if (SaveBB == ResumeOrDestroyBB)
1248 return hasCallsInBlockBetween({std::next(SaveIt), ResumeOrDestroyIt});
1249
1250 // Any calls from Save to the end of the block?
1251 if (hasCallsInBlockBetween({std::next(SaveIt), SaveBB->end()}))
1252 return true;
1253
1254 // Any calls from begging of the block up to ResumeOrDestroy?
1256 {ResumeOrDestroyBB->getFirstNonPHIIt(), ResumeOrDestroyIt}))
1257 return true;
1258
1259 // Any calls in all of the blocks between SaveBB and ResumeOrDestroyBB?
1260 if (hasCallsInBlocksBetween(SaveBB, ResumeOrDestroyBB))
1261 return true;
1262
1263 return false;
1264}
1265
1266// If a SuspendIntrin is preceded by Resume or Destroy, we can eliminate the
1267// suspend point and replace it with nornal control flow.
1269 CoroBeginInst *CoroBegin) {
1270 Instruction *Prev = Suspend->getPrevNode();
1271 if (!Prev) {
1272 auto *Pred = Suspend->getParent()->getSinglePredecessor();
1273 if (!Pred)
1274 return false;
1275 Prev = Pred->getTerminator();
1276 }
1277
1278 CallBase *CB = dyn_cast<CallBase>(Prev);
1279 if (!CB)
1280 return false;
1281
1282 auto *Callee = CB->getCalledOperand()->stripPointerCasts();
1283
1284 // See if the callsite is for resumption or destruction of the coroutine.
1285 auto *SubFn = dyn_cast<CoroSubFnInst>(Callee);
1286 if (!SubFn)
1287 return false;
1288
1289 // Does not refer to the current coroutine, we cannot do anything with it.
1290 if (SubFn->getFrame() != CoroBegin)
1291 return false;
1292
1293 // See if the transformation is safe. Specifically, see if there are any
1294 // calls in between Save and CallInstr. They can potenitally resume the
1295 // coroutine rendering this optimization unsafe.
1296 auto *Save = Suspend->getCoroSave();
1297 if (hasCallsBetween(Save, CB))
1298 return false;
1299
1300 // Replace llvm.coro.suspend with the value that results in resumption over
1301 // the resume or cleanup path.
1302 Suspend->replaceAllUsesWith(SubFn->getRawIndex());
1303 Suspend->eraseFromParent();
1304 Save->eraseFromParent();
1305
1306 // No longer need a call to coro.resume or coro.destroy.
1307 if (auto *Invoke = dyn_cast<InvokeInst>(CB)) {
1308 BranchInst::Create(Invoke->getNormalDest(), Invoke->getIterator());
1309 }
1310
1311 // Grab the CalledValue from CB before erasing the CallInstr.
1312 auto *CalledValue = CB->getCalledOperand();
1313 CB->eraseFromParent();
1314
1315 // If no more users remove it. Usually it is a bitcast of SubFn.
1316 if (CalledValue != SubFn && CalledValue->user_empty())
1317 if (auto *I = dyn_cast<Instruction>(CalledValue))
1318 I->eraseFromParent();
1319
1320 // Now we are good to remove SubFn.
1321 if (SubFn->user_empty())
1322 SubFn->eraseFromParent();
1323
1324 return true;
1325}
1326
1327// Remove suspend points that are simplified.
1329 // Currently, the only simplification we do is switch-lowering-specific.
1330 if (Shape.ABI != coro::ABI::Switch)
1331 return;
1332
1333 auto &S = Shape.CoroSuspends;
1334 size_t I = 0, N = S.size();
1335 if (N == 0)
1336 return;
1337
1338 size_t ChangedFinalIndex = std::numeric_limits<size_t>::max();
1339 while (true) {
1340 auto SI = cast<CoroSuspendInst>(S[I]);
1341 // Leave final.suspend to handleFinalSuspend since it is undefined behavior
1342 // to resume a coroutine suspended at the final suspend point.
1343 if (!SI->isFinal() && simplifySuspendPoint(SI, Shape.CoroBegin)) {
1344 if (--N == I)
1345 break;
1346
1347 std::swap(S[I], S[N]);
1348
1349 if (cast<CoroSuspendInst>(S[I])->isFinal()) {
1351 ChangedFinalIndex = I;
1352 }
1353
1354 continue;
1355 }
1356 if (++I == N)
1357 break;
1358 }
1359 S.resize(N);
1360
1361 // Maintain final.suspend in case final suspend was swapped.
1362 // Due to we requrie the final suspend to be the last element of CoroSuspends.
1363 if (ChangedFinalIndex < N) {
1364 assert(cast<CoroSuspendInst>(S[ChangedFinalIndex])->isFinal());
1365 std::swap(S[ChangedFinalIndex], S.back());
1366 }
1367}
1368
1369namespace {
1370
1371struct SwitchCoroutineSplitter {
1372 static void split(Function &F, coro::Shape &Shape,
1373 SmallVectorImpl<Function *> &Clones,
1374 TargetTransformInfo &TTI) {
1375 assert(Shape.ABI == coro::ABI::Switch);
1376
1377 // Create a resume clone by cloning the body of the original function,
1378 // setting new entry block and replacing coro.suspend an appropriate value
1379 // to force resume or cleanup pass for every suspend point.
1380 createResumeEntryBlock(F, Shape);
1381 auto *ResumeClone = coro::SwitchCloner::createClone(
1382 F, ".resume", Shape, coro::CloneKind::SwitchResume, TTI);
1383 auto *DestroyClone = coro::SwitchCloner::createClone(
1384 F, ".destroy", Shape, coro::CloneKind::SwitchUnwind, TTI);
1385 auto *CleanupClone = coro::SwitchCloner::createClone(
1386 F, ".cleanup", Shape, coro::CloneKind::SwitchCleanup, TTI);
1387
1388 postSplitCleanup(*ResumeClone);
1389 postSplitCleanup(*DestroyClone);
1390 postSplitCleanup(*CleanupClone);
1391
1392 // Store addresses resume/destroy/cleanup functions in the coroutine frame.
1393 updateCoroFrame(Shape, ResumeClone, DestroyClone, CleanupClone);
1394
1395 assert(Clones.empty());
1396 Clones.push_back(ResumeClone);
1397 Clones.push_back(DestroyClone);
1398 Clones.push_back(CleanupClone);
1399
1400 // Create a constant array referring to resume/destroy/clone functions
1401 // pointed by the last argument of @llvm.coro.info, so that CoroElide pass
1402 // can determined correct function to call.
1403 setCoroInfo(F, Shape, Clones);
1404 }
1405
1406 // Create a variant of ramp function that does not perform heap allocation
1407 // for a switch ABI coroutine.
1408 //
1409 // The newly split `.noalloc` ramp function has the following differences:
1410 // - Has one additional frame pointer parameter in lieu of dynamic
1411 // allocation.
1412 // - Suppressed allocations by replacing coro.alloc and coro.free.
1413 static Function *createNoAllocVariant(Function &F, coro::Shape &Shape,
1414 SmallVectorImpl<Function *> &Clones) {
1415 assert(Shape.ABI == coro::ABI::Switch);
1416 auto *OrigFnTy = F.getFunctionType();
1417 auto OldParams = OrigFnTy->params();
1418
1419 SmallVector<Type *> NewParams;
1420 NewParams.reserve(OldParams.size() + 1);
1421 NewParams.append(OldParams.begin(), OldParams.end());
1422 NewParams.push_back(PointerType::getUnqual(Shape.FramePtr->getContext()));
1423
1424 auto *NewFnTy = FunctionType::get(OrigFnTy->getReturnType(), NewParams,
1425 OrigFnTy->isVarArg());
1426 Function *NoAllocF =
1427 Function::Create(NewFnTy, F.getLinkage(), F.getName() + ".noalloc");
1428
1429 ValueToValueMapTy VMap;
1430 unsigned int Idx = 0;
1431 for (const auto &I : F.args()) {
1432 VMap[&I] = NoAllocF->getArg(Idx++);
1433 }
1434 // We just appended the frame pointer as the last argument of the new
1435 // function.
1436 auto FrameIdx = NoAllocF->arg_size() - 1;
1438 CloneFunctionInto(NoAllocF, &F, VMap,
1439 CloneFunctionChangeType::LocalChangesOnly, Returns);
1440
1441 if (Shape.CoroBegin) {
1442 auto *NewCoroBegin =
1444 auto *NewCoroId = cast<CoroIdInst>(NewCoroBegin->getId());
1445 coro::replaceCoroFree(NewCoroId, /*Elide=*/true);
1446 coro::suppressCoroAllocs(NewCoroId);
1447 NewCoroBegin->replaceAllUsesWith(NoAllocF->getArg(FrameIdx));
1448 NewCoroBegin->eraseFromParent();
1449 }
1450
1451 Module *M = F.getParent();
1452 M->getFunctionList().insert(M->end(), NoAllocF);
1453
1454 removeUnreachableBlocks(*NoAllocF);
1455 auto NewAttrs = NoAllocF->getAttributes();
1456 // When we elide allocation, we read these attributes to determine the
1457 // frame size and alignment.
1458 addFramePointerAttrs(NewAttrs, NoAllocF->getContext(), FrameIdx,
1459 Shape.FrameSize, Shape.FrameAlign,
1460 /*NoAlias=*/false);
1461
1462 NoAllocF->setAttributes(NewAttrs);
1463
1464 Clones.push_back(NoAllocF);
1465 // Reset the original function's coro info, make the new noalloc variant
1466 // connected to the original ramp function.
1467 setCoroInfo(F, Shape, Clones);
1468 // After copying, set the linkage to internal linkage. Original function
1469 // may have different linkage, but optimization dependent on this function
1470 // generally relies on LTO.
1472 return NoAllocF;
1473 }
1474
1475private:
1476 // Create an entry block for a resume function with a switch that will jump to
1477 // suspend points.
1478 static void createResumeEntryBlock(Function &F, coro::Shape &Shape) {
1479 LLVMContext &C = F.getContext();
1480
1481 DIBuilder DBuilder(*F.getParent(), /*AllowUnresolved*/ false);
1482 DISubprogram *DIS = F.getSubprogram();
1483 // If there is no DISubprogram for F, it implies the function is compiled
1484 // without debug info. So we also don't generate debug info for the
1485 // suspension points.
1486 bool AddDebugLabels = DIS && DIS->getUnit() &&
1487 (DIS->getUnit()->getEmissionKind() ==
1488 DICompileUnit::DebugEmissionKind::FullDebug);
1489
1490 // resume.entry:
1491 // %index.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32
1492 // 0, i32 2 % index = load i32, i32* %index.addr switch i32 %index, label
1493 // %unreachable [
1494 // i32 0, label %resume.0
1495 // i32 1, label %resume.1
1496 // ...
1497 // ]
1498
1499 auto *NewEntry = BasicBlock::Create(C, "resume.entry", &F);
1500 auto *UnreachBB = BasicBlock::Create(C, "unreachable", &F);
1501
1502 IRBuilder<> Builder(NewEntry);
1503 auto *FramePtr = Shape.FramePtr;
1504 Value *GepIndex = createSwitchIndexPtr(Shape, Builder, FramePtr);
1505 auto *Index = Builder.CreateLoad(Shape.getIndexType(), GepIndex, "index");
1506 auto *Switch =
1507 Builder.CreateSwitch(Index, UnreachBB, Shape.CoroSuspends.size());
1509
1510 // Split all coro.suspend calls
1511 size_t SuspendIndex = 0;
1512 for (auto *AnyS : Shape.CoroSuspends) {
1513 auto *S = cast<CoroSuspendInst>(AnyS);
1514 ConstantInt *IndexVal = Shape.getIndex(SuspendIndex);
1515
1516 // Replace CoroSave with a store to Index:
1517 // %index.addr = getelementptr %f.frame... (index field number)
1518 // store i32 %IndexVal, i32* %index.addr1
1519 auto *Save = S->getCoroSave();
1520 Builder.SetInsertPoint(Save);
1521 if (S->isFinal()) {
1522 // The coroutine should be marked done if it reaches the final suspend
1523 // point.
1524 markCoroutineAsDone(Builder, Shape, FramePtr);
1525 } else {
1526 Value *GepIndex = createSwitchIndexPtr(Shape, Builder, FramePtr);
1527 Builder.CreateStore(IndexVal, GepIndex);
1528 }
1529
1531 Save->eraseFromParent();
1532
1533 // Split block before and after coro.suspend and add a jump from an entry
1534 // switch:
1535 //
1536 // whateverBB:
1537 // whatever
1538 // %0 = call i8 @llvm.coro.suspend(token none, i1 false)
1539 // switch i8 %0, label %suspend[i8 0, label %resume
1540 // i8 1, label %cleanup]
1541 // becomes:
1542 //
1543 // whateverBB:
1544 // whatever
1545 // br label %resume.0.landing
1546 //
1547 // resume.0: ; <--- jump from the switch in the resume.entry
1548 // #dbg_label(...) ; <--- artificial label for debuggers
1549 // %0 = tail call i8 @llvm.coro.suspend(token none, i1 false)
1550 // br label %resume.0.landing
1551 //
1552 // resume.0.landing:
1553 // %1 = phi i8[-1, %whateverBB], [%0, %resume.0]
1554 // switch i8 % 1, label %suspend [i8 0, label %resume
1555 // i8 1, label %cleanup]
1556
1557 auto *SuspendBB = S->getParent();
1558 auto *ResumeBB =
1559 SuspendBB->splitBasicBlock(S, "resume." + Twine(SuspendIndex));
1560 auto *LandingBB = ResumeBB->splitBasicBlock(
1561 S->getNextNode(), ResumeBB->getName() + Twine(".landing"));
1562 Switch->addCase(IndexVal, ResumeBB);
1563
1564 cast<BranchInst>(SuspendBB->getTerminator())->setSuccessor(0, LandingBB);
1565 auto *PN = PHINode::Create(Builder.getInt8Ty(), 2, "");
1566 PN->insertBefore(LandingBB->begin());
1567 S->replaceAllUsesWith(PN);
1568 PN->addIncoming(Builder.getInt8(-1), SuspendBB);
1569 PN->addIncoming(S, ResumeBB);
1570
1571 if (AddDebugLabels) {
1572 if (DebugLoc SuspendLoc = S->getDebugLoc()) {
1573 std::string LabelName =
1574 ("__coro_resume_" + Twine(SuspendIndex)).str();
1575 // Take the "inlined at" location recursively, if present. This is
1576 // mandatory as the DILabel insertion checks that the scopes of label
1577 // and the attached location match. This is not the case when the
1578 // suspend location has been inlined due to pointing to the original
1579 // scope.
1580 DILocation *DILoc = SuspendLoc;
1581 while (DILocation *InlinedAt = DILoc->getInlinedAt())
1582 DILoc = InlinedAt;
1583
1584 DILabel *ResumeLabel =
1585 DBuilder.createLabel(DIS, LabelName, DILoc->getFile(),
1586 SuspendLoc.getLine(), SuspendLoc.getCol(),
1587 /*IsArtificial=*/true,
1588 /*CoroSuspendIdx=*/SuspendIndex,
1589 /*AlwaysPreserve=*/false);
1590 DBuilder.insertLabel(ResumeLabel, DILoc, ResumeBB->begin());
1591 }
1592 }
1593
1594 ++SuspendIndex;
1595 }
1596
1597 Builder.SetInsertPoint(UnreachBB);
1598 Builder.CreateUnreachable();
1599 DBuilder.finalize();
1600
1601 Shape.SwitchLowering.ResumeEntryBlock = NewEntry;
1602 }
1603
1604 // Store addresses of Resume/Destroy/Cleanup functions in the coroutine frame.
1605 static void updateCoroFrame(coro::Shape &Shape, Function *ResumeFn,
1606 Function *DestroyFn, Function *CleanupFn) {
1607 IRBuilder<> Builder(&*Shape.getInsertPtAfterFramePtr());
1608 LLVMContext &C = ResumeFn->getContext();
1609
1610 // Resume function pointer
1611 Value *ResumeAddr = Shape.FramePtr;
1612 Builder.CreateStore(ResumeFn, ResumeAddr);
1613
1614 Value *DestroyOrCleanupFn = DestroyFn;
1615
1616 CoroIdInst *CoroId = Shape.getSwitchCoroId();
1617 if (CoroAllocInst *CA = CoroId->getCoroAlloc()) {
1618 // If there is a CoroAlloc and it returns false (meaning we elide the
1619 // allocation, use CleanupFn instead of DestroyFn).
1620 DestroyOrCleanupFn = Builder.CreateSelect(CA, DestroyFn, CleanupFn);
1621 }
1622
1623 // Destroy function pointer
1624 Value *DestroyAddr = Builder.CreateInBoundsPtrAdd(
1625 Shape.FramePtr,
1626 ConstantInt::get(Type::getInt64Ty(C),
1628 "destroy.addr");
1629 Builder.CreateStore(DestroyOrCleanupFn, DestroyAddr);
1630 }
1631
1632 // Create a global constant array containing pointers to functions provided
1633 // and set Info parameter of CoroBegin to point at this constant. Example:
1634 //
1635 // @f.resumers = internal constant [2 x void(%f.frame*)*]
1636 // [void(%f.frame*)* @f.resume, void(%f.frame*)*
1637 // @f.destroy]
1638 // define void @f() {
1639 // ...
1640 // call i8* @llvm.coro.begin(i8* null, i32 0, i8* null,
1641 // i8* bitcast([2 x void(%f.frame*)*] * @f.resumers to
1642 // i8*))
1643 //
1644 // Assumes that all the functions have the same signature.
1645 static void setCoroInfo(Function &F, coro::Shape &Shape,
1647 // This only works under the switch-lowering ABI because coro elision
1648 // only works on the switch-lowering ABI.
1649 SmallVector<Constant *, 4> Args(Fns);
1650 assert(!Args.empty());
1651 Function *Part = *Fns.begin();
1652 Module *M = Part->getParent();
1653 auto *ArrTy = ArrayType::get(Part->getType(), Args.size());
1654
1655 auto *ConstVal = ConstantArray::get(ArrTy, Args);
1656 auto *GV = new GlobalVariable(*M, ConstVal->getType(), /*isConstant=*/true,
1657 GlobalVariable::PrivateLinkage, ConstVal,
1658 F.getName() + Twine(".resumers"));
1659
1660 // Update coro.begin instruction to refer to this constant.
1661 LLVMContext &C = F.getContext();
1662 auto *BC = ConstantExpr::getPointerCast(GV, PointerType::getUnqual(C));
1663 Shape.getSwitchCoroId()->setInfo(BC);
1664 }
1665};
1666
1667} // namespace
1668
1671 auto *ResumeIntrinsic = Suspend->getResumeFunction();
1672 auto &Context = Suspend->getParent()->getParent()->getContext();
1673 auto *Int8PtrTy = PointerType::getUnqual(Context);
1674
1675 IRBuilder<> Builder(ResumeIntrinsic);
1676 auto *Val = Builder.CreateBitOrPointerCast(Continuation, Int8PtrTy);
1677 ResumeIntrinsic->replaceAllUsesWith(Val);
1678 ResumeIntrinsic->eraseFromParent();
1680 PoisonValue::get(Int8PtrTy));
1681}
1682
1683/// Coerce the arguments in \p FnArgs according to \p FnTy in \p CallArgs.
1684static void coerceArguments(IRBuilder<> &Builder, FunctionType *FnTy,
1685 ArrayRef<Value *> FnArgs,
1686 SmallVectorImpl<Value *> &CallArgs) {
1687 size_t ArgIdx = 0;
1688 for (auto *paramTy : FnTy->params()) {
1689 assert(ArgIdx < FnArgs.size());
1690 if (paramTy != FnArgs[ArgIdx]->getType())
1691 CallArgs.push_back(
1692 Builder.CreateBitOrPointerCast(FnArgs[ArgIdx], paramTy));
1693 else
1694 CallArgs.push_back(FnArgs[ArgIdx]);
1695 ++ArgIdx;
1696 }
1697}
1698
1702 IRBuilder<> &Builder) {
1703 auto *FnTy = MustTailCallFn->getFunctionType();
1704 // Coerce the arguments, llvm optimizations seem to ignore the types in
1705 // vaarg functions and throws away casts in optimized mode.
1706 SmallVector<Value *, 8> CallArgs;
1707 coerceArguments(Builder, FnTy, Arguments, CallArgs);
1708
1709 auto *TailCall = Builder.CreateCall(FnTy, MustTailCallFn, CallArgs);
1710 // Skip targets which don't support tail call.
1711 if (TTI.supportsTailCallFor(TailCall)) {
1712 TailCall->setTailCallKind(CallInst::TCK_MustTail);
1713 }
1714 TailCall->setDebugLoc(Loc);
1715 TailCall->setCallingConv(MustTailCallFn->getCallingConv());
1716 return TailCall;
1717}
1718
1723 assert(Clones.empty());
1724 // Reset various things that the optimizer might have decided it
1725 // "knows" about the coroutine function due to not seeing a return.
1726 F.removeFnAttr(Attribute::NoReturn);
1727 F.removeRetAttr(Attribute::NoAlias);
1728 F.removeRetAttr(Attribute::NonNull);
1729
1730 auto &Context = F.getContext();
1731 auto *Int8PtrTy = PointerType::getUnqual(Context);
1732
1733 auto *Id = Shape.getAsyncCoroId();
1734 IRBuilder<> Builder(Id);
1735
1736 auto *FramePtr = Id->getStorage();
1737 FramePtr = Builder.CreateBitOrPointerCast(FramePtr, Int8PtrTy);
1738 FramePtr = Builder.CreateInBoundsPtrAdd(
1739 FramePtr,
1740 ConstantInt::get(Type::getInt64Ty(Context),
1741 Shape.AsyncLowering.FrameOffset),
1742 "async.ctx.frameptr");
1743
1744 // Map all uses of llvm.coro.begin to the allocated frame pointer.
1745 {
1746 // Make sure we don't invalidate Shape.FramePtr.
1747 TrackingVH<Value> Handle(Shape.FramePtr);
1748 Shape.CoroBegin->replaceAllUsesWith(FramePtr);
1749 Shape.FramePtr = Handle.getValPtr();
1750 }
1751
1752 // Create all the functions in order after the main function.
1753 auto NextF = std::next(F.getIterator());
1754
1755 // Create a continuation function for each of the suspend points.
1756 Clones.reserve(Shape.CoroSuspends.size());
1757 for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
1758 auto *Suspend = cast<CoroSuspendAsyncInst>(CS);
1759
1760 // Create the clone declaration.
1761 auto ResumeNameSuffix = ".resume.";
1762 auto ProjectionFunctionName =
1763 Suspend->getAsyncContextProjectionFunction()->getName();
1764 bool UseSwiftMangling = false;
1765 if (ProjectionFunctionName == "__swift_async_resume_project_context") {
1766 ResumeNameSuffix = "TQ";
1767 UseSwiftMangling = true;
1768 } else if (ProjectionFunctionName == "__swift_async_resume_get_context") {
1769 ResumeNameSuffix = "TY";
1770 UseSwiftMangling = true;
1771 }
1773 F, Shape,
1774 UseSwiftMangling ? ResumeNameSuffix + Twine(Idx) + "_"
1775 : ResumeNameSuffix + Twine(Idx),
1776 NextF, Suspend);
1777 Clones.push_back(Continuation);
1778
1779 // Insert a branch to a new return block immediately before the suspend
1780 // point.
1781 auto *SuspendBB = Suspend->getParent();
1782 auto *NewSuspendBB = SuspendBB->splitBasicBlock(Suspend);
1783 auto *Branch = cast<BranchInst>(SuspendBB->getTerminator());
1784
1785 // Place it before the first suspend.
1786 auto *ReturnBB =
1787 BasicBlock::Create(F.getContext(), "coro.return", &F, NewSuspendBB);
1788 Branch->setSuccessor(0, ReturnBB);
1789
1790 IRBuilder<> Builder(ReturnBB);
1791
1792 // Insert the call to the tail call function and inline it.
1793 auto *Fn = Suspend->getMustTailCallFunction();
1794 SmallVector<Value *, 8> Args(Suspend->args());
1795 auto FnArgs = ArrayRef<Value *>(Args).drop_front(
1797 auto *TailCall = coro::createMustTailCall(Suspend->getDebugLoc(), Fn, TTI,
1798 FnArgs, Builder);
1799 Builder.CreateRetVoid();
1800 InlineFunctionInfo FnInfo;
1801 (void)InlineFunction(*TailCall, FnInfo);
1802
1803 // Replace the lvm.coro.async.resume intrisic call.
1805 }
1806
1807 assert(Clones.size() == Shape.CoroSuspends.size());
1808
1809 for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
1810 auto *Suspend = CS;
1811 auto *Clone = Clones[Idx];
1812
1813 coro::BaseCloner::createClone(F, "resume." + Twine(Idx), Shape, Clone,
1814 Suspend, TTI);
1815 }
1816}
1817
1822 assert(Clones.empty());
1823
1824 // Reset various things that the optimizer might have decided it
1825 // "knows" about the coroutine function due to not seeing a return.
1826 F.removeFnAttr(Attribute::NoReturn);
1827 F.removeRetAttr(Attribute::NoAlias);
1828 F.removeRetAttr(Attribute::NonNull);
1829
1830 // Allocate the frame.
1831 auto *Id = Shape.getRetconCoroId();
1832 Value *RawFramePtr;
1833 if (Shape.RetconLowering.IsFrameInlineInStorage) {
1834 RawFramePtr = Id->getStorage();
1835 } else {
1836 IRBuilder<> Builder(Id);
1837
1838 auto FrameSize = Builder.getInt64(Shape.FrameSize);
1839
1840 // Allocate. We don't need to update the call graph node because we're
1841 // going to recompute it from scratch after splitting.
1842 // FIXME: pass the required alignment
1843 RawFramePtr = Shape.emitAlloc(Builder, FrameSize, nullptr);
1844 RawFramePtr =
1845 Builder.CreateBitCast(RawFramePtr, Shape.CoroBegin->getType());
1846
1847 // Stash the allocated frame pointer in the continuation storage.
1848 Builder.CreateStore(RawFramePtr, Id->getStorage());
1849 }
1850
1851 // Map all uses of llvm.coro.begin to the allocated frame pointer.
1852 {
1853 // Make sure we don't invalidate Shape.FramePtr.
1854 TrackingVH<Value> Handle(Shape.FramePtr);
1855 Shape.CoroBegin->replaceAllUsesWith(RawFramePtr);
1856 Shape.FramePtr = Handle.getValPtr();
1857 }
1858
1859 // Create a unique return block.
1860 BasicBlock *ReturnBB = nullptr;
1861 PHINode *ContinuationPhi = nullptr;
1862 SmallVector<PHINode *, 4> ReturnPHIs;
1863
1864 // Create all the functions in order after the main function.
1865 auto NextF = std::next(F.getIterator());
1866
1867 // Create a continuation function for each of the suspend points.
1868 Clones.reserve(Shape.CoroSuspends.size());
1869 for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
1870 auto Suspend = cast<CoroSuspendRetconInst>(CS);
1871
1872 // Create the clone declaration.
1874 F, Shape, ".resume." + Twine(Idx), NextF, nullptr);
1875 Clones.push_back(Continuation);
1876
1877 // Insert a branch to the unified return block immediately before
1878 // the suspend point.
1879 auto SuspendBB = Suspend->getParent();
1880 auto NewSuspendBB = SuspendBB->splitBasicBlock(Suspend);
1881 auto Branch = cast<BranchInst>(SuspendBB->getTerminator());
1882
1883 // Create the unified return block.
1884 if (!ReturnBB) {
1885 // Place it before the first suspend.
1886 ReturnBB =
1887 BasicBlock::Create(F.getContext(), "coro.return", &F, NewSuspendBB);
1888 Shape.RetconLowering.ReturnBlock = ReturnBB;
1889
1890 IRBuilder<> Builder(ReturnBB);
1891
1892 // First, the continuation.
1893 ContinuationPhi =
1894 Builder.CreatePHI(Continuation->getType(), Shape.CoroSuspends.size());
1895
1896 // Create PHIs for all other return values.
1897 assert(ReturnPHIs.empty());
1898
1899 // Next, all the directly-yielded values.
1900 for (auto *ResultTy : Shape.getRetconResultTypes())
1901 ReturnPHIs.push_back(
1902 Builder.CreatePHI(ResultTy, Shape.CoroSuspends.size()));
1903
1904 // Build the return value.
1905 auto RetTy = F.getReturnType();
1906
1907 // Cast the continuation value if necessary.
1908 // We can't rely on the types matching up because that type would
1909 // have to be infinite.
1910 auto CastedContinuationTy =
1911 (ReturnPHIs.empty() ? RetTy : RetTy->getStructElementType(0));
1912 auto *CastedContinuation =
1913 Builder.CreateBitCast(ContinuationPhi, CastedContinuationTy);
1914
1915 Value *RetV = CastedContinuation;
1916 if (!ReturnPHIs.empty()) {
1917 auto ValueIdx = 0;
1918 RetV = PoisonValue::get(RetTy);
1919 RetV = Builder.CreateInsertValue(RetV, CastedContinuation, ValueIdx++);
1920
1921 for (auto Phi : ReturnPHIs)
1922 RetV = Builder.CreateInsertValue(RetV, Phi, ValueIdx++);
1923 }
1924
1925 Builder.CreateRet(RetV);
1926 }
1927
1928 // Branch to the return block.
1929 Branch->setSuccessor(0, ReturnBB);
1930 assert(ContinuationPhi);
1931 ContinuationPhi->addIncoming(Continuation, SuspendBB);
1932 for (auto [Phi, VUse] :
1933 llvm::zip_equal(ReturnPHIs, Suspend->value_operands()))
1934 Phi->addIncoming(VUse, SuspendBB);
1935 }
1936
1937 assert(Clones.size() == Shape.CoroSuspends.size());
1938
1939 for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
1940 auto Suspend = CS;
1941 auto Clone = Clones[Idx];
1942
1943 coro::BaseCloner::createClone(F, "resume." + Twine(Idx), Shape, Clone,
1944 Suspend, TTI);
1945 }
1946}
1947
1948namespace {
1949class PrettyStackTraceFunction : public PrettyStackTraceEntry {
1950 Function &F;
1951
1952public:
1953 PrettyStackTraceFunction(Function &F) : F(F) {}
1954 void print(raw_ostream &OS) const override {
1955 OS << "While splitting coroutine ";
1956 F.printAsOperand(OS, /*print type*/ false, F.getParent());
1957 OS << "\n";
1958 }
1959};
1960} // namespace
1961
1962/// Remove calls to llvm.coro.end in the original function.
1964 if (Shape.ABI != coro::ABI::Switch) {
1965 for (auto *End : Shape.CoroEnds) {
1966 replaceCoroEnd(End, Shape, Shape.FramePtr, /*in ramp*/ true, nullptr);
1967 }
1968 } else {
1969 for (llvm::AnyCoroEndInst *End : Shape.CoroEnds)
1970 End->eraseFromParent();
1971 }
1972}
1973
1975 for (auto *II : Shape.CoroIsInRampInsts) {
1976 auto &Ctx = II->getContext();
1977 II->replaceAllUsesWith(ConstantInt::getTrue(Ctx));
1978 II->eraseFromParent();
1979 }
1980}
1981
1983 for (auto *U : F.users()) {
1984 if (auto *CB = dyn_cast<CallBase>(U)) {
1985 auto *Caller = CB->getFunction();
1986 if (Caller && Caller->isPresplitCoroutine() &&
1987 CB->hasFnAttr(llvm::Attribute::CoroElideSafe))
1988 return true;
1989 }
1990 }
1991 return false;
1992}
1993
1997 SwitchCoroutineSplitter::split(F, Shape, Clones, TTI);
1998}
1999
2002 bool OptimizeFrame) {
2003 PrettyStackTraceFunction prettyStackTrace(F);
2004
2005 auto &Shape = ABI.Shape;
2006 assert(Shape.CoroBegin);
2007
2008 lowerAwaitSuspends(F, Shape);
2009
2010 simplifySuspendPoints(Shape);
2011
2012 normalizeCoroutine(F, Shape, TTI);
2013 ABI.buildCoroutineFrame(OptimizeFrame);
2015
2016 bool isNoSuspendCoroutine = Shape.CoroSuspends.empty();
2017
2018 bool shouldCreateNoAllocVariant =
2019 !isNoSuspendCoroutine && Shape.ABI == coro::ABI::Switch &&
2020 hasSafeElideCaller(F) && !F.hasFnAttribute(llvm::Attribute::NoInline);
2021
2022 // If there are no suspend points, no split required, just remove
2023 // the allocation and deallocation blocks, they are not needed.
2024 if (isNoSuspendCoroutine) {
2026 } else {
2027 ABI.splitCoroutine(F, Shape, Clones, TTI);
2028 }
2029
2030 // Replace all the swifterror operations in the original function.
2031 // This invalidates SwiftErrorOps in the Shape.
2032 replaceSwiftErrorOps(F, Shape, nullptr);
2033
2034 // Salvage debug intrinsics that point into the coroutine frame in the
2035 // original function. The Cloner has already salvaged debug info in the new
2036 // coroutine funclets.
2038 auto DbgVariableRecords = collectDbgVariableRecords(F);
2039 for (DbgVariableRecord *DVR : DbgVariableRecords)
2040 coro::salvageDebugInfo(ArgToAllocaMap, *DVR, false /*UseEntryValue*/);
2041
2044
2045 if (shouldCreateNoAllocVariant)
2046 SwitchCoroutineSplitter::createNoAllocVariant(F, Shape, Clones);
2047}
2048
2050 LazyCallGraph::Node &N, const coro::Shape &Shape,
2054
2055 auto *CurrentSCC = &C;
2056 if (!Clones.empty()) {
2057 switch (Shape.ABI) {
2058 case coro::ABI::Switch:
2059 // Each clone in the Switch lowering is independent of the other clones.
2060 // Let the LazyCallGraph know about each one separately.
2061 for (Function *Clone : Clones)
2062 CG.addSplitFunction(N.getFunction(), *Clone);
2063 break;
2064 case coro::ABI::Async:
2065 case coro::ABI::Retcon:
2067 // Each clone in the Async/Retcon lowering references of the other clones.
2068 // Let the LazyCallGraph know about all of them at once.
2069 if (!Clones.empty())
2070 CG.addSplitRefRecursiveFunctions(N.getFunction(), Clones);
2071 break;
2072 }
2073
2074 // Let the CGSCC infra handle the changes to the original function.
2075 CurrentSCC = &updateCGAndAnalysisManagerForCGSCCPass(CG, *CurrentSCC, N, AM,
2076 UR, FAM);
2077 }
2078
2079 // Do some cleanup and let the CGSCC infra see if we've cleaned up any edges
2080 // to the split functions.
2081 postSplitCleanup(N.getFunction());
2082 CurrentSCC = &updateCGAndAnalysisManagerForFunctionPass(CG, *CurrentSCC, N,
2083 AM, UR, FAM);
2084 return *CurrentSCC;
2085}
2086
2087/// Replace a call to llvm.coro.prepare.retcon.
2088static void replacePrepare(CallInst *Prepare, LazyCallGraph &CG,
2090 auto CastFn = Prepare->getArgOperand(0); // as an i8*
2091 auto Fn = CastFn->stripPointerCasts(); // as its original type
2092
2093 // Attempt to peephole this pattern:
2094 // %0 = bitcast [[TYPE]] @some_function to i8*
2095 // %1 = call @llvm.coro.prepare.retcon(i8* %0)
2096 // %2 = bitcast %1 to [[TYPE]]
2097 // ==>
2098 // %2 = @some_function
2099 for (Use &U : llvm::make_early_inc_range(Prepare->uses())) {
2100 // Look for bitcasts back to the original function type.
2101 auto *Cast = dyn_cast<BitCastInst>(U.getUser());
2102 if (!Cast || Cast->getType() != Fn->getType())
2103 continue;
2104
2105 // Replace and remove the cast.
2106 Cast->replaceAllUsesWith(Fn);
2107 Cast->eraseFromParent();
2108 }
2109
2110 // Replace any remaining uses with the function as an i8*.
2111 // This can never directly be a callee, so we don't need to update CG.
2112 Prepare->replaceAllUsesWith(CastFn);
2113 Prepare->eraseFromParent();
2114
2115 // Kill dead bitcasts.
2116 while (auto *Cast = dyn_cast<BitCastInst>(CastFn)) {
2117 if (!Cast->use_empty())
2118 break;
2119 CastFn = Cast->getOperand(0);
2120 Cast->eraseFromParent();
2121 }
2122}
2123
2124static bool replaceAllPrepares(Function *PrepareFn, LazyCallGraph &CG,
2126 bool Changed = false;
2127 for (Use &P : llvm::make_early_inc_range(PrepareFn->uses())) {
2128 // Intrinsics can only be used in calls.
2129 auto *Prepare = cast<CallInst>(P.getUser());
2130 replacePrepare(Prepare, CG, C);
2131 Changed = true;
2132 }
2133
2134 return Changed;
2135}
2136
2137static void addPrepareFunction(const Module &M,
2139 StringRef Name) {
2140 auto *PrepareFn = M.getFunction(Name);
2141 if (PrepareFn && !PrepareFn->use_empty())
2142 Fns.push_back(PrepareFn);
2143}
2144
2145static std::unique_ptr<coro::BaseABI>
2147 std::function<bool(Instruction &)> IsMatCallback,
2148 const SmallVector<CoroSplitPass::BaseABITy> GenCustomABIs) {
2149 if (S.CoroBegin->hasCustomABI()) {
2150 unsigned CustomABI = S.CoroBegin->getCustomABI();
2151 if (CustomABI >= GenCustomABIs.size())
2152 llvm_unreachable("Custom ABI not found amoung those specified");
2153 return GenCustomABIs[CustomABI](F, S);
2154 }
2155
2156 switch (S.ABI) {
2157 case coro::ABI::Switch:
2158 return std::make_unique<coro::SwitchABI>(F, S, IsMatCallback);
2159 case coro::ABI::Async:
2160 return std::make_unique<coro::AsyncABI>(F, S, IsMatCallback);
2161 case coro::ABI::Retcon:
2162 return std::make_unique<coro::AnyRetconABI>(F, S, IsMatCallback);
2164 return std::make_unique<coro::AnyRetconABI>(F, S, IsMatCallback);
2165 }
2166 llvm_unreachable("Unknown ABI");
2167}
2168
2170 : CreateAndInitABI([](Function &F, coro::Shape &S) {
2171 std::unique_ptr<coro::BaseABI> ABI =
2173 ABI->init();
2174 return ABI;
2175 }),
2176 OptimizeFrame(OptimizeFrame) {}
2177
2180 : CreateAndInitABI([=](Function &F, coro::Shape &S) {
2181 std::unique_ptr<coro::BaseABI> ABI =
2183 ABI->init();
2184 return ABI;
2185 }),
2186 OptimizeFrame(OptimizeFrame) {}
2187
2188// For back compatibility, constructor takes a materializable callback and
2189// creates a generator for an ABI with a modified materializable callback.
2190CoroSplitPass::CoroSplitPass(std::function<bool(Instruction &)> IsMatCallback,
2191 bool OptimizeFrame)
2192 : CreateAndInitABI([=](Function &F, coro::Shape &S) {
2193 std::unique_ptr<coro::BaseABI> ABI =
2194 CreateNewABI(F, S, IsMatCallback, {});
2195 ABI->init();
2196 return ABI;
2197 }),
2198 OptimizeFrame(OptimizeFrame) {}
2199
2200// For back compatibility, constructor takes a materializable callback and
2201// creates a generator for an ABI with a modified materializable callback.
2203 std::function<bool(Instruction &)> IsMatCallback,
2205 : CreateAndInitABI([=](Function &F, coro::Shape &S) {
2206 std::unique_ptr<coro::BaseABI> ABI =
2207 CreateNewABI(F, S, IsMatCallback, GenCustomABIs);
2208 ABI->init();
2209 return ABI;
2210 }),
2211 OptimizeFrame(OptimizeFrame) {}
2212
2216 // NB: One invariant of a valid LazyCallGraph::SCC is that it must contain a
2217 // non-zero number of nodes, so we assume that here and grab the first
2218 // node's function's module.
2219 Module &M = *C.begin()->getFunction().getParent();
2220 auto &FAM =
2221 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
2222
2223 // Check for uses of llvm.coro.prepare.retcon/async.
2224 SmallVector<Function *, 2> PrepareFns;
2225 addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.retcon");
2226 addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.async");
2227
2228 // Find coroutines for processing.
2230 for (LazyCallGraph::Node &N : C)
2231 if (N.getFunction().isPresplitCoroutine())
2232 Coroutines.push_back(&N);
2233
2234 if (Coroutines.empty() && PrepareFns.empty())
2235 return PreservedAnalyses::all();
2236
2237 auto *CurrentSCC = &C;
2238 // Split all the coroutines.
2239 for (LazyCallGraph::Node *N : Coroutines) {
2240 Function &F = N->getFunction();
2241 LLVM_DEBUG(dbgs() << "CoroSplit: Processing coroutine '" << F.getName()
2242 << "\n");
2243
2244 // The suspend-crossing algorithm in buildCoroutineFrame gets tripped up
2245 // by unreachable blocks, so remove them as a first pass. Remove the
2246 // unreachable blocks before collecting intrinsics into Shape.
2248
2249 coro::Shape Shape(F);
2250 if (!Shape.CoroBegin)
2251 continue;
2252
2253 F.setSplittedCoroutine();
2254
2255 std::unique_ptr<coro::BaseABI> ABI = CreateAndInitABI(F, Shape);
2256
2258 auto &TTI = FAM.getResult<TargetIRAnalysis>(F);
2259 doSplitCoroutine(F, Clones, *ABI, TTI, OptimizeFrame);
2261 *N, Shape, Clones, *CurrentSCC, CG, AM, UR, FAM);
2262
2263 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
2264 ORE.emit([&]() {
2265 return OptimizationRemark(DEBUG_TYPE, "CoroSplit", &F)
2266 << "Split '" << ore::NV("function", F.getName())
2267 << "' (frame_size=" << ore::NV("frame_size", Shape.FrameSize)
2268 << ", align=" << ore::NV("align", Shape.FrameAlign.value()) << ")";
2269 });
2270
2271 if (!Shape.CoroSuspends.empty()) {
2272 // Run the CGSCC pipeline on the original and newly split functions.
2273 UR.CWorklist.insert(CurrentSCC);
2274 for (Function *Clone : Clones)
2275 UR.CWorklist.insert(CG.lookupSCC(CG.get(*Clone)));
2276 } else if (Shape.ABI == coro::ABI::Async) {
2277 // Reprocess the function to inline the tail called return function of
2278 // coro.async.end.
2279 UR.CWorklist.insert(&C);
2280 }
2281 }
2282
2283 for (auto *PrepareFn : PrepareFns) {
2284 replaceAllPrepares(PrepareFn, CG, *CurrentSCC);
2285 }
2286
2287 return PreservedAnalyses::none();
2288}
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)
Definition CoroSplit.cpp:86
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.
@ InlineInfo
#define DEBUG_TYPE
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.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
uint64_t IntrinsicInst * II
#define P(N)
FunctionAnalysisManager FAM
This file provides a priority worklist.
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:114
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
This pass exposes codegen information to IR-level passes.
static const unsigned FramePtr
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
bool isUnwind() const
Definition CoroInstr.h:698
CoroAllocInst * getCoroAlloc()
Definition CoroInstr.h:118
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
iterator begin() const
Definition ArrayRef.h:130
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.
Definition BasicBlock.h:62
iterator end()
Definition BasicBlock.h:483
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.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
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...
Definition BasicBlock.h:233
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
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.
Definition CallGraph.h:72
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.
Definition Constants.h:87
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.
Definition CoroInstr.h:653
This represents the llvm.coro.await.suspend.{void,bool,handle} instructions.
Definition CoroInstr.h:86
Value * getFrame() const
Definition CoroInstr.h:92
Value * getAwaiter() const
Definition CoroInstr.h:90
Function * getWrapperFunction() const
Definition CoroInstr.h:94
This class represents the llvm.coro.begin or llvm.coro.begin.custom.abi instructions.
Definition CoroInstr.h:461
bool hasCustomABI() const
Definition CoroInstr.h:469
int getCustomABI() const
Definition CoroInstr.h:473
void setInfo(Constant *C)
Definition CoroInstr.h:215
This represents the llvm.coro.size instruction.
Definition CoroInstr.h:641
This represents the llvm.coro.suspend.async instruction.
Definition CoroInstr.h:575
CoroAsyncResumeInst * getResumeFunction() const
Definition CoroInstr.h:596
This represents the llvm.coro.suspend instruction.
Definition CoroInstr.h:543
CoroSaveInst * getCoroSave() const
Definition CoroInstr.h:547
DIFile * getFile() const
Subprogram description. Uses SubclassData1.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
A debug info location.
Definition DebugLoc.h:123
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:164
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)
Definition Function.h:168
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition Function.h:211
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition Function.h:246
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:272
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:354
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
Definition Function.h:357
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:358
size_t arg_size() const
Definition Function.h:901
Argument * getArg(unsigned i) const
Definition Function.h:886
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).
Definition GlobalValue.h:60
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
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 ...
Definition Globals.cpp:534
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2788
This class captures the data input to the InlineFunction call, and records the auxiliary results prod...
Definition Cloning.h:251
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.
Definition LLVMContext.h:68
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.
Definition Metadata.h:1319
A single uniqued string.
Definition Metadata.h:722
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Definition Metadata.cpp:614
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
FunctionListType::iterator iterator
The Function iterators.
Definition Module.h:92
Diagnostic information for applied optimization remarks.
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.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
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.
Definition StringRef.h:55
Analysis pass providing the TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Value handle that tracks a Value across RAUW.
ValueTy * getValPtr() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:297
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:280
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:294
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
void setOperand(unsigned i, Value *Val)
Definition User.h:212
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:259
iterator_range< user_iterator > users()
Definition Value.h:427
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:713
iterator_range< use_iterator > uses()
Definition Value.h:381
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:322
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
Function & F
Definition ABI.h:59
coro::Shape & Shape
Definition ABI.h:60
AnyCoroSuspendInst * ActiveSuspend
The active suspend instruction; meaningful only for continuation and async ABIs.
Definition CoroCloner.h:57
Value * deriveNewFramePointer()
Derive the value of the new frame pointer.
TargetTransformInfo & TTI
Definition CoroCloner.h:49
coro::Shape & Shape
Definition CoroCloner.h:46
static Function * createClone(Function &OrigF, const Twine &Suffix, coro::Shape &Shape, Function *NewF, AnyCoroSuspendInst *ActiveSuspend, TargetTransformInfo &TTI)
Create a clone for a continuation lowering.
Definition CoroCloner.h:83
ValueToValueMapTy VMap
Definition CoroCloner.h:51
const Twine & Suffix
Definition CoroCloner.h:45
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.
Definition CoroCloner.h:139
void create() override
Clone the body of the original function into a resume function of some sort.
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
CallInst * Call
Changed
#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.
Definition CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ Async
The "async continuation" lowering, where each suspend point creates a single continuation function.
Definition CoroShape.h:48
@ RetconOnce
The "unique returned-continuation" lowering, where each suspend point creates a single continuation f...
Definition CoroShape.h:43
@ Retcon
The "returned-continuation" lowering, where each suspend point creates a single continuation function...
Definition CoroShape.h:36
@ Switch
The "resume-switch" lowering, where there are separate resume and destroy functions that are shared b...
Definition CoroShape.h:31
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.
Definition CoroCloner.h:33
@ Continuation
An individual continuation function.
Definition CoroCloner.h:36
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.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
auto cast_if_present(const Y &Val)
cast_if_present<X> - Functionally identical to cast, except that a null value is accepted.
Definition Casting.h:683
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1732
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.
Definition STLExtras.h:841
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2554
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
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...
Definition STLExtras.h:634
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
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.
Definition Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
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...
Definition Casting.h:547
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...
Definition Local.cpp:2531
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
TargetTransformInfo TTI
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
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.
Definition Casting.h:559
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.
Definition Local.cpp:2901
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...
Definition CFG.cpp:282
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:872
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
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
Definition CoroSplit.h:56
CallInst * makeSubFnCall(Value *Arg, int Index, Instruction *InsertPt)
SmallVector< CallInst *, 2 > SymmetricTransfers
Definition CoroShape.h:61
SmallVector< CoroAwaitSuspendInst *, 4 > CoroAwaitSuspends
Definition CoroShape.h:60
AsyncLoweringStorage AsyncLowering
Definition CoroShape.h:142
FunctionType * getResumeFunctionType() const
Definition CoroShape.h:175
IntegerType * getIndexType() const
Definition CoroShape.h:160
PointerType * getSwitchResumePointerType() const
Definition CoroShape.h:169
CoroIdInst * getSwitchCoroId() const
Definition CoroShape.h:145
SmallVector< CoroSizeInst *, 2 > CoroSizes
Definition CoroShape.h:57
coro::ABI ABI
Definition CoroShape.h:98
SmallVector< AnyCoroSuspendInst *, 4 > CoroSuspends
Definition CoroShape.h:59
uint64_t FrameSize
Definition CoroShape.h:101
ConstantInt * getIndex(uint64_t Value) const
Definition CoroShape.h:165
SwitchLoweringStorage SwitchLowering
Definition CoroShape.h:140
CoroBeginInst * CoroBegin
Definition CoroShape.h:54
BasicBlock::iterator getInsertPtAfterFramePtr() const
Definition CoroShape.h:232
SmallVector< CoroIsInRampInst *, 2 > CoroIsInRampInsts
Definition CoroShape.h:56
LLVM_ABI void emitDealloc(IRBuilder<> &Builder, Value *Ptr, CallGraph *CG) const
Deallocate memory according to the rules of the active lowering.
RetconLoweringStorage RetconLowering
Definition CoroShape.h:141
SmallVector< CoroAlignInst *, 2 > CoroAligns
Definition CoroShape.h:58
SmallVector< AnyCoroEndInst *, 4 > CoroEnds
Definition CoroShape.h:55
SmallVector< CallInst *, 2 > SwiftErrorOps
Definition CoroShape.h:64