Thanks to visit codestin.com
Credit goes to llvm.org

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