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 auto *Offset = ConstantInt::get(Type::getInt64Ty(FramePtr->getContext()),
361 return Builder.CreateInBoundsPtrAdd(FramePtr, Offset, "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().getFirstNonPHIOrDbg());
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()->getFirstNonPHIOrDbg();
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 &Context = Builder.getContext();
858 auto *FramePtrAddr = Builder.CreateInBoundsPtrAdd(
859 CallerContext,
860 ConstantInt::get(Type::getInt64Ty(Context),
861 Shape.AsyncLowering.FrameOffset),
862 "async.ctx.frameptr");
863 // Inline the projection function.
865 auto InlineRes = InlineFunction(*CallerContext, InlineInfo);
866 assert(InlineRes.isSuccess());
867 (void)InlineRes;
868 return FramePtrAddr;
869 }
870 // In continuation-lowering, the argument is the opaque storage.
873 Argument *NewStorage = &*NewF->arg_begin();
874 auto FramePtrTy = PointerType::getUnqual(Shape.FramePtr->getContext());
875
876 // If the storage is inline, just bitcast to the storage to the frame type.
877 if (Shape.RetconLowering.IsFrameInlineInStorage)
878 return NewStorage;
879
880 // Otherwise, load the real frame from the opaque storage.
881 return Builder.CreateLoad(FramePtrTy, NewStorage);
882 }
883 }
884 llvm_unreachable("bad ABI");
885}
886
887/// Adjust the scope line of the funclet to the first line number after the
888/// suspend point. This avoids a jump in the line table from the function
889/// declaration (where prologue instructions are attributed to) to the suspend
890/// point.
891/// Only adjust the scope line when the files are the same.
892/// If no candidate line number is found, fallback to the line of ActiveSuspend.
893static void updateScopeLine(Instruction *ActiveSuspend,
894 DISubprogram &SPToUpdate) {
895 if (!ActiveSuspend)
896 return;
897
899 if (!DL || SPToUpdate.getFile() != DL->getFile())
900 DL = ActiveSuspend->getDebugLoc();
901 if (DL && SPToUpdate.getFile() == DL->getFile())
902 SPToUpdate.setScopeLine(DL.getLine());
903}
904
905static void addFramePointerAttrs(AttributeList &Attrs, LLVMContext &Context,
906 unsigned ParamIndex, uint64_t Size,
907 Align Alignment, bool NoAlias) {
908 AttrBuilder ParamAttrs(Context);
909 ParamAttrs.addAttribute(Attribute::NonNull);
910 ParamAttrs.addAttribute(Attribute::NoUndef);
911
912 if (NoAlias)
913 ParamAttrs.addAttribute(Attribute::NoAlias);
914
915 ParamAttrs.addAlignmentAttr(Alignment);
916 ParamAttrs.addDereferenceableAttr(Size);
917 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs);
918}
919
920static void addAsyncContextAttrs(AttributeList &Attrs, LLVMContext &Context,
921 unsigned ParamIndex) {
922 AttrBuilder ParamAttrs(Context);
923 ParamAttrs.addAttribute(Attribute::SwiftAsync);
924 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs);
925}
926
927static void addSwiftSelfAttrs(AttributeList &Attrs, LLVMContext &Context,
928 unsigned ParamIndex) {
929 AttrBuilder ParamAttrs(Context);
930 ParamAttrs.addAttribute(Attribute::SwiftSelf);
931 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs);
932}
933
934/// Clone the body of the original function into a resume function of
935/// some sort.
937 assert(NewF);
938
939 // Replace all args with dummy instructions. If an argument is the old frame
940 // pointer, the dummy will be replaced by the new frame pointer once it is
941 // computed below. Uses of all other arguments should have already been
942 // rewritten by buildCoroutineFrame() to use loads/stores on the coroutine
943 // frame.
945 for (Argument &A : OrigF.args()) {
946 DummyArgs.push_back(new FreezeInst(PoisonValue::get(A.getType())));
947 VMap[&A] = DummyArgs.back();
948 }
949
951
952 // Ignore attempts to change certain attributes of the function.
953 // TODO: maybe there should be a way to suppress this during cloning?
954 auto savedVisibility = NewF->getVisibility();
955 auto savedUnnamedAddr = NewF->getUnnamedAddr();
956 auto savedDLLStorageClass = NewF->getDLLStorageClass();
957
958 // NewF's linkage (which CloneFunctionInto does *not* change) might not
959 // be compatible with the visibility of OrigF (which it *does* change),
960 // so protect against that.
961 auto savedLinkage = NewF->getLinkage();
963
966
967 auto &Context = NewF->getContext();
968
969 if (DISubprogram *SP = NewF->getSubprogram()) {
970 assert(SP != OrigF.getSubprogram() && SP->isDistinct());
972
973 // Update the linkage name and the function name to reflect the modified
974 // name.
975 MDString *NewLinkageName = MDString::get(Context, NewF->getName());
976 SP->replaceLinkageName(NewLinkageName);
977 if (DISubprogram *Decl = SP->getDeclaration()) {
978 TempDISubprogram NewDecl = Decl->clone();
979 NewDecl->replaceLinkageName(NewLinkageName);
980 SP->replaceDeclaration(MDNode::replaceWithUniqued(std::move(NewDecl)));
981 }
982 }
983
984 NewF->setLinkage(savedLinkage);
985 NewF->setVisibility(savedVisibility);
986 NewF->setUnnamedAddr(savedUnnamedAddr);
987 NewF->setDLLStorageClass(savedDLLStorageClass);
988 // The function sanitizer metadata needs to match the signature of the
989 // function it is being attached to. However this does not hold for split
990 // functions here. Thus remove the metadata for split functions.
991 if (Shape.ABI == coro::ABI::Switch &&
992 NewF->hasMetadata(LLVMContext::MD_func_sanitize))
993 NewF->eraseMetadata(LLVMContext::MD_func_sanitize);
994
995 // Replace the attributes of the new function:
996 auto OrigAttrs = NewF->getAttributes();
997 auto NewAttrs = AttributeList();
998
999 switch (Shape.ABI) {
1000 case coro::ABI::Switch:
1001 // Bootstrap attributes by copying function attributes from the
1002 // original function. This should include optimization settings and so on.
1003 NewAttrs = NewAttrs.addFnAttributes(
1004 Context, AttrBuilder(Context, OrigAttrs.getFnAttrs()));
1005
1006 addFramePointerAttrs(NewAttrs, Context, 0, Shape.FrameSize,
1007 Shape.FrameAlign, /*NoAlias=*/false);
1008 break;
1009 case coro::ABI::Async: {
1010 auto *ActiveAsyncSuspend = cast<CoroSuspendAsyncInst>(ActiveSuspend);
1011 if (OrigF.hasParamAttribute(Shape.AsyncLowering.ContextArgNo,
1012 Attribute::SwiftAsync)) {
1013 uint32_t ArgAttributeIndices =
1014 ActiveAsyncSuspend->getStorageArgumentIndex();
1015 auto ContextArgIndex = ArgAttributeIndices & 0xff;
1016 addAsyncContextAttrs(NewAttrs, Context, ContextArgIndex);
1017
1018 // `swiftasync` must preceed `swiftself` so 0 is not a valid index for
1019 // `swiftself`.
1020 auto SwiftSelfIndex = ArgAttributeIndices >> 8;
1021 if (SwiftSelfIndex)
1022 addSwiftSelfAttrs(NewAttrs, Context, SwiftSelfIndex);
1023 }
1024
1025 // Transfer the original function's attributes.
1026 auto FnAttrs = OrigF.getAttributes().getFnAttrs();
1027 NewAttrs = NewAttrs.addFnAttributes(Context, AttrBuilder(Context, FnAttrs));
1028 break;
1029 }
1030 case coro::ABI::Retcon:
1032 // If we have a continuation prototype, just use its attributes,
1033 // full-stop.
1034 NewAttrs = Shape.RetconLowering.ResumePrototype->getAttributes();
1035
1036 /// FIXME: Is it really good to add the NoAlias attribute?
1037 addFramePointerAttrs(NewAttrs, Context, 0,
1038 Shape.getRetconCoroId()->getStorageSize(),
1039 Shape.getRetconCoroId()->getStorageAlignment(),
1040 /*NoAlias=*/true);
1041
1042 break;
1043 }
1044
1045 switch (Shape.ABI) {
1046 // In these ABIs, the cloned functions always return 'void', and the
1047 // existing return sites are meaningless. Note that for unique
1048 // continuations, this includes the returns associated with suspends;
1049 // this is fine because we can't suspend twice.
1050 case coro::ABI::Switch:
1052 // Remove old returns.
1053 for (ReturnInst *Return : Returns)
1054 changeToUnreachable(Return);
1055 break;
1056
1057 // With multi-suspend continuations, we'll already have eliminated the
1058 // original returns and inserted returns before all the suspend points,
1059 // so we want to leave any returns in place.
1060 case coro::ABI::Retcon:
1061 break;
1062 // Async lowering will insert musttail call functions at all suspend points
1063 // followed by a return.
1064 // Don't change returns to unreachable because that will trip up the verifier.
1065 // These returns should be unreachable from the clone.
1066 case coro::ABI::Async:
1067 break;
1068 }
1069
1070 NewF->setAttributes(NewAttrs);
1071 NewF->setCallingConv(Shape.getResumeFunctionCC());
1072
1073 // Set up the new entry block.
1075
1076 // Turn symmetric transfers into musttail calls.
1077 for (CallInst *ResumeCall : Shape.SymmetricTransfers) {
1078 ResumeCall = cast<CallInst>(VMap[ResumeCall]);
1079 if (TTI.supportsTailCallFor(ResumeCall)) {
1080 // FIXME: Could we support symmetric transfer effectively without
1081 // musttail?
1082 ResumeCall->setTailCallKind(CallInst::TCK_MustTail);
1083 }
1084
1085 // Put a 'ret void' after the call, and split any remaining instructions to
1086 // an unreachable block.
1087 BasicBlock *BB = ResumeCall->getParent();
1088 BB->splitBasicBlock(ResumeCall->getNextNode());
1089 Builder.SetInsertPoint(BB->getTerminator());
1090 Builder.CreateRetVoid();
1092 }
1093
1094 Builder.SetInsertPoint(&NewF->getEntryBlock().front());
1096
1097 // Remap frame pointer.
1098 Value *OldFramePtr = VMap[Shape.FramePtr];
1099 NewFramePtr->takeName(OldFramePtr);
1100 OldFramePtr->replaceAllUsesWith(NewFramePtr);
1101
1102 // Remap vFrame pointer.
1103 auto *NewVFrame = Builder.CreateBitCast(
1104 NewFramePtr, PointerType::getUnqual(Builder.getContext()), "vFrame");
1105 Value *OldVFrame = cast<Value>(VMap[Shape.CoroBegin]);
1106 if (OldVFrame != NewVFrame)
1107 OldVFrame->replaceAllUsesWith(NewVFrame);
1108
1109 // All uses of the arguments should have been resolved by this point,
1110 // so we can safely remove the dummy values.
1111 for (Instruction *DummyArg : DummyArgs) {
1112 DummyArg->replaceAllUsesWith(PoisonValue::get(DummyArg->getType()));
1113 DummyArg->deleteValue();
1114 }
1115
1116 switch (Shape.ABI) {
1117 case coro::ABI::Switch:
1118 // Rewrite final suspend handling as it is not done via switch (allows to
1119 // remove final case from the switch, since it is undefined behavior to
1120 // resume the coroutine suspended at the final suspend point.
1121 if (Shape.SwitchLowering.HasFinalSuspend)
1123 break;
1124 case coro::ABI::Async:
1125 case coro::ABI::Retcon:
1127 // Replace uses of the active suspend with the corresponding
1128 // continuation-function arguments.
1129 assert(ActiveSuspend != nullptr &&
1130 "no active suspend when lowering a continuation-style coroutine");
1132 break;
1133 }
1134
1135 // Handle suspends.
1137
1138 // Handle swifterror.
1140
1141 // Remove coro.end intrinsics.
1143
1145
1146 // Salvage debug info that points into the coroutine frame.
1148}
1149
1151 // Create a new function matching the original type
1152 NewF = createCloneDeclaration(OrigF, Shape, Suffix, OrigF.getParent()->end(),
1154
1155 // Clone the function
1157
1158 // Override EntryCount for the cloned resume function with the true sum of
1159 // all suspension points profile counts.
1160 if (FKind == coro::CloneKind::SwitchResume && OrigF.hasProfileData() &&
1161 Shape.ResumeEntryCount.has_value()) {
1162 NewF->setEntryCount(Shape.ResumeEntryCount.value());
1163 }
1164
1165 // Replacing coro.free with 'null' in cleanup to suppress deallocation code.
1168}
1169
1171 assert(Shape.ABI == coro::ABI::Async);
1172
1173 auto *FuncPtrStruct = cast<ConstantStruct>(
1175 auto *OrigRelativeFunOffset = FuncPtrStruct->getOperand(0);
1176 auto *OrigContextSize = FuncPtrStruct->getOperand(1);
1177 auto *NewContextSize = ConstantInt::get(OrigContextSize->getType(),
1179 auto *NewFuncPtrStruct = ConstantStruct::get(
1180 FuncPtrStruct->getType(), OrigRelativeFunOffset, NewContextSize);
1181
1182 Shape.AsyncLowering.AsyncFuncPointer->setInitializer(NewFuncPtrStruct);
1183}
1184
1186 if (Shape.ABI == coro::ABI::Async)
1188
1189 for (CoroAlignInst *CA : Shape.CoroAligns) {
1191 ConstantInt::get(CA->getType(), Shape.FrameAlign.value()));
1192 CA->eraseFromParent();
1193 }
1194
1195 if (Shape.CoroSizes.empty())
1196 return;
1197
1198 // In the same function all coro.sizes should have the same result type.
1199 auto *SizeIntrin = Shape.CoroSizes.back();
1200 auto *SizeConstant = ConstantInt::get(SizeIntrin->getType(),
1202
1203 for (CoroSizeInst *CS : Shape.CoroSizes) {
1204 CS->replaceAllUsesWith(SizeConstant);
1205 CS->eraseFromParent();
1206 }
1207}
1208
1211
1212#ifndef NDEBUG
1213 // For now, we do a mandatory verification step because we don't
1214 // entirely trust this pass. Note that we don't want to add a verifier
1215 // pass to FPM below because it will also verify all the global data.
1216 if (verifyFunction(F, &errs()))
1217 report_fatal_error("Broken function");
1218#endif
1219}
1220
1221// Coroutine has no suspend points. Remove heap allocation for the coroutine
1222// frame if possible.
1224 auto *CoroBegin = Shape.CoroBegin;
1225 switch (Shape.ABI) {
1226 case coro::ABI::Switch: {
1227 if (auto *AllocInst = Shape.getSwitchCoroId()->getCoroAlloc()) {
1228 coro::elideCoroFree(CoroBegin);
1229
1230 IRBuilder<> Builder(AllocInst);
1231 // Create an alloca for a byte array of the frame size
1232 auto *FrameTy = ArrayType::get(Type::getInt8Ty(Builder.getContext()),
1233 Shape.FrameSize);
1234 auto *Frame = Builder.CreateAlloca(
1235 FrameTy, nullptr, AllocInst->getFunction()->getName() + ".Frame");
1236 Frame->setAlignment(Shape.FrameAlign);
1237 AllocInst->replaceAllUsesWith(Builder.getFalse());
1238 AllocInst->eraseFromParent();
1239 CoroBegin->replaceAllUsesWith(Frame);
1240 } else {
1241 CoroBegin->replaceAllUsesWith(CoroBegin->getMem());
1242 }
1243
1244 break;
1245 }
1246 case coro::ABI::Async:
1247 case coro::ABI::Retcon:
1249 CoroBegin->replaceAllUsesWith(PoisonValue::get(CoroBegin->getType()));
1250 break;
1251 }
1252
1253 CoroBegin->eraseFromParent();
1254 Shape.CoroBegin = nullptr;
1255}
1256
1257// SimplifySuspendPoint needs to check that there is no calls between
1258// coro_save and coro_suspend, since any of the calls may potentially resume
1259// the coroutine and if that is the case we cannot eliminate the suspend point.
1261 for (Instruction &I : R) {
1262 // Assume that no intrinsic can resume the coroutine.
1263 if (isa<IntrinsicInst>(I))
1264 continue;
1265
1266 if (isa<CallBase>(I))
1267 return true;
1268 }
1269 return false;
1270}
1271
1272static bool hasCallsInBlocksBetween(BasicBlock *SaveBB, BasicBlock *ResDesBB) {
1275
1276 Set.insert(SaveBB);
1277 Worklist.push_back(ResDesBB);
1278
1279 // Accumulate all blocks between SaveBB and ResDesBB. Because CoroSaveIntr
1280 // returns a token consumed by suspend instruction, all blocks in between
1281 // will have to eventually hit SaveBB when going backwards from ResDesBB.
1282 while (!Worklist.empty()) {
1283 auto *BB = Worklist.pop_back_val();
1284 Set.insert(BB);
1285 for (auto *Pred : predecessors(BB))
1286 if (!Set.contains(Pred))
1287 Worklist.push_back(Pred);
1288 }
1289
1290 // SaveBB and ResDesBB are checked separately in hasCallsBetween.
1291 Set.erase(SaveBB);
1292 Set.erase(ResDesBB);
1293
1294 for (auto *BB : Set)
1295 if (hasCallsInBlockBetween({BB->getFirstNonPHIIt(), BB->end()}))
1296 return true;
1297
1298 return false;
1299}
1300
1301static bool hasCallsBetween(Instruction *Save, Instruction *ResumeOrDestroy) {
1302 auto *SaveBB = Save->getParent();
1303 auto *ResumeOrDestroyBB = ResumeOrDestroy->getParent();
1304 BasicBlock::iterator SaveIt = Save->getIterator();
1305 BasicBlock::iterator ResumeOrDestroyIt = ResumeOrDestroy->getIterator();
1306
1307 if (SaveBB == ResumeOrDestroyBB)
1308 return hasCallsInBlockBetween({std::next(SaveIt), ResumeOrDestroyIt});
1309
1310 // Any calls from Save to the end of the block?
1311 if (hasCallsInBlockBetween({std::next(SaveIt), SaveBB->end()}))
1312 return true;
1313
1314 // Any calls from begging of the block up to ResumeOrDestroy?
1316 {ResumeOrDestroyBB->getFirstNonPHIIt(), ResumeOrDestroyIt}))
1317 return true;
1318
1319 // Any calls in all of the blocks between SaveBB and ResumeOrDestroyBB?
1320 if (hasCallsInBlocksBetween(SaveBB, ResumeOrDestroyBB))
1321 return true;
1322
1323 return false;
1324}
1325
1326// If a SuspendIntrin is preceded by Resume or Destroy, we can eliminate the
1327// suspend point and replace it with nornal control flow.
1329 CoroBeginInst *CoroBegin) {
1330 Instruction *Prev = Suspend->getPrevNode();
1331 if (!Prev) {
1332 auto *Pred = Suspend->getParent()->getSinglePredecessor();
1333 if (!Pred)
1334 return false;
1335 Prev = Pred->getTerminator();
1336 }
1337
1338 CallBase *CB = dyn_cast<CallBase>(Prev);
1339 if (!CB)
1340 return false;
1341
1342 auto *Callee = CB->getCalledOperand()->stripPointerCasts();
1343
1344 // See if the callsite is for resumption or destruction of the coroutine.
1345 auto *SubFn = dyn_cast<CoroSubFnInst>(Callee);
1346 if (!SubFn)
1347 return false;
1348
1349 // Does not refer to the current coroutine, we cannot do anything with it.
1350 if (SubFn->getFrame() != CoroBegin)
1351 return false;
1352
1353 // See if the transformation is safe. Specifically, see if there are any
1354 // calls in between Save and CallInstr. They can potenitally resume the
1355 // coroutine rendering this optimization unsafe.
1356 auto *Save = Suspend->getCoroSave();
1357 if (hasCallsBetween(Save, CB))
1358 return false;
1359
1360 // Replace llvm.coro.suspend with the value that results in resumption over
1361 // the resume or cleanup path.
1362 Suspend->replaceAllUsesWith(SubFn->getRawIndex());
1363 Suspend->eraseFromParent();
1364 Save->eraseFromParent();
1365
1366 // No longer need a call to coro.resume or coro.destroy.
1367 if (auto *Invoke = dyn_cast<InvokeInst>(CB)) {
1368 UncondBrInst::Create(Invoke->getNormalDest(), Invoke->getIterator());
1369 }
1370
1371 // Grab the CalledValue from CB before erasing the CallInstr.
1372 auto *CalledValue = CB->getCalledOperand();
1373 CB->eraseFromParent();
1374
1375 // If no more users remove it. Usually it is a bitcast of SubFn.
1376 if (CalledValue != SubFn && CalledValue->user_empty())
1377 if (auto *I = dyn_cast<Instruction>(CalledValue))
1378 I->eraseFromParent();
1379
1380 // Now we are good to remove SubFn.
1381 if (SubFn->user_empty())
1382 SubFn->eraseFromParent();
1383
1384 return true;
1385}
1386
1387// Remove suspend points that are simplified.
1389 // Currently, the only simplification we do is switch-lowering-specific.
1390 if (Shape.ABI != coro::ABI::Switch)
1391 return;
1392
1393 auto &S = Shape.CoroSuspends;
1394 size_t I = 0, N = S.size();
1395 if (N == 0)
1396 return;
1397
1398 size_t ChangedFinalIndex = std::numeric_limits<size_t>::max();
1399 while (true) {
1400 auto SI = cast<CoroSuspendInst>(S[I]);
1401 // Leave final.suspend to handleFinalSuspend since it is undefined behavior
1402 // to resume a coroutine suspended at the final suspend point.
1403 if (!SI->isFinal() && simplifySuspendPoint(SI, Shape.CoroBegin)) {
1404 if (--N == I)
1405 break;
1406
1407 std::swap(S[I], S[N]);
1408
1409 if (cast<CoroSuspendInst>(S[I])->isFinal()) {
1411 ChangedFinalIndex = I;
1412 }
1413
1414 continue;
1415 }
1416 if (++I == N)
1417 break;
1418 }
1419 S.resize(N);
1420
1421 // Maintain final.suspend in case final suspend was swapped.
1422 // Due to we requrie the final suspend to be the last element of CoroSuspends.
1423 if (ChangedFinalIndex < N) {
1424 assert(cast<CoroSuspendInst>(S[ChangedFinalIndex])->isFinal());
1425 std::swap(S[ChangedFinalIndex], S.back());
1426 }
1427}
1428
1429namespace {
1430
1431struct SwitchCoroutineSplitter {
1432 static void split(Function &F, coro::Shape &Shape,
1433 SmallVectorImpl<Function *> &Clones,
1434 TargetTransformInfo &TTI) {
1435 assert(Shape.ABI == coro::ABI::Switch);
1436
1437 // Create a resume clone by cloning the body of the original function,
1438 // setting new entry block and replacing coro.suspend an appropriate value
1439 // to force resume or cleanup pass for every suspend point.
1440 createResumeEntryBlock(F, Shape);
1441 auto *ResumeClone = coro::SwitchCloner::createClone(
1442 F, ".resume", Shape, coro::CloneKind::SwitchResume, TTI);
1443 auto *DestroyClone = coro::SwitchCloner::createClone(
1444 F, ".destroy", Shape, coro::CloneKind::SwitchUnwind, TTI);
1445 auto *CleanupClone = coro::SwitchCloner::createClone(
1446 F, ".cleanup", Shape, coro::CloneKind::SwitchCleanup, TTI);
1447
1449 replaceSwitchResumeCoroFree(Shape, *ResumeClone, *CleanupClone);
1450
1451 postSplitCleanup(*ResumeClone);
1452 postSplitCleanup(*DestroyClone);
1453 postSplitCleanup(*CleanupClone);
1454
1455 // Store addresses resume/destroy/cleanup functions in the coroutine frame.
1456 updateCoroFrame(Shape, ResumeClone, DestroyClone, CleanupClone);
1457
1458 assert(Clones.empty());
1459 Clones.push_back(ResumeClone);
1460 Clones.push_back(DestroyClone);
1461 Clones.push_back(CleanupClone);
1462
1463 // Create a constant array referring to resume/destroy/clone functions
1464 // pointed by the last argument of @llvm.coro.info, so that CoroElide pass
1465 // can determined correct function to call.
1466 setCoroInfo(F, Shape, Clones);
1467 }
1468
1469 // Create a variant of ramp function that does not perform heap allocation
1470 // for a switch ABI coroutine.
1471 //
1472 // The newly split `.noalloc` ramp function has the following differences:
1473 // - Has one additional frame pointer parameter in lieu of dynamic
1474 // allocation.
1475 // - Suppressed allocations by replacing coro.alloc and coro.free.
1476 static Function *createNoAllocVariant(Function &F, coro::Shape &Shape,
1477 SmallVectorImpl<Function *> &Clones) {
1478 assert(Shape.ABI == coro::ABI::Switch);
1479 auto *OrigFnTy = F.getFunctionType();
1480 auto OldParams = OrigFnTy->params();
1481
1482 SmallVector<Type *> NewParams;
1483 NewParams.reserve(OldParams.size() + 1);
1484 NewParams.append(OldParams.begin(), OldParams.end());
1485 NewParams.push_back(PointerType::getUnqual(Shape.FramePtr->getContext()));
1486
1487 auto *NewFnTy = FunctionType::get(OrigFnTy->getReturnType(), NewParams,
1488 OrigFnTy->isVarArg());
1489 Function *NoAllocF = Function::Create(
1490 NewFnTy, F.getLinkage(), F.getAddressSpace(), F.getName() + ".noalloc");
1491
1492 ValueToValueMapTy VMap;
1493 unsigned int Idx = 0;
1494 for (const auto &I : F.args()) {
1495 VMap[&I] = NoAllocF->getArg(Idx++);
1496 }
1497 // We just appended the frame pointer as the last argument of the new
1498 // function.
1499 auto FrameIdx = NoAllocF->arg_size() - 1;
1501 CloneFunctionInto(NoAllocF, &F, VMap,
1502 CloneFunctionChangeType::LocalChangesOnly, Returns);
1503
1504 if (Shape.CoroBegin) {
1505 auto *NewCoroBegin =
1507 coro::elideCoroFree(NewCoroBegin);
1508 coro::suppressCoroAllocs(cast<CoroIdInst>(NewCoroBegin->getId()));
1509 NewCoroBegin->replaceAllUsesWith(NoAllocF->getArg(FrameIdx));
1510 NewCoroBegin->eraseFromParent();
1511 }
1512
1513 Module *M = F.getParent();
1514 M->getFunctionList().insert(M->end(), NoAllocF);
1515
1516 removeUnreachableBlocks(*NoAllocF);
1517 auto NewAttrs = NoAllocF->getAttributes();
1518 // When we elide allocation, we read these attributes to determine the
1519 // frame size and alignment.
1520 addFramePointerAttrs(NewAttrs, NoAllocF->getContext(), FrameIdx,
1521 Shape.FrameSize, Shape.FrameAlign,
1522 /*NoAlias=*/false);
1523
1524 NoAllocF->setAttributes(NewAttrs);
1525
1526 Clones.push_back(NoAllocF);
1527 // Reset the original function's coro info, make the new noalloc variant
1528 // connected to the original ramp function.
1529 setCoroInfo(F, Shape, Clones);
1530 // After copying, set the linkage to internal linkage. Original function
1531 // may have different linkage, but optimization dependent on this function
1532 // generally relies on LTO.
1534 return NoAllocF;
1535 }
1536
1537private:
1538 // Create an entry block for a resume function with a switch that will jump to
1539 // suspend points.
1540 static void createResumeEntryBlock(Function &F, coro::Shape &Shape) {
1541 LLVMContext &C = F.getContext();
1542
1543 DIBuilder DBuilder(*F.getParent(), /*AllowUnresolved*/ false);
1544 DISubprogram *DIS = F.getSubprogram();
1545 // If there is no DISubprogram for F, it implies the function is compiled
1546 // without debug info. So we also don't generate debug info for the
1547 // suspension points.
1548 bool AddDebugLabels = DIS && DIS->getUnit() &&
1549 (DIS->getUnit()->getEmissionKind() ==
1550 DICompileUnit::DebugEmissionKind::FullDebug);
1551
1552 // resume.entry:
1553 // %index.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32
1554 // 0, i32 2 % index = load i32, i32* %index.addr switch i32 %index, label
1555 // %unreachable [
1556 // i32 0, label %resume.0
1557 // i32 1, label %resume.1
1558 // ...
1559 // ]
1560
1561 auto *NewEntry = BasicBlock::Create(C, "resume.entry", &F);
1562 auto *UnreachBB = BasicBlock::Create(C, "unreachable", &F);
1563
1564 IRBuilder<> Builder(NewEntry);
1565 auto *FramePtr = Shape.FramePtr;
1566 Value *GepIndex = createSwitchIndexPtr(Shape, Builder, FramePtr);
1567 auto *Index = Builder.CreateLoad(Shape.getIndexType(), GepIndex, "index");
1568 auto *Switch =
1569 Builder.CreateSwitch(Index, UnreachBB, Shape.CoroSuspends.size());
1571
1572 // Split all coro.suspend calls
1573 size_t SuspendIndex = 0;
1574 SmallVector<uint64_t, 8> SwitchWeights64;
1575 // Default destination (unreachable) has weight 0
1576 SwitchWeights64.push_back(0);
1577
1578 for (auto *AnyS : Shape.CoroSuspends) {
1579 auto *S = cast<CoroSuspendInst>(AnyS);
1580 ConstantInt *IndexVal = Shape.getIndex(SuspendIndex);
1581
1582 // Replace CoroSave with a store to Index:
1583 // %index.addr = getelementptr %f.frame... (index field number)
1584 // store i32 %IndexVal, i32* %index.addr1
1585 auto *Save = S->getCoroSave();
1586 Builder.SetInsertPoint(Save);
1587 if (S->isFinal()) {
1588 // The coroutine should be marked done if it reaches the final suspend
1589 // point.
1590 markCoroutineAsDone(Builder, Shape, FramePtr);
1591 } else {
1592 Value *GepIndex = createSwitchIndexPtr(Shape, Builder, FramePtr);
1593 Builder.CreateStore(IndexVal, GepIndex);
1594 }
1595
1597 Save->eraseFromParent();
1598
1599 // Split block before and after coro.suspend and add a jump from an entry
1600 // switch:
1601 //
1602 // whateverBB:
1603 // whatever
1604 // %0 = call i8 @llvm.coro.suspend(token none, i1 false)
1605 // switch i8 %0, label %suspend[i8 0, label %resume
1606 // i8 1, label %cleanup]
1607 // becomes:
1608 //
1609 // whateverBB:
1610 // whatever
1611 // br label %resume.0.landing
1612 //
1613 // resume.0: ; <--- jump from the switch in the resume.entry
1614 // #dbg_label(...) ; <--- artificial label for debuggers
1615 // %0 = tail call i8 @llvm.coro.suspend(token none, i1 false)
1616 // br label %resume.0.landing
1617 //
1618 // resume.0.landing:
1619 // %1 = phi i8[-1, %whateverBB], [%0, %resume.0]
1620 // switch i8 % 1, label %suspend [i8 0, label %resume
1621 // i8 1, label %cleanup]
1622
1623 auto *SuspendBB = S->getParent();
1624 auto *ResumeBB =
1625 SuspendBB->splitBasicBlock(S, "resume." + Twine(SuspendIndex));
1626 auto *LandingBB = ResumeBB->splitBasicBlock(
1627 S->getNextNode(), ResumeBB->getName() + Twine(".landing"));
1628 Switch->addCase(IndexVal, ResumeBB);
1629
1630 // Get pre-split frequency for this suspend point
1631 uint64_t Weight = 1; // Default fallback weight
1632 auto It = Shape.SuspendFreqs.find(AnyS);
1633 if (It != Shape.SuspendFreqs.end()) {
1634 Weight = It->second;
1635 }
1636 SwitchWeights64.push_back(Weight);
1637
1638 cast<UncondBrInst>(SuspendBB->getTerminator())->setSuccessor(LandingBB);
1639 auto *PN = PHINode::Create(Builder.getInt8Ty(), 2, "");
1640 PN->insertBefore(LandingBB->begin());
1641 S->replaceAllUsesWith(PN);
1642 PN->addIncoming(Builder.getInt8(-1), SuspendBB);
1643 PN->addIncoming(S, ResumeBB);
1644
1645 if (AddDebugLabels) {
1646 if (DebugLoc SuspendLoc = S->getDebugLoc()) {
1647 std::string LabelName =
1648 ("__coro_resume_" + Twine(SuspendIndex)).str();
1649 // Take the "inlined at" location recursively, if present. This is
1650 // mandatory as the DILabel insertion checks that the scopes of label
1651 // and the attached location match. This is not the case when the
1652 // suspend location has been inlined due to pointing to the original
1653 // scope.
1654 DILocation *DILoc = SuspendLoc;
1655 while (DILocation *InlinedAt = DILoc->getInlinedAt())
1656 DILoc = InlinedAt;
1657
1658 DILabel *ResumeLabel =
1659 DBuilder.createLabel(DIS, LabelName, DILoc->getFile(),
1660 SuspendLoc.getLine(), SuspendLoc.getCol(),
1661 /*IsArtificial=*/true,
1662 /*CoroSuspendIdx=*/SuspendIndex,
1663 /*AlwaysPreserve=*/false);
1664 DBuilder.insertLabel(ResumeLabel, DILoc, ResumeBB->begin());
1665 }
1666 }
1667
1668 ++SuspendIndex;
1669 }
1670
1671 if (!Shape.SuspendFreqs.empty()) {
1672 auto SwitchWeights32 = llvm::fitWeights(SwitchWeights64);
1673 MDBuilder MDB(C);
1674 Switch->setMetadata(LLVMContext::MD_prof,
1675 MDB.createBranchWeights(SwitchWeights32));
1676 }
1677
1678 Builder.SetInsertPoint(UnreachBB);
1679 Builder.CreateUnreachable();
1680 DBuilder.finalize();
1681
1682 Shape.SwitchLowering.ResumeEntryBlock = NewEntry;
1683 }
1684
1685 // Store addresses of Resume/Destroy/Cleanup functions in the coroutine frame.
1686 static void updateCoroFrame(coro::Shape &Shape, Function *ResumeFn,
1687 Function *DestroyFn, Function *CleanupFn) {
1688 IRBuilder<> Builder(&*Shape.getInsertPtAfterFramePtr());
1689 LLVMContext &C = ResumeFn->getContext();
1690
1691 // Resume function pointer
1692 Value *ResumeAddr = Shape.FramePtr;
1693 Builder.CreateStore(ResumeFn, ResumeAddr);
1694
1695 Value *DestroyOrCleanupFn = DestroyFn;
1696
1697 CoroIdInst *CoroId = Shape.getSwitchCoroId();
1698 if (CoroAllocInst *CA = CoroId->getCoroAlloc()) {
1699 // If there is a CoroAlloc and it returns false (meaning we elide the
1700 // allocation, use CleanupFn instead of DestroyFn).
1701 DestroyOrCleanupFn = Builder.CreateSelect(CA, DestroyFn, CleanupFn);
1702 applyProfMetadataIfEnabled(DestroyOrCleanupFn, [&](Instruction *Inst) {
1704 CoroId->getFunction());
1705 });
1706 }
1707
1708 // Destroy function pointer
1709 Value *DestroyAddr = Builder.CreateInBoundsPtrAdd(
1710 Shape.FramePtr,
1711 ConstantInt::get(Type::getInt64Ty(C),
1713 "destroy.addr");
1714 Builder.CreateStore(DestroyOrCleanupFn, DestroyAddr);
1715 }
1716
1717 // Create a global constant array containing pointers to functions provided
1718 // and set Info parameter of CoroBegin to point at this constant. Example:
1719 //
1720 // @f.resumers = internal constant [2 x void(%f.frame*)*]
1721 // [void(%f.frame*)* @f.resume, void(%f.frame*)*
1722 // @f.destroy]
1723 // define void @f() {
1724 // ...
1725 // call i8* @llvm.coro.begin(i8* null, i32 0, i8* null,
1726 // i8* bitcast([2 x void(%f.frame*)*] * @f.resumers to
1727 // i8*))
1728 //
1729 // Assumes that all the functions have the same signature.
1730 static void setCoroInfo(Function &F, coro::Shape &Shape,
1732 // This only works under the switch-lowering ABI because coro elision
1733 // only works on the switch-lowering ABI.
1734 SmallVector<Constant *, 4> Args(Fns);
1735 assert(!Args.empty());
1736 Function *Part = *Fns.begin();
1737 Module *M = Part->getParent();
1738 auto *ArrTy = ArrayType::get(Part->getType(), Args.size());
1739
1740 auto *ConstVal = ConstantArray::get(ArrTy, Args);
1741 auto *GV = new GlobalVariable(*M, ConstVal->getType(), /*isConstant=*/true,
1742 GlobalVariable::PrivateLinkage, ConstVal,
1743 F.getName() + Twine(".resumers"));
1744
1745 // Update coro.begin instruction to refer to this constant.
1746 LLVMContext &C = F.getContext();
1747 auto *BC = ConstantExpr::getPointerCast(GV, PointerType::getUnqual(C));
1748 Shape.getSwitchCoroId()->setInfo(BC);
1749 }
1750};
1751
1752} // namespace
1753
1756 auto *ResumeIntrinsic = Suspend->getResumeFunction();
1757 auto &Context = Suspend->getParent()->getParent()->getContext();
1758 auto *Int8PtrTy = PointerType::getUnqual(Context);
1759
1760 IRBuilder<> Builder(ResumeIntrinsic);
1761 auto *Val = Builder.CreateBitOrPointerCast(Continuation, Int8PtrTy);
1762 ResumeIntrinsic->replaceAllUsesWith(Val);
1763 ResumeIntrinsic->eraseFromParent();
1765 PoisonValue::get(Int8PtrTy));
1766}
1767
1768/// Coerce the arguments in \p FnArgs according to \p FnTy in \p CallArgs.
1769static void coerceArguments(IRBuilder<> &Builder, FunctionType *FnTy,
1770 ArrayRef<Value *> FnArgs,
1771 SmallVectorImpl<Value *> &CallArgs) {
1772 size_t ArgIdx = 0;
1773 for (auto *paramTy : FnTy->params()) {
1774 assert(ArgIdx < FnArgs.size());
1775 if (paramTy != FnArgs[ArgIdx]->getType())
1776 CallArgs.push_back(
1777 Builder.CreateBitOrPointerCast(FnArgs[ArgIdx], paramTy));
1778 else
1779 CallArgs.push_back(FnArgs[ArgIdx]);
1780 ++ArgIdx;
1781 }
1782}
1783
1787 IRBuilder<> &Builder) {
1788 auto *FnTy = MustTailCallFn->getFunctionType();
1789 // Coerce the arguments, llvm optimizations seem to ignore the types in
1790 // vaarg functions and throws away casts in optimized mode.
1791 SmallVector<Value *, 8> CallArgs;
1792 coerceArguments(Builder, FnTy, Arguments, CallArgs);
1793
1794 auto *TailCall = Builder.CreateCall(FnTy, MustTailCallFn, CallArgs);
1795 // Skip targets which don't support tail call.
1796 if (TTI.supportsTailCallFor(TailCall)) {
1797 TailCall->setTailCallKind(CallInst::TCK_MustTail);
1798 }
1799 TailCall->setDebugLoc(Loc);
1800 TailCall->setCallingConv(MustTailCallFn->getCallingConv());
1801 return TailCall;
1802}
1803
1808 assert(Clones.empty());
1809 // Reset various things that the optimizer might have decided it
1810 // "knows" about the coroutine function due to not seeing a return.
1811 F.removeFnAttr(Attribute::NoReturn);
1812 F.removeRetAttr(Attribute::NoAlias);
1813 F.removeRetAttr(Attribute::NonNull);
1814
1815 auto &Context = F.getContext();
1816 auto *Int8PtrTy = PointerType::getUnqual(Context);
1817
1818 auto *Id = Shape.getAsyncCoroId();
1819 IRBuilder<> Builder(Id);
1820
1821 auto *FramePtr = Id->getStorage();
1822 FramePtr = Builder.CreateBitOrPointerCast(FramePtr, Int8PtrTy);
1823 FramePtr = Builder.CreateInBoundsPtrAdd(
1824 FramePtr,
1825 ConstantInt::get(Type::getInt64Ty(Context),
1826 Shape.AsyncLowering.FrameOffset),
1827 "async.ctx.frameptr");
1828
1829 // Map all uses of llvm.coro.begin to the allocated frame pointer.
1830 {
1831 // Make sure we don't invalidate Shape.FramePtr.
1832 TrackingVH<Value> Handle(Shape.FramePtr);
1833 Shape.CoroBegin->replaceAllUsesWith(FramePtr);
1834 Shape.FramePtr = Handle.getValPtr();
1835 }
1836
1837 // Create all the functions in order after the main function.
1838 auto NextF = std::next(F.getIterator());
1839
1840 // Create a continuation function for each of the suspend points.
1841 Clones.reserve(Shape.CoroSuspends.size());
1842 for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
1843 auto *Suspend = cast<CoroSuspendAsyncInst>(CS);
1844
1845 // Create the clone declaration.
1846 auto ResumeNameSuffix = ".resume.";
1847 auto ProjectionFunctionName =
1848 Suspend->getAsyncContextProjectionFunction()->getName();
1849 bool UseSwiftMangling = false;
1850 if (ProjectionFunctionName == "__swift_async_resume_project_context") {
1851 ResumeNameSuffix = "TQ";
1852 UseSwiftMangling = true;
1853 } else if (ProjectionFunctionName == "__swift_async_resume_get_context") {
1854 ResumeNameSuffix = "TY";
1855 UseSwiftMangling = true;
1856 }
1858 F, Shape,
1859 UseSwiftMangling ? ResumeNameSuffix + Twine(Idx) + "_"
1860 : ResumeNameSuffix + Twine(Idx),
1861 NextF, Suspend);
1862 Clones.push_back(Continuation);
1863
1864 // Insert a branch to a new return block immediately before the suspend
1865 // point.
1866 auto *SuspendBB = Suspend->getParent();
1867 auto *NewSuspendBB = SuspendBB->splitBasicBlock(Suspend);
1868 auto *Branch = cast<UncondBrInst>(SuspendBB->getTerminator());
1869
1870 // Place it before the first suspend.
1871 auto *ReturnBB =
1872 BasicBlock::Create(F.getContext(), "coro.return", &F, NewSuspendBB);
1873 Branch->setSuccessor(0, ReturnBB);
1874
1875 IRBuilder<> Builder(ReturnBB);
1876
1877 // Insert the call to the tail call function and inline it.
1878 auto *Fn = Suspend->getMustTailCallFunction();
1879 SmallVector<Value *, 8> Args(Suspend->args());
1880 auto FnArgs = ArrayRef<Value *>(Args).drop_front(
1882 auto *TailCall = coro::createMustTailCall(Suspend->getDebugLoc(), Fn, TTI,
1883 FnArgs, Builder);
1884 Builder.CreateRetVoid();
1885 InlineFunctionInfo FnInfo;
1886 (void)InlineFunction(*TailCall, FnInfo);
1887
1888 // Replace the lvm.coro.async.resume intrisic call.
1890 }
1891
1892 assert(Clones.size() == Shape.CoroSuspends.size());
1893
1894 for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
1895 auto *Suspend = CS;
1896 auto *Clone = Clones[Idx];
1897
1898 coro::BaseCloner::createClone(F, "resume." + Twine(Idx), Shape, Clone,
1899 Suspend, TTI);
1900 }
1901}
1902
1907 assert(Clones.empty());
1908
1909 // Reset various things that the optimizer might have decided it
1910 // "knows" about the coroutine function due to not seeing a return.
1911 F.removeFnAttr(Attribute::NoReturn);
1912 F.removeRetAttr(Attribute::NoAlias);
1913 F.removeRetAttr(Attribute::NonNull);
1914
1915 // Allocate the frame.
1916 auto *Id = Shape.getRetconCoroId();
1917 Value *RawFramePtr;
1918 if (Shape.RetconLowering.IsFrameInlineInStorage) {
1919 RawFramePtr = Id->getStorage();
1920 } else {
1921 IRBuilder<> Builder(Id);
1922
1923 auto FrameSize = Builder.getInt64(Shape.FrameSize);
1924
1925 // Allocate. We don't need to update the call graph node because we're
1926 // going to recompute it from scratch after splitting.
1927 // FIXME: pass the required alignment
1928 RawFramePtr = Shape.emitAlloc(Builder, FrameSize, nullptr);
1929 RawFramePtr =
1930 Builder.CreateBitCast(RawFramePtr, Shape.CoroBegin->getType());
1931
1932 // Stash the allocated frame pointer in the continuation storage.
1933 Builder.CreateStore(RawFramePtr, Id->getStorage());
1934 }
1935
1936 // Map all uses of llvm.coro.begin to the allocated frame pointer.
1937 {
1938 // Make sure we don't invalidate Shape.FramePtr.
1939 TrackingVH<Value> Handle(Shape.FramePtr);
1940 Shape.CoroBegin->replaceAllUsesWith(RawFramePtr);
1941 Shape.FramePtr = Handle.getValPtr();
1942 }
1943
1944 // Create a unique return block.
1945 BasicBlock *ReturnBB = nullptr;
1946 PHINode *ContinuationPhi = nullptr;
1947 SmallVector<PHINode *, 4> ReturnPHIs;
1948
1949 // Create all the functions in order after the main function.
1950 auto NextF = std::next(F.getIterator());
1951
1952 // Create a continuation function for each of the suspend points.
1953 Clones.reserve(Shape.CoroSuspends.size());
1954 for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
1955 auto Suspend = cast<CoroSuspendRetconInst>(CS);
1956
1957 // Create the clone declaration.
1959 F, Shape, ".resume." + Twine(Idx), NextF, nullptr);
1960 Clones.push_back(Continuation);
1961
1962 // Insert a branch to the unified return block immediately before
1963 // the suspend point.
1964 auto SuspendBB = Suspend->getParent();
1965 auto NewSuspendBB = SuspendBB->splitBasicBlock(Suspend);
1966 auto Branch = cast<UncondBrInst>(SuspendBB->getTerminator());
1967
1968 // Create the unified return block.
1969 if (!ReturnBB) {
1970 // Place it before the first suspend.
1971 ReturnBB =
1972 BasicBlock::Create(F.getContext(), "coro.return", &F, NewSuspendBB);
1973 Shape.RetconLowering.ReturnBlock = ReturnBB;
1974
1975 IRBuilder<> Builder(ReturnBB);
1976
1977 // First, the continuation.
1978 ContinuationPhi =
1979 Builder.CreatePHI(Continuation->getType(), Shape.CoroSuspends.size());
1980
1981 // Create PHIs for all other return values.
1982 assert(ReturnPHIs.empty());
1983
1984 // Next, all the directly-yielded values.
1985 for (auto *ResultTy : Shape.getRetconResultTypes())
1986 ReturnPHIs.push_back(
1987 Builder.CreatePHI(ResultTy, Shape.CoroSuspends.size()));
1988
1989 // Build the return value.
1990 auto RetTy = F.getReturnType();
1991
1992 // Cast the continuation value if necessary.
1993 // We can't rely on the types matching up because that type would
1994 // have to be infinite.
1995 auto CastedContinuationTy =
1996 (ReturnPHIs.empty() ? RetTy : RetTy->getStructElementType(0));
1997 auto *CastedContinuation =
1998 Builder.CreateBitCast(ContinuationPhi, CastedContinuationTy);
1999
2000 Value *RetV = CastedContinuation;
2001 if (!ReturnPHIs.empty()) {
2002 auto ValueIdx = 0;
2003 RetV = PoisonValue::get(RetTy);
2004 RetV = Builder.CreateInsertValue(RetV, CastedContinuation, ValueIdx++);
2005
2006 for (auto Phi : ReturnPHIs)
2007 RetV = Builder.CreateInsertValue(RetV, Phi, ValueIdx++);
2008 }
2009
2010 Builder.CreateRet(RetV);
2011 }
2012
2013 // Branch to the return block.
2014 Branch->setSuccessor(0, ReturnBB);
2015 assert(ContinuationPhi);
2016 ContinuationPhi->addIncoming(Continuation, SuspendBB);
2017 for (auto [Phi, VUse] :
2018 llvm::zip_equal(ReturnPHIs, Suspend->value_operands()))
2019 Phi->addIncoming(VUse, SuspendBB);
2020 }
2021
2022 assert(Clones.size() == Shape.CoroSuspends.size());
2023
2024 for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
2025 auto Suspend = CS;
2026 auto Clone = Clones[Idx];
2027
2028 coro::BaseCloner::createClone(F, "resume." + Twine(Idx), Shape, Clone,
2029 Suspend, TTI);
2030 }
2031}
2032
2033namespace {
2034class PrettyStackTraceFunction : public PrettyStackTraceEntry {
2035 Function &F;
2036
2037public:
2038 PrettyStackTraceFunction(Function &F) : F(F) {}
2039 void print(raw_ostream &OS) const override {
2040 OS << "While splitting coroutine ";
2041 F.printAsOperand(OS, /*print type*/ false, F.getParent());
2042 OS << "\n";
2043 }
2044};
2045} // namespace
2046
2047/// Remove calls to llvm.coro.end in the original function.
2049 if (Shape.ABI != coro::ABI::Switch) {
2050 for (auto *End : Shape.CoroEnds) {
2051 replaceCoroEnd(End, Shape, Shape.FramePtr, /*in ramp*/ true, nullptr);
2052 }
2053 } else {
2054 for (llvm::AnyCoroEndInst *End : Shape.CoroEnds)
2055 End->eraseFromParent();
2056 }
2057}
2058
2060 for (auto *II : Shape.CoroIsInRampInsts) {
2061 auto &Ctx = II->getContext();
2062 II->replaceAllUsesWith(ConstantInt::getTrue(Ctx));
2063 II->eraseFromParent();
2064 }
2065}
2066
2068 for (auto *U : F.users()) {
2069 if (auto *CB = dyn_cast<CallBase>(U)) {
2070 auto *Caller = CB->getFunction();
2071 if (Caller && Caller->isPresplitCoroutine() &&
2072 CB->hasFnAttr(llvm::Attribute::CoroElideSafe))
2073 return true;
2074 }
2075 }
2076 return false;
2077}
2078
2082 SwitchCoroutineSplitter::split(F, Shape, Clones, TTI);
2083}
2084
2087 bool OptimizeFrame) {
2088 PrettyStackTraceFunction prettyStackTrace(F);
2089
2090 auto &Shape = ABI.Shape;
2091 assert(Shape.CoroBegin);
2092
2093 lowerAwaitSuspends(F, Shape);
2094
2095 simplifySuspendPoints(Shape);
2096
2097 normalizeCoroutine(F, Shape, TTI);
2098 ABI.buildCoroutineFrame(OptimizeFrame);
2100
2101 bool isNoSuspendCoroutine = Shape.CoroSuspends.empty();
2102
2103 bool shouldCreateNoAllocVariant =
2104 !isNoSuspendCoroutine && Shape.ABI == coro::ABI::Switch &&
2105 hasSafeElideCaller(F) && !F.hasFnAttribute(llvm::Attribute::NoInline);
2106 if (Shape.ABI == coro::ABI::Switch)
2108 shouldCreateNoAllocVariant;
2109
2110 // If there are no suspend points, no split required, just remove
2111 // the allocation and deallocation blocks, they are not needed.
2112 if (isNoSuspendCoroutine) {
2114 } else {
2115 ABI.splitCoroutine(F, Shape, Clones, TTI);
2116 }
2117
2118 // Replace all the swifterror operations in the original function.
2119 // This invalidates SwiftErrorOps in the Shape.
2120 replaceSwiftErrorOps(F, Shape, nullptr);
2121
2122 // Salvage debug intrinsics that point into the coroutine frame in the
2123 // original function. The Cloner has already salvaged debug info in the new
2124 // coroutine funclets.
2126 auto DbgVariableRecords = collectDbgVariableRecords(F);
2127 for (DbgVariableRecord *DVR : DbgVariableRecords)
2128 coro::salvageDebugInfo(ArgToAllocaMap, *DVR, false /*UseEntryValue*/);
2129
2132
2133 if (shouldCreateNoAllocVariant)
2134 SwitchCoroutineSplitter::createNoAllocVariant(F, Shape, Clones);
2135}
2136
2138 LazyCallGraph::Node &N, const coro::Shape &Shape,
2142
2143 auto *CurrentSCC = &C;
2144 if (!Clones.empty()) {
2145 switch (Shape.ABI) {
2146 case coro::ABI::Switch:
2147 // The resume clone's elided-frame check holds a reference to the cleanup
2148 // clone. Add the cleanup clone first, so populating the resume node does
2149 // not materialize an unregistered cleanup node.
2151 assert(Clones.size() >= 3 && "expected switch coroutine clones");
2152 CG.addSplitFunction(N.getFunction(), *Clones[2]);
2153 CG.addSplitFunction(N.getFunction(), *Clones[1]);
2154 CG.addSplitFunction(N.getFunction(), *Clones[0]);
2155 for (Function *Clone : drop_begin(Clones, 3))
2156 CG.addSplitFunction(N.getFunction(), *Clone);
2157 } else {
2158 // Each clone in the Switch lowering is independent of the other
2159 // clones. Let the LazyCallGraph know about each one separately.
2160 for (Function *Clone : Clones)
2161 CG.addSplitFunction(N.getFunction(), *Clone);
2162 }
2163 break;
2164 case coro::ABI::Async:
2165 case coro::ABI::Retcon:
2167 // Each clone in the Async/Retcon lowering references of the other clones.
2168 // Let the LazyCallGraph know about all of them at once.
2169 if (!Clones.empty())
2170 CG.addSplitRefRecursiveFunctions(N.getFunction(), Clones);
2171 break;
2172 }
2173
2174 // Let the CGSCC infra handle the changes to the original function.
2175 CurrentSCC = &updateCGAndAnalysisManagerForCGSCCPass(CG, *CurrentSCC, N, AM,
2176 UR, FAM);
2177 }
2178
2179 // Do some cleanup and let the CGSCC infra see if we've cleaned up any edges
2180 // to the split functions.
2181 postSplitCleanup(N.getFunction());
2182 CurrentSCC = &updateCGAndAnalysisManagerForFunctionPass(CG, *CurrentSCC, N,
2183 AM, UR, FAM);
2184 return *CurrentSCC;
2185}
2186
2187/// Replace a call to llvm.coro.prepare.retcon.
2188static void replacePrepare(CallInst *Prepare, LazyCallGraph &CG,
2190 auto CastFn = Prepare->getArgOperand(0); // as an i8*
2191 auto Fn = CastFn->stripPointerCasts(); // as its original type
2192
2193 // Attempt to peephole this pattern:
2194 // %0 = bitcast [[TYPE]] @some_function to i8*
2195 // %1 = call @llvm.coro.prepare.retcon(i8* %0)
2196 // %2 = bitcast %1 to [[TYPE]]
2197 // ==>
2198 // %2 = @some_function
2199 for (Use &U : llvm::make_early_inc_range(Prepare->uses())) {
2200 // Look for bitcasts back to the original function type.
2201 auto *Cast = dyn_cast<BitCastInst>(U.getUser());
2202 if (!Cast || Cast->getType() != Fn->getType())
2203 continue;
2204
2205 // Replace and remove the cast.
2206 Cast->replaceAllUsesWith(Fn);
2207 Cast->eraseFromParent();
2208 }
2209
2210 // Replace any remaining uses with the function as an i8*.
2211 // This can never directly be a callee, so we don't need to update CG.
2212 Prepare->replaceAllUsesWith(CastFn);
2213 Prepare->eraseFromParent();
2214
2215 // Kill dead bitcasts.
2216 while (auto *Cast = dyn_cast<BitCastInst>(CastFn)) {
2217 if (!Cast->use_empty())
2218 break;
2219 CastFn = Cast->getOperand(0);
2220 Cast->eraseFromParent();
2221 }
2222}
2223
2224static bool replaceAllPrepares(Function *PrepareFn, LazyCallGraph &CG,
2226 bool Changed = false;
2227 for (Use &P : llvm::make_early_inc_range(PrepareFn->uses())) {
2228 // Intrinsics can only be used in calls.
2229 auto *Prepare = cast<CallInst>(P.getUser());
2230 replacePrepare(Prepare, CG, C);
2231 Changed = true;
2232 }
2233
2234 return Changed;
2235}
2236
2237static void addPrepareFunction(const Module &M,
2239 StringRef Name) {
2240 auto *PrepareFn = M.getFunction(Name);
2241 if (PrepareFn && !PrepareFn->use_empty())
2242 Fns.push_back(PrepareFn);
2243}
2244
2245static std::unique_ptr<coro::BaseABI>
2247 std::function<bool(Instruction &)> IsMatCallback,
2248 const SmallVector<CoroSplitPass::BaseABITy> GenCustomABIs) {
2249 if (S.CoroBegin->hasCustomABI()) {
2250 unsigned CustomABI = S.CoroBegin->getCustomABI();
2251 if (CustomABI >= GenCustomABIs.size())
2252 llvm_unreachable("Custom ABI not found amoung those specified");
2253 return GenCustomABIs[CustomABI](F, S);
2254 }
2255
2256 switch (S.ABI) {
2257 case coro::ABI::Switch:
2258 return std::make_unique<coro::SwitchABI>(F, S, IsMatCallback);
2259 case coro::ABI::Async:
2260 return std::make_unique<coro::AsyncABI>(F, S, IsMatCallback);
2261 case coro::ABI::Retcon:
2262 return std::make_unique<coro::AnyRetconABI>(F, S, IsMatCallback);
2264 return std::make_unique<coro::AnyRetconABI>(F, S, IsMatCallback);
2265 }
2266 llvm_unreachable("Unknown ABI");
2267}
2268
2270 : CreateAndInitABI([](Function &F, coro::Shape &S) {
2271 std::unique_ptr<coro::BaseABI> ABI =
2273 ABI->init();
2274 return ABI;
2275 }),
2276 OptimizeFrame(OptimizeFrame) {}
2277
2280 : CreateAndInitABI([=](Function &F, coro::Shape &S) {
2281 std::unique_ptr<coro::BaseABI> ABI =
2283 ABI->init();
2284 return ABI;
2285 }),
2286 OptimizeFrame(OptimizeFrame) {}
2287
2288// For back compatibility, constructor takes a materializable callback and
2289// creates a generator for an ABI with a modified materializable callback.
2290CoroSplitPass::CoroSplitPass(std::function<bool(Instruction &)> IsMatCallback,
2291 bool OptimizeFrame)
2292 : CreateAndInitABI([=](Function &F, coro::Shape &S) {
2293 std::unique_ptr<coro::BaseABI> ABI =
2294 CreateNewABI(F, S, IsMatCallback, {});
2295 ABI->init();
2296 return ABI;
2297 }),
2298 OptimizeFrame(OptimizeFrame) {}
2299
2300// For back compatibility, constructor takes a materializable callback and
2301// creates a generator for an ABI with a modified materializable callback.
2303 std::function<bool(Instruction &)> IsMatCallback,
2305 : CreateAndInitABI([=](Function &F, coro::Shape &S) {
2306 std::unique_ptr<coro::BaseABI> ABI =
2307 CreateNewABI(F, S, IsMatCallback, GenCustomABIs);
2308 ABI->init();
2309 return ABI;
2310 }),
2311 OptimizeFrame(OptimizeFrame) {}
2312
2316 // NB: One invariant of a valid LazyCallGraph::SCC is that it must contain a
2317 // non-zero number of nodes, so we assume that here and grab the first
2318 // node's function's module.
2319 Module &M = *C.begin()->getFunction().getParent();
2320 auto &FAM =
2321 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
2322
2323 // Check for uses of llvm.coro.prepare.retcon/async.
2324 SmallVector<Function *, 2> PrepareFns;
2325 addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.retcon");
2326 addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.async");
2327
2328 // Find coroutines for processing.
2330 for (LazyCallGraph::Node &N : C)
2331 if (N.getFunction().isPresplitCoroutine())
2332 Coroutines.push_back(&N);
2333
2334 if (Coroutines.empty() && PrepareFns.empty())
2335 return PreservedAnalyses::all();
2336
2337 auto *CurrentSCC = &C;
2338 // Split all the coroutines.
2339 for (LazyCallGraph::Node *N : Coroutines) {
2340 Function &F = N->getFunction();
2341 LLVM_DEBUG(dbgs() << "CoroSplit: Processing coroutine '" << F.getName()
2342 << "\n");
2343
2344 // The suspend-crossing algorithm in buildCoroutineFrame gets tripped up
2345 // by unreachable blocks, so remove them as a first pass. Remove the
2346 // unreachable blocks before collecting intrinsics into Shape.
2348
2349 coro::Shape Shape(F);
2350 if (!Shape.CoroBegin)
2351 continue;
2352
2353 F.setSplittedCoroutine();
2354
2355 // Query BFI and populate SuspendFreqs right before splitting.
2356 auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
2357 for (auto *AnyS : Shape.CoroSuspends) {
2358 BasicBlock *BB = AnyS->getParent();
2359 uint64_t Freq = BFI.getBlockFreq(BB).getFrequency();
2360 Shape.SuspendFreqs[AnyS] = Freq;
2361
2362 // Query BFI to get the actual estimated execution profile count of the
2363 // basic block where this suspension point resides.
2364 std::optional<uint64_t> Count = BFI.getBlockProfileCount(BB);
2365 if (Count.has_value()) {
2366 if (!Shape.ResumeEntryCount.has_value()) {
2367 // For the first suspend point visited, initialize the total sum.
2368 Shape.ResumeEntryCount = Count.value();
2369 } else {
2370 // Accumulate the absolute execution count of each subsequent suspend
2371 // point into the total sum.
2372 Shape.ResumeEntryCount.value() += Count.value();
2373 }
2374 }
2375 }
2376
2377 std::unique_ptr<coro::BaseABI> ABI = CreateAndInitABI(F, Shape);
2378
2380 auto &TTI = FAM.getResult<TargetIRAnalysis>(F);
2381 doSplitCoroutine(F, Clones, *ABI, TTI, OptimizeFrame);
2383 *N, Shape, Clones, *CurrentSCC, CG, AM, UR, FAM);
2384
2385 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
2386 ORE.emit([&]() {
2387 return OptimizationRemark(DEBUG_TYPE, "CoroSplit", &F)
2388 << "Split '" << ore::NV("function", F.getName())
2389 << "' (frame_size=" << ore::NV("frame_size", Shape.FrameSize)
2390 << ", align=" << ore::NV("align", Shape.FrameAlign.value()) << ")";
2391 });
2392
2393 if (!Shape.CoroSuspends.empty()) {
2394 // Run the CGSCC pipeline on the original and newly split functions.
2395 UR.CWorklist.insert(CurrentSCC);
2396 for (Function *Clone : Clones)
2397 UR.CWorklist.insert(CG.lookupSCC(CG.get(*Clone)));
2398 } else if (Shape.ABI == coro::ABI::Async) {
2399 // Reprocess the function to inline the tail called return function of
2400 // coro.async.end.
2401 UR.CWorklist.insert(&C);
2402 }
2403 }
2404
2405 for (auto *PrepareFn : PrepareFns) {
2406 replaceAllPrepares(PrepareFn, CG, *CurrentSCC);
2407 }
2408
2409 return PreservedAnalyses::none();
2410}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
unsigned 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.
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
This pass exposes codegen information to IR-level passes.
static const unsigned FramePtr
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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:459
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:356
size_t arg_size() const
Definition Function.h:886
Argument * getArg(unsigned i) const
Definition Function.h:871
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:2306
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2391
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:1916
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2918
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:71
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:339
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:553
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:712
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:319
void splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl< Function * > &Clones, TargetTransformInfo &TTI) override
void splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl< Function * > &Clones, TargetTransformInfo &TTI) override
Function & F
Definition ABI.h:59
coro::Shape & Shape
Definition ABI.h:60
AnyCoroSuspendInst * ActiveSuspend
The active suspend instruction; meaningful only for continuation and async ABIs.
Definition CoroCloner.h:57
Value * deriveNewFramePointer()
Derive the value of the new frame pointer.
TargetTransformInfo & TTI
Definition CoroCloner.h:49
coro::Shape & Shape
Definition CoroCloner.h:46
static Function * createClone(Function &OrigF, const Twine &Suffix, coro::Shape &Shape, Function *NewF, AnyCoroSuspendInst *ActiveSuspend, TargetTransformInfo &TTI)
Create a clone for a continuation lowering.
Definition CoroCloner.h:83
ValueToValueMapTy VMap
Definition CoroCloner.h:51
const Twine & Suffix
Definition CoroCloner.h:45
void replaceRetconOrAsyncSuspendUses()
Replace uses of the active llvm.coro.suspend.retcon/async call with the arguments to the continuation...
virtual void create()
Clone the body of the original function into a resume function of some sort.
void splitCoroutine(Function &F, coro::Shape &Shape, SmallVectorImpl< Function * > &Clones, TargetTransformInfo &TTI) override
static Function * createClone(Function &OrigF, const Twine &Suffix, coro::Shape &Shape, CloneKind FKind, TargetTransformInfo &TTI)
Create a clone for a switch lowering.
Definition CoroCloner.h:139
void create() override
Clone the body of the original function into a resume function of some sort.
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
CallInst * Call
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ 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:2907
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:2538
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:267
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