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