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