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