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