LLVM 22.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 InResume, 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 (!InResume)
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// Mark a coroutine as done, which implies that the coroutine is finished and
306// never gets resumed.
307//
308// In resume-switched ABI, the done state is represented by storing zero in
309// ResumeFnAddr.
310//
311// NOTE: We couldn't omit the argument `FramePtr`. It is necessary because the
312// pointer to the frame in splitted function is not stored in `Shape`.
313static void markCoroutineAsDone(IRBuilder<> &Builder, const coro::Shape &Shape,
314 Value *FramePtr) {
315 assert(
316 Shape.ABI == coro::ABI::Switch &&
317 "markCoroutineAsDone is only supported for Switch-Resumed ABI for now.");
318 auto *GepIndex = Builder.CreateStructGEP(
320 "ResumeFn.addr");
323 Builder.CreateStore(NullPtr, GepIndex);
324
325 // If the coroutine don't have unwind coro end, we could omit the store to
326 // the final suspend point since we could infer the coroutine is suspended
327 // at the final suspend point by the nullness of ResumeFnAddr.
328 // However, we can't skip it if the coroutine have unwind coro end. Since
329 // the coroutine reaches unwind coro end is considered suspended at the
330 // final suspend point (the ResumeFnAddr is null) but in fact the coroutine
331 // didn't complete yet. We need the IndexVal for the final suspend point
332 // to make the states clear.
335 assert(cast<CoroSuspendInst>(Shape.CoroSuspends.back())->isFinal() &&
336 "The final suspend should only live in the last position of "
337 "CoroSuspends.");
338 ConstantInt *IndexVal = Shape.getIndex(Shape.CoroSuspends.size() - 1);
339 auto *FinalIndex = Builder.CreateStructGEP(
340 Shape.FrameTy, FramePtr, Shape.getSwitchIndexField(), "index.addr");
341
342 Builder.CreateStore(IndexVal, FinalIndex);
343 }
344}
345
346/// Replace an unwind call to llvm.coro.end.
347static void replaceUnwindCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape,
348 Value *FramePtr, bool InResume,
349 CallGraph *CG) {
350 IRBuilder<> Builder(End);
351
352 switch (Shape.ABI) {
353 // In switch-lowering, this does nothing in the main function.
354 case coro::ABI::Switch: {
355 // In C++'s specification, the coroutine should be marked as done
356 // if promise.unhandled_exception() throws. The frontend will
357 // call coro.end(true) along this path.
358 //
359 // FIXME: We should refactor this once there is other language
360 // which uses Switch-Resumed style other than C++.
361 markCoroutineAsDone(Builder, Shape, FramePtr);
362 if (!InResume)
363 return;
364 break;
365 }
366 // In async lowering this does nothing.
367 case coro::ABI::Async:
368 break;
369 // In continuation-lowering, this frees the continuation storage.
372 maybeFreeRetconStorage(Builder, Shape, FramePtr, CG);
373 break;
374 }
375
376 // If coro.end has an associated bundle, add cleanupret instruction.
377 if (auto Bundle = End->getOperandBundle(LLVMContext::OB_funclet)) {
378 auto *FromPad = cast<CleanupPadInst>(Bundle->Inputs[0]);
379 auto *CleanupRet = Builder.CreateCleanupRet(FromPad, nullptr);
380 End->getParent()->splitBasicBlock(End);
381 CleanupRet->getParent()->getTerminator()->eraseFromParent();
382 }
383}
384
385static void replaceCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape,
386 Value *FramePtr, bool InResume, CallGraph *CG) {
387 if (End->isUnwind())
388 replaceUnwindCoroEnd(End, Shape, FramePtr, InResume, CG);
389 else
390 replaceFallthroughCoroEnd(End, Shape, FramePtr, InResume, CG);
391
392 auto &Context = End->getContext();
393 End->replaceAllUsesWith(InResume ? ConstantInt::getTrue(Context)
394 : ConstantInt::getFalse(Context));
395 End->eraseFromParent();
396}
397
398// In the resume function, we remove the last case (when coro::Shape is built,
399// the final suspend point (if present) is always the last element of
400// CoroSuspends array) since it is an undefined behavior to resume a coroutine
401// suspended at the final suspend point.
402// In the destroy function, if it isn't possible that the ResumeFnAddr is NULL
403// and the coroutine doesn't suspend at the final suspend point actually (this
404// is possible since the coroutine is considered suspended at the final suspend
405// point if promise.unhandled_exception() exits via an exception), we can
406// remove the last case.
409 Shape.SwitchLowering.HasFinalSuspend);
410
411 if (isSwitchDestroyFunction() && Shape.SwitchLowering.HasUnwindCoroEnd)
412 return;
413
414 auto *Switch = cast<SwitchInst>(VMap[Shape.SwitchLowering.ResumeSwitch]);
415 auto FinalCaseIt = std::prev(Switch->case_end());
416 BasicBlock *ResumeBB = FinalCaseIt->getCaseSuccessor();
417 Switch->removeCase(FinalCaseIt);
419 BasicBlock *OldSwitchBB = Switch->getParent();
420 auto *NewSwitchBB = OldSwitchBB->splitBasicBlock(Switch, "Switch");
421 Builder.SetInsertPoint(OldSwitchBB->getTerminator());
422
423 if (NewF->isCoroOnlyDestroyWhenComplete()) {
424 // When the coroutine can only be destroyed when complete, we don't need
425 // to generate code for other cases.
426 Builder.CreateBr(ResumeBB);
427 } else {
428 auto *GepIndex = Builder.CreateStructGEP(
430 "ResumeFn.addr");
431 auto *Load =
432 Builder.CreateLoad(Shape.getSwitchResumePointerType(), GepIndex);
433 auto *Cond = Builder.CreateIsNull(Load);
434 Builder.CreateCondBr(Cond, ResumeBB, NewSwitchBB);
435 }
436 OldSwitchBB->getTerminator()->eraseFromParent();
437 }
438}
439
440static FunctionType *
442 auto *AsyncSuspend = cast<CoroSuspendAsyncInst>(Suspend);
443 auto *StructTy = cast<StructType>(AsyncSuspend->getType());
444 auto &Context = Suspend->getParent()->getParent()->getContext();
445 auto *VoidTy = Type::getVoidTy(Context);
446 return FunctionType::get(VoidTy, StructTy->elements(), false);
447}
448
450 const Twine &Suffix,
451 Module::iterator InsertBefore,
452 AnyCoroSuspendInst *ActiveSuspend) {
453 Module *M = OrigF.getParent();
454 auto *FnTy = (Shape.ABI != coro::ABI::Async)
455 ? Shape.getResumeFunctionType()
456 : getFunctionTypeFromAsyncSuspend(ActiveSuspend);
457
458 Function *NewF =
460 OrigF.getName() + Suffix);
461
462 M->getFunctionList().insert(InsertBefore, NewF);
463
464 return NewF;
465}
466
467/// Replace uses of the active llvm.coro.suspend.retcon/async call with the
468/// arguments to the continuation function.
469///
470/// This assumes that the builder has a meaningful insertion point.
473 Shape.ABI == coro::ABI::Async);
474
475 auto NewS = VMap[ActiveSuspend];
476 if (NewS->use_empty())
477 return;
478
479 // Copy out all the continuation arguments after the buffer pointer into
480 // an easily-indexed data structure for convenience.
482 // The async ABI includes all arguments -- including the first argument.
483 bool IsAsyncABI = Shape.ABI == coro::ABI::Async;
484 for (auto I = IsAsyncABI ? NewF->arg_begin() : std::next(NewF->arg_begin()),
485 E = NewF->arg_end();
486 I != E; ++I)
487 Args.push_back(&*I);
488
489 // If the suspend returns a single scalar value, we can just do a simple
490 // replacement.
491 if (!isa<StructType>(NewS->getType())) {
492 assert(Args.size() == 1);
493 NewS->replaceAllUsesWith(Args.front());
494 return;
495 }
496
497 // Try to peephole extracts of an aggregate return.
498 for (Use &U : llvm::make_early_inc_range(NewS->uses())) {
499 auto *EVI = dyn_cast<ExtractValueInst>(U.getUser());
500 if (!EVI || EVI->getNumIndices() != 1)
501 continue;
502
503 EVI->replaceAllUsesWith(Args[EVI->getIndices().front()]);
504 EVI->eraseFromParent();
505 }
506
507 // If we have no remaining uses, we're done.
508 if (NewS->use_empty())
509 return;
510
511 // Otherwise, we need to create an aggregate.
512 Value *Aggr = PoisonValue::get(NewS->getType());
513 for (auto [Idx, Arg] : llvm::enumerate(Args))
514 Aggr = Builder.CreateInsertValue(Aggr, Arg, Idx);
515
516 NewS->replaceAllUsesWith(Aggr);
517}
518
520 Value *SuspendResult;
521
522 switch (Shape.ABI) {
523 // In switch lowering, replace coro.suspend with the appropriate value
524 // for the type of function we're extracting.
525 // Replacing coro.suspend with (0) will result in control flow proceeding to
526 // a resume label associated with a suspend point, replacing it with (1) will
527 // result in control flow proceeding to a cleanup label associated with this
528 // suspend point.
530 SuspendResult = Builder.getInt8(isSwitchDestroyFunction() ? 1 : 0);
531 break;
532
533 // In async lowering there are no uses of the result.
534 case coro::ABI::Async:
535 return;
536
537 // In returned-continuation lowering, the arguments from earlier
538 // continuations are theoretically arbitrary, and they should have been
539 // spilled.
542 return;
543 }
544
545 for (AnyCoroSuspendInst *CS : Shape.CoroSuspends) {
546 // The active suspend was handled earlier.
547 if (CS == ActiveSuspend)
548 continue;
549
550 auto *MappedCS = cast<AnyCoroSuspendInst>(VMap[CS]);
551 MappedCS->replaceAllUsesWith(SuspendResult);
552 MappedCS->eraseFromParent();
553 }
554}
555
557 for (AnyCoroEndInst *CE : Shape.CoroEnds) {
558 // We use a null call graph because there's no call graph node for
559 // the cloned function yet. We'll just be rebuilding that later.
560 auto *NewCE = cast<AnyCoroEndInst>(VMap[CE]);
561 replaceCoroEnd(NewCE, Shape, NewFramePtr, /*in resume*/ true, nullptr);
562 }
563}
564
566 ValueToValueMapTy *VMap) {
567 if (Shape.ABI == coro::ABI::Async && Shape.CoroSuspends.empty())
568 return;
569 Value *CachedSlot = nullptr;
570 auto getSwiftErrorSlot = [&](Type *ValueTy) -> Value * {
571 if (CachedSlot)
572 return CachedSlot;
573
574 // Check if the function has a swifterror argument.
575 for (auto &Arg : F.args()) {
576 if (Arg.isSwiftError()) {
577 CachedSlot = &Arg;
578 return &Arg;
579 }
580 }
581
582 // Create a swifterror alloca.
583 IRBuilder<> Builder(&F.getEntryBlock(),
584 F.getEntryBlock().getFirstNonPHIOrDbg());
585 auto Alloca = Builder.CreateAlloca(ValueTy);
586 Alloca->setSwiftError(true);
587
588 CachedSlot = Alloca;
589 return Alloca;
590 };
591
592 for (CallInst *Op : Shape.SwiftErrorOps) {
593 auto MappedOp = VMap ? cast<CallInst>((*VMap)[Op]) : Op;
594 IRBuilder<> Builder(MappedOp);
595
596 // If there are no arguments, this is a 'get' operation.
597 Value *MappedResult;
598 if (Op->arg_empty()) {
599 auto ValueTy = Op->getType();
600 auto Slot = getSwiftErrorSlot(ValueTy);
601 MappedResult = Builder.CreateLoad(ValueTy, Slot);
602 } else {
603 assert(Op->arg_size() == 1);
604 auto Value = MappedOp->getArgOperand(0);
605 auto ValueTy = Value->getType();
606 auto Slot = getSwiftErrorSlot(ValueTy);
607 Builder.CreateStore(Value, Slot);
608 MappedResult = Slot;
609 }
610
611 MappedOp->replaceAllUsesWith(MappedResult);
612 MappedOp->eraseFromParent();
613 }
614
615 // If we're updating the original function, we've invalidated SwiftErrorOps.
616 if (VMap == nullptr) {
617 Shape.SwiftErrorOps.clear();
618 }
619}
620
621/// Returns all debug records in F.
624 SmallVector<DbgVariableRecord *> DbgVariableRecords;
625 for (auto &I : instructions(F)) {
626 for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange()))
627 DbgVariableRecords.push_back(&DVR);
628 }
629 return DbgVariableRecords;
630}
631
635
637 auto DbgVariableRecords = collectDbgVariableRecords(*NewF);
639
640 // Only 64-bit ABIs have a register we can refer to with the entry value.
641 bool UseEntryValue = OrigF.getParent()->getTargetTriple().isArch64Bit();
642 for (DbgVariableRecord *DVR : DbgVariableRecords)
643 coro::salvageDebugInfo(ArgToAllocaMap, *DVR, UseEntryValue);
644
645 // Remove all salvaged dbg.declare intrinsics that became
646 // either unreachable or stale due to the CoroSplit transformation.
647 DominatorTree DomTree(*NewF);
648 auto IsUnreachableBlock = [&](BasicBlock *BB) {
649 return !isPotentiallyReachable(&NewF->getEntryBlock(), BB, nullptr,
650 &DomTree);
651 };
652 auto RemoveOne = [&](DbgVariableRecord *DVI) {
653 if (IsUnreachableBlock(DVI->getParent()))
654 DVI->eraseFromParent();
655 else if (isa_and_nonnull<AllocaInst>(DVI->getVariableLocationOp(0))) {
656 // Count all non-debuginfo uses in reachable blocks.
657 unsigned Uses = 0;
658 for (auto *User : DVI->getVariableLocationOp(0)->users())
659 if (auto *I = dyn_cast<Instruction>(User))
660 if (!isa<AllocaInst>(I) && !IsUnreachableBlock(I->getParent()))
661 ++Uses;
662 if (!Uses)
663 DVI->eraseFromParent();
664 }
665 };
666 for_each(DbgVariableRecords, RemoveOne);
667}
668
670 // In the original function, the AllocaSpillBlock is a block immediately
671 // following the allocation of the frame object which defines GEPs for
672 // all the allocas that have been moved into the frame, and it ends by
673 // branching to the original beginning of the coroutine. Make this
674 // the entry block of the cloned function.
675 auto *Entry = cast<BasicBlock>(VMap[Shape.AllocaSpillBlock]);
676 auto *OldEntry = &NewF->getEntryBlock();
677 Entry->setName("entry" + Suffix);
678 Entry->moveBefore(OldEntry);
679 Entry->getTerminator()->eraseFromParent();
680
681 // Clear all predecessors of the new entry block. There should be
682 // exactly one predecessor, which we created when splitting out
683 // AllocaSpillBlock to begin with.
684 assert(Entry->hasOneUse());
685 auto BranchToEntry = cast<BranchInst>(Entry->user_back());
686 assert(BranchToEntry->isUnconditional());
687 Builder.SetInsertPoint(BranchToEntry);
688 Builder.CreateUnreachable();
689 BranchToEntry->eraseFromParent();
690
691 // Branch from the entry to the appropriate place.
692 Builder.SetInsertPoint(Entry);
693 switch (Shape.ABI) {
694 case coro::ABI::Switch: {
695 // In switch-lowering, we built a resume-entry block in the original
696 // function. Make the entry block branch to this.
697 auto *SwitchBB =
698 cast<BasicBlock>(VMap[Shape.SwitchLowering.ResumeEntryBlock]);
699 Builder.CreateBr(SwitchBB);
700 SwitchBB->moveAfter(Entry);
701 break;
702 }
703 case coro::ABI::Async:
706 // In continuation ABIs, we want to branch to immediately after the
707 // active suspend point. Earlier phases will have put the suspend in its
708 // own basic block, so just thread our jump directly to its successor.
709 assert((Shape.ABI == coro::ABI::Async &&
711 ((Shape.ABI == coro::ABI::Retcon ||
715 auto Branch = cast<BranchInst>(MappedCS->getNextNode());
716 assert(Branch->isUnconditional());
717 Builder.CreateBr(Branch->getSuccessor(0));
718 break;
719 }
720 }
721
722 // Any static alloca that's still being used but not reachable from the new
723 // entry needs to be moved to the new entry.
724 Function *F = OldEntry->getParent();
725 DominatorTree DT{*F};
727 auto *Alloca = dyn_cast<AllocaInst>(&I);
728 if (!Alloca || I.use_empty())
729 continue;
730 if (DT.isReachableFromEntry(I.getParent()) ||
731 !isa<ConstantInt>(Alloca->getArraySize()))
732 continue;
733 I.moveBefore(*Entry, Entry->getFirstInsertionPt());
734 }
735}
736
737/// Derive the value of the new frame pointer.
739 // Builder should be inserting to the front of the new entry block.
740
741 switch (Shape.ABI) {
742 // In switch-lowering, the argument is the frame pointer.
744 return &*NewF->arg_begin();
745 // In async-lowering, one of the arguments is an async context as determined
746 // by the `llvm.coro.id.async` intrinsic. We can retrieve the async context of
747 // the resume function from the async context projection function associated
748 // with the active suspend. The frame is located as a tail to the async
749 // context header.
750 case coro::ABI::Async: {
751 auto *ActiveAsyncSuspend = cast<CoroSuspendAsyncInst>(ActiveSuspend);
752 auto ContextIdx = ActiveAsyncSuspend->getStorageArgumentIndex() & 0xff;
753 auto *CalleeContext = NewF->getArg(ContextIdx);
754 auto *ProjectionFunc =
755 ActiveAsyncSuspend->getAsyncContextProjectionFunction();
756 auto DbgLoc =
758 // Calling i8* (i8*)
759 auto *CallerContext = Builder.CreateCall(ProjectionFunc->getFunctionType(),
760 ProjectionFunc, CalleeContext);
761 CallerContext->setCallingConv(ProjectionFunc->getCallingConv());
762 CallerContext->setDebugLoc(DbgLoc);
763 // The frame is located after the async_context header.
764 auto &Context = Builder.getContext();
765 auto *FramePtrAddr = Builder.CreateConstInBoundsGEP1_32(
766 Type::getInt8Ty(Context), CallerContext,
767 Shape.AsyncLowering.FrameOffset, "async.ctx.frameptr");
768 // Inline the projection function.
770 auto InlineRes = InlineFunction(*CallerContext, InlineInfo);
771 assert(InlineRes.isSuccess());
772 (void)InlineRes;
773 return FramePtrAddr;
774 }
775 // In continuation-lowering, the argument is the opaque storage.
778 Argument *NewStorage = &*NewF->arg_begin();
779 auto FramePtrTy = PointerType::getUnqual(Shape.FrameTy->getContext());
780
781 // If the storage is inline, just bitcast to the storage to the frame type.
782 if (Shape.RetconLowering.IsFrameInlineInStorage)
783 return NewStorage;
784
785 // Otherwise, load the real frame from the opaque storage.
786 return Builder.CreateLoad(FramePtrTy, NewStorage);
787 }
788 }
789 llvm_unreachable("bad ABI");
790}
791
792/// Adjust the scope line of the funclet to the first line number after the
793/// suspend point. This avoids a jump in the line table from the function
794/// declaration (where prologue instructions are attributed to) to the suspend
795/// point.
796/// Only adjust the scope line when the files are the same.
797/// If no candidate line number is found, fallback to the line of ActiveSuspend.
798static void updateScopeLine(Instruction *ActiveSuspend,
799 DISubprogram &SPToUpdate) {
800 if (!ActiveSuspend)
801 return;
802
803 // No subsequent instruction -> fallback to the location of ActiveSuspend.
804 if (!ActiveSuspend->getNextNode()) {
805 if (auto DL = ActiveSuspend->getDebugLoc())
806 if (SPToUpdate.getFile() == DL->getFile())
807 SPToUpdate.setScopeLine(DL->getLine());
808 return;
809 }
810
812 // Corosplit splits the BB around ActiveSuspend, so the meaningful
813 // instructions are not in the same BB.
814 if (auto *Branch = dyn_cast_or_null<BranchInst>(Successor);
815 Branch && Branch->isUnconditional())
816 Successor = Branch->getSuccessor(0)->getFirstNonPHIOrDbg();
817
818 // Find the first successor of ActiveSuspend with a non-zero line location.
819 // If that matches the file of ActiveSuspend, use it.
820 BasicBlock *PBB = Successor->getParent();
821 for (; Successor != PBB->end(); Successor = std::next(Successor)) {
823 auto DL = Successor->getDebugLoc();
824 if (!DL || DL.getLine() == 0)
825 continue;
826
827 if (SPToUpdate.getFile() == DL->getFile()) {
828 SPToUpdate.setScopeLine(DL.getLine());
829 return;
830 }
831
832 break;
833 }
834
835 // If the search above failed, fallback to the location of ActiveSuspend.
836 if (auto DL = ActiveSuspend->getDebugLoc())
837 if (SPToUpdate.getFile() == DL->getFile())
838 SPToUpdate.setScopeLine(DL->getLine());
839}
840
841static void addFramePointerAttrs(AttributeList &Attrs, LLVMContext &Context,
842 unsigned ParamIndex, uint64_t Size,
843 Align Alignment, bool NoAlias) {
844 AttrBuilder ParamAttrs(Context);
845 ParamAttrs.addAttribute(Attribute::NonNull);
846 ParamAttrs.addAttribute(Attribute::NoUndef);
847
848 if (NoAlias)
849 ParamAttrs.addAttribute(Attribute::NoAlias);
850
851 ParamAttrs.addAlignmentAttr(Alignment);
852 ParamAttrs.addDereferenceableAttr(Size);
853 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs);
854}
855
856static void addAsyncContextAttrs(AttributeList &Attrs, LLVMContext &Context,
857 unsigned ParamIndex) {
858 AttrBuilder ParamAttrs(Context);
859 ParamAttrs.addAttribute(Attribute::SwiftAsync);
860 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs);
861}
862
863static void addSwiftSelfAttrs(AttributeList &Attrs, LLVMContext &Context,
864 unsigned ParamIndex) {
865 AttrBuilder ParamAttrs(Context);
866 ParamAttrs.addAttribute(Attribute::SwiftSelf);
867 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs);
868}
869
870/// Clone the body of the original function into a resume function of
871/// some sort.
873 assert(NewF);
874
875 // Replace all args with dummy instructions. If an argument is the old frame
876 // pointer, the dummy will be replaced by the new frame pointer once it is
877 // computed below. Uses of all other arguments should have already been
878 // rewritten by buildCoroutineFrame() to use loads/stores on the coroutine
879 // frame.
881 for (Argument &A : OrigF.args()) {
882 DummyArgs.push_back(new FreezeInst(PoisonValue::get(A.getType())));
883 VMap[&A] = DummyArgs.back();
884 }
885
887
888 // Ignore attempts to change certain attributes of the function.
889 // TODO: maybe there should be a way to suppress this during cloning?
890 auto savedVisibility = NewF->getVisibility();
891 auto savedUnnamedAddr = NewF->getUnnamedAddr();
892 auto savedDLLStorageClass = NewF->getDLLStorageClass();
893
894 // NewF's linkage (which CloneFunctionInto does *not* change) might not
895 // be compatible with the visibility of OrigF (which it *does* change),
896 // so protect against that.
897 auto savedLinkage = NewF->getLinkage();
899
902
903 auto &Context = NewF->getContext();
904
905 if (DISubprogram *SP = NewF->getSubprogram()) {
906 assert(SP != OrigF.getSubprogram() && SP->isDistinct());
908
909 // Update the linkage name and the function name to reflect the modified
910 // name.
911 MDString *NewLinkageName = MDString::get(Context, NewF->getName());
912 SP->replaceLinkageName(NewLinkageName);
913 if (DISubprogram *Decl = SP->getDeclaration()) {
914 TempDISubprogram NewDecl = Decl->clone();
915 NewDecl->replaceLinkageName(NewLinkageName);
916 SP->replaceDeclaration(MDNode::replaceWithUniqued(std::move(NewDecl)));
917 }
918 }
919
920 NewF->setLinkage(savedLinkage);
921 NewF->setVisibility(savedVisibility);
922 NewF->setUnnamedAddr(savedUnnamedAddr);
923 NewF->setDLLStorageClass(savedDLLStorageClass);
924 // The function sanitizer metadata needs to match the signature of the
925 // function it is being attached to. However this does not hold for split
926 // functions here. Thus remove the metadata for split functions.
927 if (Shape.ABI == coro::ABI::Switch &&
928 NewF->hasMetadata(LLVMContext::MD_func_sanitize))
929 NewF->eraseMetadata(LLVMContext::MD_func_sanitize);
930
931 // Replace the attributes of the new function:
932 auto OrigAttrs = NewF->getAttributes();
933 auto NewAttrs = AttributeList();
934
935 switch (Shape.ABI) {
937 // Bootstrap attributes by copying function attributes from the
938 // original function. This should include optimization settings and so on.
939 NewAttrs = NewAttrs.addFnAttributes(
940 Context, AttrBuilder(Context, OrigAttrs.getFnAttrs()));
941
942 addFramePointerAttrs(NewAttrs, Context, 0, Shape.FrameSize,
943 Shape.FrameAlign, /*NoAlias=*/false);
944 break;
945 case coro::ABI::Async: {
946 auto *ActiveAsyncSuspend = cast<CoroSuspendAsyncInst>(ActiveSuspend);
947 if (OrigF.hasParamAttribute(Shape.AsyncLowering.ContextArgNo,
948 Attribute::SwiftAsync)) {
949 uint32_t ArgAttributeIndices =
950 ActiveAsyncSuspend->getStorageArgumentIndex();
951 auto ContextArgIndex = ArgAttributeIndices & 0xff;
952 addAsyncContextAttrs(NewAttrs, Context, ContextArgIndex);
953
954 // `swiftasync` must preceed `swiftself` so 0 is not a valid index for
955 // `swiftself`.
956 auto SwiftSelfIndex = ArgAttributeIndices >> 8;
957 if (SwiftSelfIndex)
958 addSwiftSelfAttrs(NewAttrs, Context, SwiftSelfIndex);
959 }
960
961 // Transfer the original function's attributes.
962 auto FnAttrs = OrigF.getAttributes().getFnAttrs();
963 NewAttrs = NewAttrs.addFnAttributes(Context, AttrBuilder(Context, FnAttrs));
964 break;
965 }
968 // If we have a continuation prototype, just use its attributes,
969 // full-stop.
970 NewAttrs = Shape.RetconLowering.ResumePrototype->getAttributes();
971
972 /// FIXME: Is it really good to add the NoAlias attribute?
973 addFramePointerAttrs(NewAttrs, Context, 0,
974 Shape.getRetconCoroId()->getStorageSize(),
975 Shape.getRetconCoroId()->getStorageAlignment(),
976 /*NoAlias=*/true);
977
978 break;
979 }
980
981 switch (Shape.ABI) {
982 // In these ABIs, the cloned functions always return 'void', and the
983 // existing return sites are meaningless. Note that for unique
984 // continuations, this includes the returns associated with suspends;
985 // this is fine because we can't suspend twice.
988 // Remove old returns.
989 for (ReturnInst *Return : Returns)
990 changeToUnreachable(Return);
991 break;
992
993 // With multi-suspend continuations, we'll already have eliminated the
994 // original returns and inserted returns before all the suspend points,
995 // so we want to leave any returns in place.
997 break;
998 // Async lowering will insert musttail call functions at all suspend points
999 // followed by a return.
1000 // Don't change returns to unreachable because that will trip up the verifier.
1001 // These returns should be unreachable from the clone.
1002 case coro::ABI::Async:
1003 break;
1004 }
1005
1006 NewF->setAttributes(NewAttrs);
1007 NewF->setCallingConv(Shape.getResumeFunctionCC());
1008
1009 // Set up the new entry block.
1011
1012 // Turn symmetric transfers into musttail calls.
1013 for (CallInst *ResumeCall : Shape.SymmetricTransfers) {
1014 ResumeCall = cast<CallInst>(VMap[ResumeCall]);
1015 if (TTI.supportsTailCallFor(ResumeCall)) {
1016 // FIXME: Could we support symmetric transfer effectively without
1017 // musttail?
1018 ResumeCall->setTailCallKind(CallInst::TCK_MustTail);
1019 }
1020
1021 // Put a 'ret void' after the call, and split any remaining instructions to
1022 // an unreachable block.
1023 BasicBlock *BB = ResumeCall->getParent();
1024 BB->splitBasicBlock(ResumeCall->getNextNode());
1025 Builder.SetInsertPoint(BB->getTerminator());
1026 Builder.CreateRetVoid();
1028 }
1029
1030 Builder.SetInsertPoint(&NewF->getEntryBlock().front());
1032
1033 // Remap frame pointer.
1034 Value *OldFramePtr = VMap[Shape.FramePtr];
1035 NewFramePtr->takeName(OldFramePtr);
1036 OldFramePtr->replaceAllUsesWith(NewFramePtr);
1037
1038 // Remap vFrame pointer.
1039 auto *NewVFrame = Builder.CreateBitCast(
1040 NewFramePtr, PointerType::getUnqual(Builder.getContext()), "vFrame");
1041 Value *OldVFrame = cast<Value>(VMap[Shape.CoroBegin]);
1042 if (OldVFrame != NewVFrame)
1043 OldVFrame->replaceAllUsesWith(NewVFrame);
1044
1045 // All uses of the arguments should have been resolved by this point,
1046 // so we can safely remove the dummy values.
1047 for (Instruction *DummyArg : DummyArgs) {
1048 DummyArg->replaceAllUsesWith(PoisonValue::get(DummyArg->getType()));
1049 DummyArg->deleteValue();
1050 }
1051
1052 switch (Shape.ABI) {
1053 case coro::ABI::Switch:
1054 // Rewrite final suspend handling as it is not done via switch (allows to
1055 // remove final case from the switch, since it is undefined behavior to
1056 // resume the coroutine suspended at the final suspend point.
1057 if (Shape.SwitchLowering.HasFinalSuspend)
1059 break;
1060 case coro::ABI::Async:
1061 case coro::ABI::Retcon:
1063 // Replace uses of the active suspend with the corresponding
1064 // continuation-function arguments.
1065 assert(ActiveSuspend != nullptr &&
1066 "no active suspend when lowering a continuation-style coroutine");
1068 break;
1069 }
1070
1071 // Handle suspends.
1073
1074 // Handle swifterror.
1076
1077 // Remove coro.end intrinsics.
1079
1080 // Salvage debug info that points into the coroutine frame.
1082}
1083
1085 // Create a new function matching the original type
1086 NewF = createCloneDeclaration(OrigF, Shape, Suffix, OrigF.getParent()->end(),
1088
1089 // Clone the function
1091
1092 // Eliminate coro.free from the clones, replacing it with 'null' in cleanup,
1093 // to suppress deallocation code.
1094 coro::replaceCoroFree(cast<CoroIdInst>(VMap[Shape.CoroBegin->getId()]),
1096}
1097
1099 assert(Shape.ABI == coro::ABI::Async);
1100
1101 auto *FuncPtrStruct = cast<ConstantStruct>(
1103 auto *OrigRelativeFunOffset = FuncPtrStruct->getOperand(0);
1104 auto *OrigContextSize = FuncPtrStruct->getOperand(1);
1105 auto *NewContextSize = ConstantInt::get(OrigContextSize->getType(),
1107 auto *NewFuncPtrStruct = ConstantStruct::get(
1108 FuncPtrStruct->getType(), OrigRelativeFunOffset, NewContextSize);
1109
1110 Shape.AsyncLowering.AsyncFuncPointer->setInitializer(NewFuncPtrStruct);
1111}
1112
1114 // In the same function all coro.sizes should have the same result type.
1115 auto *SizeIntrin = Shape.CoroSizes.back();
1116 Module *M = SizeIntrin->getModule();
1117 const DataLayout &DL = M->getDataLayout();
1118 return DL.getTypeAllocSize(Shape.FrameTy);
1119}
1120
1122 if (Shape.ABI == coro::ABI::Async)
1124
1125 for (CoroAlignInst *CA : Shape.CoroAligns) {
1127 ConstantInt::get(CA->getType(), Shape.FrameAlign.value()));
1128 CA->eraseFromParent();
1129 }
1130
1131 if (Shape.CoroSizes.empty())
1132 return;
1133
1134 // In the same function all coro.sizes should have the same result type.
1135 auto *SizeIntrin = Shape.CoroSizes.back();
1136 auto *SizeConstant =
1137 ConstantInt::get(SizeIntrin->getType(), getFrameSizeForShape(Shape));
1138
1139 for (CoroSizeInst *CS : Shape.CoroSizes) {
1140 CS->replaceAllUsesWith(SizeConstant);
1141 CS->eraseFromParent();
1142 }
1143}
1144
1147
1148#ifndef NDEBUG
1149 // For now, we do a mandatory verification step because we don't
1150 // entirely trust this pass. Note that we don't want to add a verifier
1151 // pass to FPM below because it will also verify all the global data.
1152 if (verifyFunction(F, &errs()))
1153 report_fatal_error("Broken function");
1154#endif
1155}
1156
1157// Coroutine has no suspend points. Remove heap allocation for the coroutine
1158// frame if possible.
1160 auto *CoroBegin = Shape.CoroBegin;
1161 switch (Shape.ABI) {
1162 case coro::ABI::Switch: {
1163 auto SwitchId = Shape.getSwitchCoroId();
1164 auto *AllocInst = SwitchId->getCoroAlloc();
1165 coro::replaceCoroFree(SwitchId, /*Elide=*/AllocInst != nullptr);
1166 if (AllocInst) {
1167 IRBuilder<> Builder(AllocInst);
1168 auto *Frame = Builder.CreateAlloca(Shape.FrameTy);
1169 Frame->setAlignment(Shape.FrameAlign);
1170 AllocInst->replaceAllUsesWith(Builder.getFalse());
1171 AllocInst->eraseFromParent();
1172 CoroBegin->replaceAllUsesWith(Frame);
1173 } else {
1174 CoroBegin->replaceAllUsesWith(CoroBegin->getMem());
1175 }
1176
1177 break;
1178 }
1179 case coro::ABI::Async:
1180 case coro::ABI::Retcon:
1182 CoroBegin->replaceAllUsesWith(PoisonValue::get(CoroBegin->getType()));
1183 break;
1184 }
1185
1186 CoroBegin->eraseFromParent();
1187 Shape.CoroBegin = nullptr;
1188}
1189
1190// SimplifySuspendPoint needs to check that there is no calls between
1191// coro_save and coro_suspend, since any of the calls may potentially resume
1192// the coroutine and if that is the case we cannot eliminate the suspend point.
1194 for (Instruction &I : R) {
1195 // Assume that no intrinsic can resume the coroutine.
1196 if (isa<IntrinsicInst>(I))
1197 continue;
1198
1199 if (isa<CallBase>(I))
1200 return true;
1201 }
1202 return false;
1203}
1204
1205static bool hasCallsInBlocksBetween(BasicBlock *SaveBB, BasicBlock *ResDesBB) {
1208
1209 Set.insert(SaveBB);
1210 Worklist.push_back(ResDesBB);
1211
1212 // Accumulate all blocks between SaveBB and ResDesBB. Because CoroSaveIntr
1213 // returns a token consumed by suspend instruction, all blocks in between
1214 // will have to eventually hit SaveBB when going backwards from ResDesBB.
1215 while (!Worklist.empty()) {
1216 auto *BB = Worklist.pop_back_val();
1217 Set.insert(BB);
1218 for (auto *Pred : predecessors(BB))
1219 if (!Set.contains(Pred))
1220 Worklist.push_back(Pred);
1221 }
1222
1223 // SaveBB and ResDesBB are checked separately in hasCallsBetween.
1224 Set.erase(SaveBB);
1225 Set.erase(ResDesBB);
1226
1227 for (auto *BB : Set)
1228 if (hasCallsInBlockBetween({BB->getFirstNonPHIIt(), BB->end()}))
1229 return true;
1230
1231 return false;
1232}
1233
1234static bool hasCallsBetween(Instruction *Save, Instruction *ResumeOrDestroy) {
1235 auto *SaveBB = Save->getParent();
1236 auto *ResumeOrDestroyBB = ResumeOrDestroy->getParent();
1237 BasicBlock::iterator SaveIt = Save->getIterator();
1238 BasicBlock::iterator ResumeOrDestroyIt = ResumeOrDestroy->getIterator();
1239
1240 if (SaveBB == ResumeOrDestroyBB)
1241 return hasCallsInBlockBetween({std::next(SaveIt), ResumeOrDestroyIt});
1242
1243 // Any calls from Save to the end of the block?
1244 if (hasCallsInBlockBetween({std::next(SaveIt), SaveBB->end()}))
1245 return true;
1246
1247 // Any calls from begging of the block up to ResumeOrDestroy?
1249 {ResumeOrDestroyBB->getFirstNonPHIIt(), ResumeOrDestroyIt}))
1250 return true;
1251
1252 // Any calls in all of the blocks between SaveBB and ResumeOrDestroyBB?
1253 if (hasCallsInBlocksBetween(SaveBB, ResumeOrDestroyBB))
1254 return true;
1255
1256 return false;
1257}
1258
1259// If a SuspendIntrin is preceded by Resume or Destroy, we can eliminate the
1260// suspend point and replace it with nornal control flow.
1262 CoroBeginInst *CoroBegin) {
1263 Instruction *Prev = Suspend->getPrevNode();
1264 if (!Prev) {
1265 auto *Pred = Suspend->getParent()->getSinglePredecessor();
1266 if (!Pred)
1267 return false;
1268 Prev = Pred->getTerminator();
1269 }
1270
1271 CallBase *CB = dyn_cast<CallBase>(Prev);
1272 if (!CB)
1273 return false;
1274
1275 auto *Callee = CB->getCalledOperand()->stripPointerCasts();
1276
1277 // See if the callsite is for resumption or destruction of the coroutine.
1278 auto *SubFn = dyn_cast<CoroSubFnInst>(Callee);
1279 if (!SubFn)
1280 return false;
1281
1282 // Does not refer to the current coroutine, we cannot do anything with it.
1283 if (SubFn->getFrame() != CoroBegin)
1284 return false;
1285
1286 // See if the transformation is safe. Specifically, see if there are any
1287 // calls in between Save and CallInstr. They can potenitally resume the
1288 // coroutine rendering this optimization unsafe.
1289 auto *Save = Suspend->getCoroSave();
1290 if (hasCallsBetween(Save, CB))
1291 return false;
1292
1293 // Replace llvm.coro.suspend with the value that results in resumption over
1294 // the resume or cleanup path.
1295 Suspend->replaceAllUsesWith(SubFn->getRawIndex());
1296 Suspend->eraseFromParent();
1297 Save->eraseFromParent();
1298
1299 // No longer need a call to coro.resume or coro.destroy.
1300 if (auto *Invoke = dyn_cast<InvokeInst>(CB)) {
1301 BranchInst::Create(Invoke->getNormalDest(), Invoke->getIterator());
1302 }
1303
1304 // Grab the CalledValue from CB before erasing the CallInstr.
1305 auto *CalledValue = CB->getCalledOperand();
1306 CB->eraseFromParent();
1307
1308 // If no more users remove it. Usually it is a bitcast of SubFn.
1309 if (CalledValue != SubFn && CalledValue->user_empty())
1310 if (auto *I = dyn_cast<Instruction>(CalledValue))
1311 I->eraseFromParent();
1312
1313 // Now we are good to remove SubFn.
1314 if (SubFn->user_empty())
1315 SubFn->eraseFromParent();
1316
1317 return true;
1318}
1319
1320// Remove suspend points that are simplified.
1322 // Currently, the only simplification we do is switch-lowering-specific.
1323 if (Shape.ABI != coro::ABI::Switch)
1324 return;
1325
1326 auto &S = Shape.CoroSuspends;
1327 size_t I = 0, N = S.size();
1328 if (N == 0)
1329 return;
1330
1331 size_t ChangedFinalIndex = std::numeric_limits<size_t>::max();
1332 while (true) {
1333 auto SI = cast<CoroSuspendInst>(S[I]);
1334 // Leave final.suspend to handleFinalSuspend since it is undefined behavior
1335 // to resume a coroutine suspended at the final suspend point.
1336 if (!SI->isFinal() && simplifySuspendPoint(SI, Shape.CoroBegin)) {
1337 if (--N == I)
1338 break;
1339
1340 std::swap(S[I], S[N]);
1341
1342 if (cast<CoroSuspendInst>(S[I])->isFinal()) {
1344 ChangedFinalIndex = I;
1345 }
1346
1347 continue;
1348 }
1349 if (++I == N)
1350 break;
1351 }
1352 S.resize(N);
1353
1354 // Maintain final.suspend in case final suspend was swapped.
1355 // Due to we requrie the final suspend to be the last element of CoroSuspends.
1356 if (ChangedFinalIndex < N) {
1357 assert(cast<CoroSuspendInst>(S[ChangedFinalIndex])->isFinal());
1358 std::swap(S[ChangedFinalIndex], S.back());
1359 }
1360}
1361
1362namespace {
1363
1364struct SwitchCoroutineSplitter {
1365 static void split(Function &F, coro::Shape &Shape,
1366 SmallVectorImpl<Function *> &Clones,
1367 TargetTransformInfo &TTI) {
1368 assert(Shape.ABI == coro::ABI::Switch);
1369
1370 // Create a resume clone by cloning the body of the original function,
1371 // setting new entry block and replacing coro.suspend an appropriate value
1372 // to force resume or cleanup pass for every suspend point.
1373 createResumeEntryBlock(F, Shape);
1374 auto *ResumeClone = coro::SwitchCloner::createClone(
1375 F, ".resume", Shape, coro::CloneKind::SwitchResume, TTI);
1376 auto *DestroyClone = coro::SwitchCloner::createClone(
1377 F, ".destroy", Shape, coro::CloneKind::SwitchUnwind, TTI);
1378 auto *CleanupClone = coro::SwitchCloner::createClone(
1379 F, ".cleanup", Shape, coro::CloneKind::SwitchCleanup, TTI);
1380
1381 postSplitCleanup(*ResumeClone);
1382 postSplitCleanup(*DestroyClone);
1383 postSplitCleanup(*CleanupClone);
1384
1385 // Store addresses resume/destroy/cleanup functions in the coroutine frame.
1386 updateCoroFrame(Shape, ResumeClone, DestroyClone, CleanupClone);
1387
1388 assert(Clones.empty());
1389 Clones.push_back(ResumeClone);
1390 Clones.push_back(DestroyClone);
1391 Clones.push_back(CleanupClone);
1392
1393 // Create a constant array referring to resume/destroy/clone functions
1394 // pointed by the last argument of @llvm.coro.info, so that CoroElide pass
1395 // can determined correct function to call.
1396 setCoroInfo(F, Shape, Clones);
1397 }
1398
1399 // Create a variant of ramp function that does not perform heap allocation
1400 // for a switch ABI coroutine.
1401 //
1402 // The newly split `.noalloc` ramp function has the following differences:
1403 // - Has one additional frame pointer parameter in lieu of dynamic
1404 // allocation.
1405 // - Suppressed allocations by replacing coro.alloc and coro.free.
1406 static Function *createNoAllocVariant(Function &F, coro::Shape &Shape,
1407 SmallVectorImpl<Function *> &Clones) {
1408 assert(Shape.ABI == coro::ABI::Switch);
1409 auto *OrigFnTy = F.getFunctionType();
1410 auto OldParams = OrigFnTy->params();
1411
1412 SmallVector<Type *> NewParams;
1413 NewParams.reserve(OldParams.size() + 1);
1414 NewParams.append(OldParams.begin(), OldParams.end());
1415 NewParams.push_back(PointerType::getUnqual(Shape.FrameTy->getContext()));
1416
1417 auto *NewFnTy = FunctionType::get(OrigFnTy->getReturnType(), NewParams,
1418 OrigFnTy->isVarArg());
1419 Function *NoAllocF =
1420 Function::Create(NewFnTy, F.getLinkage(), F.getName() + ".noalloc");
1421
1422 ValueToValueMapTy VMap;
1423 unsigned int Idx = 0;
1424 for (const auto &I : F.args()) {
1425 VMap[&I] = NoAllocF->getArg(Idx++);
1426 }
1427 // We just appended the frame pointer as the last argument of the new
1428 // function.
1429 auto FrameIdx = NoAllocF->arg_size() - 1;
1431 CloneFunctionInto(NoAllocF, &F, VMap,
1432 CloneFunctionChangeType::LocalChangesOnly, Returns);
1433
1434 if (Shape.CoroBegin) {
1435 auto *NewCoroBegin =
1437 auto *NewCoroId = cast<CoroIdInst>(NewCoroBegin->getId());
1438 coro::replaceCoroFree(NewCoroId, /*Elide=*/true);
1439 coro::suppressCoroAllocs(NewCoroId);
1440 NewCoroBegin->replaceAllUsesWith(NoAllocF->getArg(FrameIdx));
1441 NewCoroBegin->eraseFromParent();
1442 }
1443
1444 Module *M = F.getParent();
1445 M->getFunctionList().insert(M->end(), NoAllocF);
1446
1447 removeUnreachableBlocks(*NoAllocF);
1448 auto NewAttrs = NoAllocF->getAttributes();
1449 // When we elide allocation, we read these attributes to determine the
1450 // frame size and alignment.
1451 addFramePointerAttrs(NewAttrs, NoAllocF->getContext(), FrameIdx,
1452 Shape.FrameSize, Shape.FrameAlign,
1453 /*NoAlias=*/false);
1454
1455 NoAllocF->setAttributes(NewAttrs);
1456
1457 Clones.push_back(NoAllocF);
1458 // Reset the original function's coro info, make the new noalloc variant
1459 // connected to the original ramp function.
1460 setCoroInfo(F, Shape, Clones);
1461 // After copying, set the linkage to internal linkage. Original function
1462 // may have different linkage, but optimization dependent on this function
1463 // generally relies on LTO.
1465 return NoAllocF;
1466 }
1467
1468private:
1469 // Create an entry block for a resume function with a switch that will jump to
1470 // suspend points.
1471 static void createResumeEntryBlock(Function &F, coro::Shape &Shape) {
1472 LLVMContext &C = F.getContext();
1473
1474 DIBuilder DBuilder(*F.getParent(), /*AllowUnresolved*/ false);
1475 DISubprogram *DIS = F.getSubprogram();
1476 // If there is no DISubprogram for F, it implies the function is compiled
1477 // without debug info. So we also don't generate debug info for the
1478 // suspension points.
1479 bool AddDebugLabels = DIS && DIS->getUnit() &&
1480 (DIS->getUnit()->getEmissionKind() ==
1481 DICompileUnit::DebugEmissionKind::FullDebug);
1482
1483 // resume.entry:
1484 // %index.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32
1485 // 0, i32 2 % index = load i32, i32* %index.addr switch i32 %index, label
1486 // %unreachable [
1487 // i32 0, label %resume.0
1488 // i32 1, label %resume.1
1489 // ...
1490 // ]
1491
1492 auto *NewEntry = BasicBlock::Create(C, "resume.entry", &F);
1493 auto *UnreachBB = BasicBlock::Create(C, "unreachable", &F);
1494
1495 IRBuilder<> Builder(NewEntry);
1496 auto *FramePtr = Shape.FramePtr;
1497 auto *FrameTy = Shape.FrameTy;
1498 auto *GepIndex = Builder.CreateStructGEP(
1499 FrameTy, FramePtr, Shape.getSwitchIndexField(), "index.addr");
1500 auto *Index = Builder.CreateLoad(Shape.getIndexType(), GepIndex, "index");
1501 auto *Switch =
1502 Builder.CreateSwitch(Index, UnreachBB, Shape.CoroSuspends.size());
1504
1505 // Split all coro.suspend calls
1506 size_t SuspendIndex = 0;
1507 for (auto *AnyS : Shape.CoroSuspends) {
1508 auto *S = cast<CoroSuspendInst>(AnyS);
1509 ConstantInt *IndexVal = Shape.getIndex(SuspendIndex);
1510
1511 // Replace CoroSave with a store to Index:
1512 // %index.addr = getelementptr %f.frame... (index field number)
1513 // store i32 %IndexVal, i32* %index.addr1
1514 auto *Save = S->getCoroSave();
1515 Builder.SetInsertPoint(Save);
1516 if (S->isFinal()) {
1517 // The coroutine should be marked done if it reaches the final suspend
1518 // point.
1519 markCoroutineAsDone(Builder, Shape, FramePtr);
1520 } else {
1521 auto *GepIndex = Builder.CreateStructGEP(
1522 FrameTy, FramePtr, Shape.getSwitchIndexField(), "index.addr");
1523 Builder.CreateStore(IndexVal, GepIndex);
1524 }
1525
1527 Save->eraseFromParent();
1528
1529 // Split block before and after coro.suspend and add a jump from an entry
1530 // switch:
1531 //
1532 // whateverBB:
1533 // whatever
1534 // %0 = call i8 @llvm.coro.suspend(token none, i1 false)
1535 // switch i8 %0, label %suspend[i8 0, label %resume
1536 // i8 1, label %cleanup]
1537 // becomes:
1538 //
1539 // whateverBB:
1540 // whatever
1541 // br label %resume.0.landing
1542 //
1543 // resume.0: ; <--- jump from the switch in the resume.entry
1544 // #dbg_label(...) ; <--- artificial label for debuggers
1545 // %0 = tail call i8 @llvm.coro.suspend(token none, i1 false)
1546 // br label %resume.0.landing
1547 //
1548 // resume.0.landing:
1549 // %1 = phi i8[-1, %whateverBB], [%0, %resume.0]
1550 // switch i8 % 1, label %suspend [i8 0, label %resume
1551 // i8 1, label %cleanup]
1552
1553 auto *SuspendBB = S->getParent();
1554 auto *ResumeBB =
1555 SuspendBB->splitBasicBlock(S, "resume." + Twine(SuspendIndex));
1556 auto *LandingBB = ResumeBB->splitBasicBlock(
1557 S->getNextNode(), ResumeBB->getName() + Twine(".landing"));
1558 Switch->addCase(IndexVal, ResumeBB);
1559
1560 cast<BranchInst>(SuspendBB->getTerminator())->setSuccessor(0, LandingBB);
1561 auto *PN = PHINode::Create(Builder.getInt8Ty(), 2, "");
1562 PN->insertBefore(LandingBB->begin());
1563 S->replaceAllUsesWith(PN);
1564 PN->addIncoming(Builder.getInt8(-1), SuspendBB);
1565 PN->addIncoming(S, ResumeBB);
1566
1567 if (AddDebugLabels) {
1568 if (DebugLoc SuspendLoc = S->getDebugLoc()) {
1569 std::string LabelName =
1570 ("__coro_resume_" + Twine(SuspendIndex)).str();
1571 // Take the "inlined at" location recursively, if present. This is
1572 // mandatory as the DILabel insertion checks that the scopes of label
1573 // and the attached location match. This is not the case when the
1574 // suspend location has been inlined due to pointing to the original
1575 // scope.
1576 DILocation *DILoc = SuspendLoc;
1577 while (DILocation *InlinedAt = DILoc->getInlinedAt())
1578 DILoc = InlinedAt;
1579
1580 DILabel *ResumeLabel =
1581 DBuilder.createLabel(DIS, LabelName, DILoc->getFile(),
1582 SuspendLoc.getLine(), SuspendLoc.getCol(),
1583 /*IsArtificial=*/true,
1584 /*CoroSuspendIdx=*/SuspendIndex,
1585 /*AlwaysPreserve=*/false);
1586 DBuilder.insertLabel(ResumeLabel, DILoc, ResumeBB->begin());
1587 }
1588 }
1589
1590 ++SuspendIndex;
1591 }
1592
1593 Builder.SetInsertPoint(UnreachBB);
1594 Builder.CreateUnreachable();
1595 DBuilder.finalize();
1596
1597 Shape.SwitchLowering.ResumeEntryBlock = NewEntry;
1598 }
1599
1600 // Store addresses of Resume/Destroy/Cleanup functions in the coroutine frame.
1601 static void updateCoroFrame(coro::Shape &Shape, Function *ResumeFn,
1602 Function *DestroyFn, Function *CleanupFn) {
1603 IRBuilder<> Builder(&*Shape.getInsertPtAfterFramePtr());
1604
1605 auto *ResumeAddr = Builder.CreateStructGEP(
1607 "resume.addr");
1608 Builder.CreateStore(ResumeFn, ResumeAddr);
1609
1610 Value *DestroyOrCleanupFn = DestroyFn;
1611
1612 CoroIdInst *CoroId = Shape.getSwitchCoroId();
1613 if (CoroAllocInst *CA = CoroId->getCoroAlloc()) {
1614 // If there is a CoroAlloc and it returns false (meaning we elide the
1615 // allocation, use CleanupFn instead of DestroyFn).
1616 DestroyOrCleanupFn = Builder.CreateSelect(CA, DestroyFn, CleanupFn);
1617 }
1618
1619 auto *DestroyAddr = Builder.CreateStructGEP(
1621 "destroy.addr");
1622 Builder.CreateStore(DestroyOrCleanupFn, DestroyAddr);
1623 }
1624
1625 // Create a global constant array containing pointers to functions provided
1626 // and set Info parameter of CoroBegin to point at this constant. Example:
1627 //
1628 // @f.resumers = internal constant [2 x void(%f.frame*)*]
1629 // [void(%f.frame*)* @f.resume, void(%f.frame*)*
1630 // @f.destroy]
1631 // define void @f() {
1632 // ...
1633 // call i8* @llvm.coro.begin(i8* null, i32 0, i8* null,
1634 // i8* bitcast([2 x void(%f.frame*)*] * @f.resumers to
1635 // i8*))
1636 //
1637 // Assumes that all the functions have the same signature.
1638 static void setCoroInfo(Function &F, coro::Shape &Shape,
1640 // This only works under the switch-lowering ABI because coro elision
1641 // only works on the switch-lowering ABI.
1643 assert(!Args.empty());
1644 Function *Part = *Fns.begin();
1645 Module *M = Part->getParent();
1646 auto *ArrTy = ArrayType::get(Part->getType(), Args.size());
1647
1648 auto *ConstVal = ConstantArray::get(ArrTy, Args);
1649 auto *GV = new GlobalVariable(*M, ConstVal->getType(), /*isConstant=*/true,
1650 GlobalVariable::PrivateLinkage, ConstVal,
1651 F.getName() + Twine(".resumers"));
1652
1653 // Update coro.begin instruction to refer to this constant.
1654 LLVMContext &C = F.getContext();
1655 auto *BC = ConstantExpr::getPointerCast(GV, PointerType::getUnqual(C));
1656 Shape.getSwitchCoroId()->setInfo(BC);
1657 }
1658};
1659
1660} // namespace
1661
1664 auto *ResumeIntrinsic = Suspend->getResumeFunction();
1665 auto &Context = Suspend->getParent()->getParent()->getContext();
1666 auto *Int8PtrTy = PointerType::getUnqual(Context);
1667
1668 IRBuilder<> Builder(ResumeIntrinsic);
1669 auto *Val = Builder.CreateBitOrPointerCast(Continuation, Int8PtrTy);
1670 ResumeIntrinsic->replaceAllUsesWith(Val);
1671 ResumeIntrinsic->eraseFromParent();
1673 PoisonValue::get(Int8PtrTy));
1674}
1675
1676/// Coerce the arguments in \p FnArgs according to \p FnTy in \p CallArgs.
1677static void coerceArguments(IRBuilder<> &Builder, FunctionType *FnTy,
1678 ArrayRef<Value *> FnArgs,
1679 SmallVectorImpl<Value *> &CallArgs) {
1680 size_t ArgIdx = 0;
1681 for (auto *paramTy : FnTy->params()) {
1682 assert(ArgIdx < FnArgs.size());
1683 if (paramTy != FnArgs[ArgIdx]->getType())
1684 CallArgs.push_back(
1685 Builder.CreateBitOrPointerCast(FnArgs[ArgIdx], paramTy));
1686 else
1687 CallArgs.push_back(FnArgs[ArgIdx]);
1688 ++ArgIdx;
1689 }
1690}
1691
1695 IRBuilder<> &Builder) {
1696 auto *FnTy = MustTailCallFn->getFunctionType();
1697 // Coerce the arguments, llvm optimizations seem to ignore the types in
1698 // vaarg functions and throws away casts in optimized mode.
1699 SmallVector<Value *, 8> CallArgs;
1700 coerceArguments(Builder, FnTy, Arguments, CallArgs);
1701
1702 auto *TailCall = Builder.CreateCall(FnTy, MustTailCallFn, CallArgs);
1703 // Skip targets which don't support tail call.
1704 if (TTI.supportsTailCallFor(TailCall)) {
1705 TailCall->setTailCallKind(CallInst::TCK_MustTail);
1706 }
1707 TailCall->setDebugLoc(Loc);
1708 TailCall->setCallingConv(MustTailCallFn->getCallingConv());
1709 return TailCall;
1710}
1711
1716 assert(Clones.empty());
1717 // Reset various things that the optimizer might have decided it
1718 // "knows" about the coroutine function due to not seeing a return.
1719 F.removeFnAttr(Attribute::NoReturn);
1720 F.removeRetAttr(Attribute::NoAlias);
1721 F.removeRetAttr(Attribute::NonNull);
1722
1723 auto &Context = F.getContext();
1724 auto *Int8PtrTy = PointerType::getUnqual(Context);
1725
1726 auto *Id = Shape.getAsyncCoroId();
1727 IRBuilder<> Builder(Id);
1728
1729 auto *FramePtr = Id->getStorage();
1730 FramePtr = Builder.CreateBitOrPointerCast(FramePtr, Int8PtrTy);
1731 FramePtr = Builder.CreateConstInBoundsGEP1_32(
1732 Type::getInt8Ty(Context), FramePtr, Shape.AsyncLowering.FrameOffset,
1733 "async.ctx.frameptr");
1734
1735 // Map all uses of llvm.coro.begin to the allocated frame pointer.
1736 {
1737 // Make sure we don't invalidate Shape.FramePtr.
1738 TrackingVH<Value> Handle(Shape.FramePtr);
1739 Shape.CoroBegin->replaceAllUsesWith(FramePtr);
1740 Shape.FramePtr = Handle.getValPtr();
1741 }
1742
1743 // Create all the functions in order after the main function.
1744 auto NextF = std::next(F.getIterator());
1745
1746 // Create a continuation function for each of the suspend points.
1747 Clones.reserve(Shape.CoroSuspends.size());
1748 for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
1749 auto *Suspend = cast<CoroSuspendAsyncInst>(CS);
1750
1751 // Create the clone declaration.
1752 auto ResumeNameSuffix = ".resume.";
1753 auto ProjectionFunctionName =
1754 Suspend->getAsyncContextProjectionFunction()->getName();
1755 bool UseSwiftMangling = false;
1756 if (ProjectionFunctionName == "__swift_async_resume_project_context") {
1757 ResumeNameSuffix = "TQ";
1758 UseSwiftMangling = true;
1759 } else if (ProjectionFunctionName == "__swift_async_resume_get_context") {
1760 ResumeNameSuffix = "TY";
1761 UseSwiftMangling = true;
1762 }
1764 F, Shape,
1765 UseSwiftMangling ? ResumeNameSuffix + Twine(Idx) + "_"
1766 : ResumeNameSuffix + Twine(Idx),
1767 NextF, Suspend);
1768 Clones.push_back(Continuation);
1769
1770 // Insert a branch to a new return block immediately before the suspend
1771 // point.
1772 auto *SuspendBB = Suspend->getParent();
1773 auto *NewSuspendBB = SuspendBB->splitBasicBlock(Suspend);
1774 auto *Branch = cast<BranchInst>(SuspendBB->getTerminator());
1775
1776 // Place it before the first suspend.
1777 auto *ReturnBB =
1778 BasicBlock::Create(F.getContext(), "coro.return", &F, NewSuspendBB);
1779 Branch->setSuccessor(0, ReturnBB);
1780
1781 IRBuilder<> Builder(ReturnBB);
1782
1783 // Insert the call to the tail call function and inline it.
1784 auto *Fn = Suspend->getMustTailCallFunction();
1785 SmallVector<Value *, 8> Args(Suspend->args());
1786 auto FnArgs = ArrayRef<Value *>(Args).drop_front(
1788 auto *TailCall = coro::createMustTailCall(Suspend->getDebugLoc(), Fn, TTI,
1789 FnArgs, Builder);
1790 Builder.CreateRetVoid();
1791 InlineFunctionInfo FnInfo;
1792 (void)InlineFunction(*TailCall, FnInfo);
1793
1794 // Replace the lvm.coro.async.resume intrisic call.
1796 }
1797
1798 assert(Clones.size() == Shape.CoroSuspends.size());
1799
1800 for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
1801 auto *Suspend = CS;
1802 auto *Clone = Clones[Idx];
1803
1804 coro::BaseCloner::createClone(F, "resume." + Twine(Idx), Shape, Clone,
1805 Suspend, TTI);
1806 }
1807}
1808
1813 assert(Clones.empty());
1814
1815 // Reset various things that the optimizer might have decided it
1816 // "knows" about the coroutine function due to not seeing a return.
1817 F.removeFnAttr(Attribute::NoReturn);
1818 F.removeRetAttr(Attribute::NoAlias);
1819 F.removeRetAttr(Attribute::NonNull);
1820
1821 // Allocate the frame.
1822 auto *Id = Shape.getRetconCoroId();
1823 Value *RawFramePtr;
1824 if (Shape.RetconLowering.IsFrameInlineInStorage) {
1825 RawFramePtr = Id->getStorage();
1826 } else {
1827 IRBuilder<> Builder(Id);
1828
1829 // Determine the size of the frame.
1830 const DataLayout &DL = F.getDataLayout();
1831 auto Size = DL.getTypeAllocSize(Shape.FrameTy);
1832
1833 // Allocate. We don't need to update the call graph node because we're
1834 // going to recompute it from scratch after splitting.
1835 // FIXME: pass the required alignment
1836 RawFramePtr = Shape.emitAlloc(Builder, Builder.getInt64(Size), nullptr);
1837 RawFramePtr =
1838 Builder.CreateBitCast(RawFramePtr, Shape.CoroBegin->getType());
1839
1840 // Stash the allocated frame pointer in the continuation storage.
1841 Builder.CreateStore(RawFramePtr, Id->getStorage());
1842 }
1843
1844 // Map all uses of llvm.coro.begin to the allocated frame pointer.
1845 {
1846 // Make sure we don't invalidate Shape.FramePtr.
1847 TrackingVH<Value> Handle(Shape.FramePtr);
1848 Shape.CoroBegin->replaceAllUsesWith(RawFramePtr);
1849 Shape.FramePtr = Handle.getValPtr();
1850 }
1851
1852 // Create a unique return block.
1853 BasicBlock *ReturnBB = nullptr;
1854 PHINode *ContinuationPhi = nullptr;
1855 SmallVector<PHINode *, 4> ReturnPHIs;
1856
1857 // Create all the functions in order after the main function.
1858 auto NextF = std::next(F.getIterator());
1859
1860 // Create a continuation function for each of the suspend points.
1861 Clones.reserve(Shape.CoroSuspends.size());
1862 for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
1863 auto Suspend = cast<CoroSuspendRetconInst>(CS);
1864
1865 // Create the clone declaration.
1867 F, Shape, ".resume." + Twine(Idx), NextF, nullptr);
1868 Clones.push_back(Continuation);
1869
1870 // Insert a branch to the unified return block immediately before
1871 // the suspend point.
1872 auto SuspendBB = Suspend->getParent();
1873 auto NewSuspendBB = SuspendBB->splitBasicBlock(Suspend);
1874 auto Branch = cast<BranchInst>(SuspendBB->getTerminator());
1875
1876 // Create the unified return block.
1877 if (!ReturnBB) {
1878 // Place it before the first suspend.
1879 ReturnBB =
1880 BasicBlock::Create(F.getContext(), "coro.return", &F, NewSuspendBB);
1881 Shape.RetconLowering.ReturnBlock = ReturnBB;
1882
1883 IRBuilder<> Builder(ReturnBB);
1884
1885 // First, the continuation.
1886 ContinuationPhi =
1887 Builder.CreatePHI(Continuation->getType(), Shape.CoroSuspends.size());
1888
1889 // Create PHIs for all other return values.
1890 assert(ReturnPHIs.empty());
1891
1892 // Next, all the directly-yielded values.
1893 for (auto *ResultTy : Shape.getRetconResultTypes())
1894 ReturnPHIs.push_back(
1895 Builder.CreatePHI(ResultTy, Shape.CoroSuspends.size()));
1896
1897 // Build the return value.
1898 auto RetTy = F.getReturnType();
1899
1900 // Cast the continuation value if necessary.
1901 // We can't rely on the types matching up because that type would
1902 // have to be infinite.
1903 auto CastedContinuationTy =
1904 (ReturnPHIs.empty() ? RetTy : RetTy->getStructElementType(0));
1905 auto *CastedContinuation =
1906 Builder.CreateBitCast(ContinuationPhi, CastedContinuationTy);
1907
1908 Value *RetV = CastedContinuation;
1909 if (!ReturnPHIs.empty()) {
1910 auto ValueIdx = 0;
1911 RetV = PoisonValue::get(RetTy);
1912 RetV = Builder.CreateInsertValue(RetV, CastedContinuation, ValueIdx++);
1913
1914 for (auto Phi : ReturnPHIs)
1915 RetV = Builder.CreateInsertValue(RetV, Phi, ValueIdx++);
1916 }
1917
1918 Builder.CreateRet(RetV);
1919 }
1920
1921 // Branch to the return block.
1922 Branch->setSuccessor(0, ReturnBB);
1923 assert(ContinuationPhi);
1924 ContinuationPhi->addIncoming(Continuation, SuspendBB);
1925 for (auto [Phi, VUse] :
1926 llvm::zip_equal(ReturnPHIs, Suspend->value_operands()))
1927 Phi->addIncoming(VUse, SuspendBB);
1928 }
1929
1930 assert(Clones.size() == Shape.CoroSuspends.size());
1931
1932 for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
1933 auto Suspend = CS;
1934 auto Clone = Clones[Idx];
1935
1936 coro::BaseCloner::createClone(F, "resume." + Twine(Idx), Shape, Clone,
1937 Suspend, TTI);
1938 }
1939}
1940
1941namespace {
1942class PrettyStackTraceFunction : public PrettyStackTraceEntry {
1943 Function &F;
1944
1945public:
1946 PrettyStackTraceFunction(Function &F) : F(F) {}
1947 void print(raw_ostream &OS) const override {
1948 OS << "While splitting coroutine ";
1949 F.printAsOperand(OS, /*print type*/ false, F.getParent());
1950 OS << "\n";
1951 }
1952};
1953} // namespace
1954
1955/// Remove calls to llvm.coro.end in the original function.
1957 if (Shape.ABI != coro::ABI::Switch) {
1958 for (auto *End : Shape.CoroEnds) {
1959 replaceCoroEnd(End, Shape, Shape.FramePtr, /*in resume*/ false, nullptr);
1960 }
1961 } else {
1962 for (llvm::AnyCoroEndInst *End : Shape.CoroEnds) {
1963 auto &Context = End->getContext();
1965 End->eraseFromParent();
1966 }
1967 }
1968}
1969
1971 for (auto *U : F.users()) {
1972 if (auto *CB = dyn_cast<CallBase>(U)) {
1973 auto *Caller = CB->getFunction();
1974 if (Caller && Caller->isPresplitCoroutine() &&
1975 CB->hasFnAttr(llvm::Attribute::CoroElideSafe))
1976 return true;
1977 }
1978 }
1979 return false;
1980}
1981
1985 SwitchCoroutineSplitter::split(F, Shape, Clones, TTI);
1986}
1987
1990 bool OptimizeFrame) {
1991 PrettyStackTraceFunction prettyStackTrace(F);
1992
1993 auto &Shape = ABI.Shape;
1994 assert(Shape.CoroBegin);
1995
1996 lowerAwaitSuspends(F, Shape);
1997
1998 simplifySuspendPoints(Shape);
1999
2000 normalizeCoroutine(F, Shape, TTI);
2001 ABI.buildCoroutineFrame(OptimizeFrame);
2003
2004 bool isNoSuspendCoroutine = Shape.CoroSuspends.empty();
2005
2006 bool shouldCreateNoAllocVariant =
2007 !isNoSuspendCoroutine && Shape.ABI == coro::ABI::Switch &&
2008 hasSafeElideCaller(F) && !F.hasFnAttribute(llvm::Attribute::NoInline);
2009
2010 // If there are no suspend points, no split required, just remove
2011 // the allocation and deallocation blocks, they are not needed.
2012 if (isNoSuspendCoroutine) {
2014 } else {
2015 ABI.splitCoroutine(F, Shape, Clones, TTI);
2016 }
2017
2018 // Replace all the swifterror operations in the original function.
2019 // This invalidates SwiftErrorOps in the Shape.
2020 replaceSwiftErrorOps(F, Shape, nullptr);
2021
2022 // Salvage debug intrinsics that point into the coroutine frame in the
2023 // original function. The Cloner has already salvaged debug info in the new
2024 // coroutine funclets.
2026 auto DbgVariableRecords = collectDbgVariableRecords(F);
2027 for (DbgVariableRecord *DVR : DbgVariableRecords)
2028 coro::salvageDebugInfo(ArgToAllocaMap, *DVR, false /*UseEntryValue*/);
2029
2031
2032 if (shouldCreateNoAllocVariant)
2033 SwitchCoroutineSplitter::createNoAllocVariant(F, Shape, Clones);
2034}
2035
2037 LazyCallGraph::Node &N, const coro::Shape &Shape,
2041
2042 auto *CurrentSCC = &C;
2043 if (!Clones.empty()) {
2044 switch (Shape.ABI) {
2045 case coro::ABI::Switch:
2046 // Each clone in the Switch lowering is independent of the other clones.
2047 // Let the LazyCallGraph know about each one separately.
2048 for (Function *Clone : Clones)
2049 CG.addSplitFunction(N.getFunction(), *Clone);
2050 break;
2051 case coro::ABI::Async:
2052 case coro::ABI::Retcon:
2054 // Each clone in the Async/Retcon lowering references of the other clones.
2055 // Let the LazyCallGraph know about all of them at once.
2056 if (!Clones.empty())
2057 CG.addSplitRefRecursiveFunctions(N.getFunction(), Clones);
2058 break;
2059 }
2060
2061 // Let the CGSCC infra handle the changes to the original function.
2062 CurrentSCC = &updateCGAndAnalysisManagerForCGSCCPass(CG, *CurrentSCC, N, AM,
2063 UR, FAM);
2064 }
2065
2066 // Do some cleanup and let the CGSCC infra see if we've cleaned up any edges
2067 // to the split functions.
2068 postSplitCleanup(N.getFunction());
2069 CurrentSCC = &updateCGAndAnalysisManagerForFunctionPass(CG, *CurrentSCC, N,
2070 AM, UR, FAM);
2071 return *CurrentSCC;
2072}
2073
2074/// Replace a call to llvm.coro.prepare.retcon.
2075static void replacePrepare(CallInst *Prepare, LazyCallGraph &CG,
2077 auto CastFn = Prepare->getArgOperand(0); // as an i8*
2078 auto Fn = CastFn->stripPointerCasts(); // as its original type
2079
2080 // Attempt to peephole this pattern:
2081 // %0 = bitcast [[TYPE]] @some_function to i8*
2082 // %1 = call @llvm.coro.prepare.retcon(i8* %0)
2083 // %2 = bitcast %1 to [[TYPE]]
2084 // ==>
2085 // %2 = @some_function
2086 for (Use &U : llvm::make_early_inc_range(Prepare->uses())) {
2087 // Look for bitcasts back to the original function type.
2088 auto *Cast = dyn_cast<BitCastInst>(U.getUser());
2089 if (!Cast || Cast->getType() != Fn->getType())
2090 continue;
2091
2092 // Replace and remove the cast.
2093 Cast->replaceAllUsesWith(Fn);
2094 Cast->eraseFromParent();
2095 }
2096
2097 // Replace any remaining uses with the function as an i8*.
2098 // This can never directly be a callee, so we don't need to update CG.
2099 Prepare->replaceAllUsesWith(CastFn);
2100 Prepare->eraseFromParent();
2101
2102 // Kill dead bitcasts.
2103 while (auto *Cast = dyn_cast<BitCastInst>(CastFn)) {
2104 if (!Cast->use_empty())
2105 break;
2106 CastFn = Cast->getOperand(0);
2107 Cast->eraseFromParent();
2108 }
2109}
2110
2111static bool replaceAllPrepares(Function *PrepareFn, LazyCallGraph &CG,
2113 bool Changed = false;
2114 for (Use &P : llvm::make_early_inc_range(PrepareFn->uses())) {
2115 // Intrinsics can only be used in calls.
2116 auto *Prepare = cast<CallInst>(P.getUser());
2117 replacePrepare(Prepare, CG, C);
2118 Changed = true;
2119 }
2120
2121 return Changed;
2122}
2123
2124static void addPrepareFunction(const Module &M,
2126 StringRef Name) {
2127 auto *PrepareFn = M.getFunction(Name);
2128 if (PrepareFn && !PrepareFn->use_empty())
2129 Fns.push_back(PrepareFn);
2130}
2131
2132static std::unique_ptr<coro::BaseABI>
2134 std::function<bool(Instruction &)> IsMatCallback,
2135 const SmallVector<CoroSplitPass::BaseABITy> GenCustomABIs) {
2136 if (S.CoroBegin->hasCustomABI()) {
2137 unsigned CustomABI = S.CoroBegin->getCustomABI();
2138 if (CustomABI >= GenCustomABIs.size())
2139 llvm_unreachable("Custom ABI not found amoung those specified");
2140 return GenCustomABIs[CustomABI](F, S);
2141 }
2142
2143 switch (S.ABI) {
2144 case coro::ABI::Switch:
2145 return std::make_unique<coro::SwitchABI>(F, S, IsMatCallback);
2146 case coro::ABI::Async:
2147 return std::make_unique<coro::AsyncABI>(F, S, IsMatCallback);
2148 case coro::ABI::Retcon:
2149 return std::make_unique<coro::AnyRetconABI>(F, S, IsMatCallback);
2151 return std::make_unique<coro::AnyRetconABI>(F, S, IsMatCallback);
2152 }
2153 llvm_unreachable("Unknown ABI");
2154}
2155
2157 : CreateAndInitABI([](Function &F, coro::Shape &S) {
2158 std::unique_ptr<coro::BaseABI> ABI =
2160 ABI->init();
2161 return ABI;
2162 }),
2163 OptimizeFrame(OptimizeFrame) {}
2164
2167 : CreateAndInitABI([=](Function &F, coro::Shape &S) {
2168 std::unique_ptr<coro::BaseABI> ABI =
2170 ABI->init();
2171 return ABI;
2172 }),
2173 OptimizeFrame(OptimizeFrame) {}
2174
2175// For back compatibility, constructor takes a materializable callback and
2176// creates a generator for an ABI with a modified materializable callback.
2177CoroSplitPass::CoroSplitPass(std::function<bool(Instruction &)> IsMatCallback,
2178 bool OptimizeFrame)
2179 : CreateAndInitABI([=](Function &F, coro::Shape &S) {
2180 std::unique_ptr<coro::BaseABI> ABI =
2181 CreateNewABI(F, S, IsMatCallback, {});
2182 ABI->init();
2183 return ABI;
2184 }),
2185 OptimizeFrame(OptimizeFrame) {}
2186
2187// For back compatibility, constructor takes a materializable callback and
2188// creates a generator for an ABI with a modified materializable callback.
2190 std::function<bool(Instruction &)> IsMatCallback,
2192 : CreateAndInitABI([=](Function &F, coro::Shape &S) {
2193 std::unique_ptr<coro::BaseABI> ABI =
2194 CreateNewABI(F, S, IsMatCallback, GenCustomABIs);
2195 ABI->init();
2196 return ABI;
2197 }),
2198 OptimizeFrame(OptimizeFrame) {}
2199
2203 // NB: One invariant of a valid LazyCallGraph::SCC is that it must contain a
2204 // non-zero number of nodes, so we assume that here and grab the first
2205 // node's function's module.
2206 Module &M = *C.begin()->getFunction().getParent();
2207 auto &FAM =
2208 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
2209
2210 // Check for uses of llvm.coro.prepare.retcon/async.
2211 SmallVector<Function *, 2> PrepareFns;
2212 addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.retcon");
2213 addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.async");
2214
2215 // Find coroutines for processing.
2217 for (LazyCallGraph::Node &N : C)
2218 if (N.getFunction().isPresplitCoroutine())
2219 Coroutines.push_back(&N);
2220
2221 if (Coroutines.empty() && PrepareFns.empty())
2222 return PreservedAnalyses::all();
2223
2224 auto *CurrentSCC = &C;
2225 // Split all the coroutines.
2226 for (LazyCallGraph::Node *N : Coroutines) {
2227 Function &F = N->getFunction();
2228 LLVM_DEBUG(dbgs() << "CoroSplit: Processing coroutine '" << F.getName()
2229 << "\n");
2230
2231 // The suspend-crossing algorithm in buildCoroutineFrame gets tripped up
2232 // by unreachable blocks, so remove them as a first pass. Remove the
2233 // unreachable blocks before collecting intrinsics into Shape.
2235
2236 coro::Shape Shape(F);
2237 if (!Shape.CoroBegin)
2238 continue;
2239
2240 F.setSplittedCoroutine();
2241
2242 std::unique_ptr<coro::BaseABI> ABI = CreateAndInitABI(F, Shape);
2243
2245 auto &TTI = FAM.getResult<TargetIRAnalysis>(F);
2246 doSplitCoroutine(F, Clones, *ABI, TTI, OptimizeFrame);
2248 *N, Shape, Clones, *CurrentSCC, CG, AM, UR, FAM);
2249
2250 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
2251 ORE.emit([&]() {
2252 return OptimizationRemark(DEBUG_TYPE, "CoroSplit", &F)
2253 << "Split '" << ore::NV("function", F.getName())
2254 << "' (frame_size=" << ore::NV("frame_size", Shape.FrameSize)
2255 << ", align=" << ore::NV("align", Shape.FrameAlign.value()) << ")";
2256 });
2257
2258 if (!Shape.CoroSuspends.empty()) {
2259 // Run the CGSCC pipeline on the original and newly split functions.
2260 UR.CWorklist.insert(CurrentSCC);
2261 for (Function *Clone : Clones)
2262 UR.CWorklist.insert(CG.lookupSCC(CG.get(*Clone)));
2263 } else if (Shape.ABI == coro::ABI::Async) {
2264 // Reprocess the function to inline the tail called return function of
2265 // coro.async.end.
2266 UR.CWorklist.insert(&C);
2267 }
2268 }
2269
2270 for (auto *PrepareFn : PrepareFns) {
2271 replaceAllPrepares(PrepareFn, CG, *CurrentSCC);
2272 }
2273
2274 return PreservedAnalyses::none();
2275}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
AMDGPU Lower Kernel Arguments
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file provides interfaces used to manipulate a call graph, regardless if it is a "old style" Call...
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static void addSwiftSelfAttrs(AttributeList &Attrs, LLVMContext &Context, unsigned ParamIndex)
static bool hasCallsBetween(Instruction *Save, Instruction *ResumeOrDestroy)
static LazyCallGraph::SCC & updateCallGraphAfterCoroutineSplit(LazyCallGraph::Node &N, const coro::Shape &Shape, const SmallVectorImpl< Function * > &Clones, LazyCallGraph::SCC &C, LazyCallGraph &CG, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, FunctionAnalysisManager &FAM)
static void replaceSwiftErrorOps(Function &F, coro::Shape &Shape, ValueToValueMapTy *VMap)
static void addAsyncContextAttrs(AttributeList &Attrs, LLVMContext &Context, unsigned ParamIndex)
static void maybeFreeRetconStorage(IRBuilder<> &Builder, const coro::Shape &Shape, Value *FramePtr, CallGraph *CG)
static bool hasCallsInBlocksBetween(BasicBlock *SaveBB, BasicBlock *ResDesBB)
static Function * createCloneDeclaration(Function &OrigF, coro::Shape &Shape, const Twine &Suffix, Module::iterator InsertBefore, AnyCoroSuspendInst *ActiveSuspend)
static FunctionType * getFunctionTypeFromAsyncSuspend(AnyCoroSuspendInst *Suspend)
static void updateScopeLine(Instruction *ActiveSuspend, DISubprogram &SPToUpdate)
Adjust the scope line of the funclet to the first line number after the suspend point.
static void addPrepareFunction(const Module &M, SmallVectorImpl< Function * > &Fns, StringRef Name)
static SmallVector< DbgVariableRecord * > collectDbgVariableRecords(Function &F)
Returns all debug records in F.
static void simplifySuspendPoints(coro::Shape &Shape)
static void addFramePointerAttrs(AttributeList &Attrs, LLVMContext &Context, unsigned ParamIndex, uint64_t Size, Align Alignment, bool NoAlias)
static bool hasSafeElideCaller(Function &F)
static bool replaceAllPrepares(Function *PrepareFn, LazyCallGraph &CG, LazyCallGraph::SCC &C)
static void replaceFallthroughCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG)
Replace a non-unwind call to llvm.coro.end.
static void replaceFrameSizeAndAlignment(coro::Shape &Shape)
static std::unique_ptr< coro::BaseABI > CreateNewABI(Function &F, coro::Shape &S, std::function< bool(Instruction &)> IsMatCallback, const SmallVector< CoroSplitPass::BaseABITy > GenCustomABIs)
static bool replaceCoroEndAsync(AnyCoroEndInst *End)
Replace an llvm.coro.end.async.
static void doSplitCoroutine(Function &F, SmallVectorImpl< Function * > &Clones, coro::BaseABI &ABI, TargetTransformInfo &TTI, bool OptimizeFrame)
static bool hasCallsInBlockBetween(iterator_range< BasicBlock::iterator > R)
static void replaceUnwindCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG)
Replace an unwind call to llvm.coro.end.
static bool simplifySuspendPoint(CoroSuspendInst *Suspend, CoroBeginInst *CoroBegin)
static void 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 replaceCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG)
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 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 TypeSize getFrameSizeForShape(coro::Shape &Shape)
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:55
#define I(x, y, z)
Definition MD5.cpp:58
Machine Check Debug Module
#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:119
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:686
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:41
size_t size() const
size - Get the array size.
Definition ArrayRef.h:147
iterator begin() const
Definition ArrayRef.h:135
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator end()
Definition BasicBlock.h:472
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
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
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:641
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:449
bool hasCustomABI() const
Definition CoroInstr.h:457
int getCustomABI() const
Definition CoroInstr.h:461
void setInfo(Constant *C)
Definition CoroInstr.h:215
This represents the llvm.coro.size instruction.
Definition CoroInstr.h:629
This represents the llvm.coro.suspend.async instruction.
Definition CoroInstr.h:563
CoroAsyncResumeInst * getResumeFunction() const
Definition CoroInstr.h:584
This represents the llvm.coro.suspend instruction.
Definition CoroInstr.h:531
CoroSaveInst * getCoroSave() const
Definition CoroInstr.h:535
DIFile * getFile() const
Subprogram description. Uses SubclassData1.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:63
Record of a variable value-assignment, aka a non instruction representation of the dbg....
A debug info location.
Definition DebugLoc.h:124
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:165
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:166
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition Function.h:209
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition Function.h:244
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:270
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:352
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
Definition Function.h:355
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:359
size_t arg_size() const
Definition Function.h:899
Argument * getArg(unsigned i) const
Definition Function.h:884
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:511
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2780
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:1316
A single uniqued string.
Definition Metadata.h:720
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Definition Metadata.cpp:607
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
LLVM_ABI Type * getTypeAtIndex(const Value *V) const
Given an index value into the type, return the type of the element.
Definition Type.cpp:719
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
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:281
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:295
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:128
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:237
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:546
iterator_range< user_iterator > users()
Definition Value.h:426
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:701
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.cpp:1101
iterator_range< use_iterator > uses()
Definition Value.h:380
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:58
Value * deriveNewFramePointer()
Derive the value of the new frame pointer.
TargetTransformInfo & TTI
Definition CoroCloner.h:50
coro::Shape & Shape
Definition CoroCloner.h:47
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:84
ValueToValueMapTy VMap
Definition CoroCloner.h:52
const Twine & Suffix
Definition CoroCloner.h:46
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:134
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:359
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:34
@ Continuation
An individual continuation function.
Definition CoroCloner.h:37
void salvageDebugInfo(SmallDenseMap< Argument *, AllocaInst *, 4 > &ArgToAllocaMap, DbgVariableRecord &DVR, bool UseEntryValue)
Attempts to rewrite the location operand of debug records in terms of the coroutine frame pointer,...
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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:689
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:1720
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:853
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:2474
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
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:646
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:682
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:759
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:167
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:548
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:2513
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:565
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:2883
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:853
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:85
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:60
SmallVector< CoroAwaitSuspendInst *, 4 > CoroAwaitSuspends
Definition CoroShape.h:59
AsyncLoweringStorage AsyncLowering
Definition CoroShape.h:155
FunctionType * getResumeFunctionType() const
Definition CoroShape.h:193
IntegerType * getIndexType() const
Definition CoroShape.h:178
StructType * FrameTy
Definition CoroShape.h:114
CoroIdInst * getSwitchCoroId() const
Definition CoroShape.h:158
SmallVector< CoroSizeInst *, 2 > CoroSizes
Definition CoroShape.h:56
SmallVector< AnyCoroSuspendInst *, 4 > CoroSuspends
Definition CoroShape.h:58
uint64_t FrameSize
Definition CoroShape.h:116
ConstantInt * getIndex(uint64_t Value) const
Definition CoroShape.h:183
SwitchLoweringStorage SwitchLowering
Definition CoroShape.h:153
CoroBeginInst * CoroBegin
Definition CoroShape.h:54
BasicBlock::iterator getInsertPtAfterFramePtr() const
Definition CoroShape.h:250
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:154
SmallVector< CoroAlignInst *, 2 > CoroAligns
Definition CoroShape.h:57
SmallVector< AnyCoroEndInst *, 4 > CoroEnds
Definition CoroShape.h:55
SmallVector< CallInst *, 2 > SwiftErrorOps
Definition CoroShape.h:63
unsigned getSwitchIndexField() const
Definition CoroShape.h:173