LLVM 22.0.0git
CoroSplit.cpp File Reference
#include "llvm/Transforms/Coroutines/CoroSplit.h"
#include "CoroCloner.h"
#include "CoroInternal.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PriorityWorklist.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Coroutines/MaterializationUtils.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/CallGraphUpdater.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <initializer_list>
#include <iterator>

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "coro-split"

Functions

static void lowerAwaitSuspend (IRBuilder<> &Builder, CoroAwaitSuspendInst *CB, coro::Shape &Shape)
static void lowerAwaitSuspends (Function &F, coro::Shape &Shape)
static void maybeFreeRetconStorage (IRBuilder<> &Builder, const coro::Shape &Shape, Value *FramePtr, CallGraph *CG)
static bool replaceCoroEndAsync (AnyCoroEndInst *End)
 Replace an llvm.coro.end.async.
static void replaceFallthroughCoroEnd (AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG)
 Replace a non-unwind call to llvm.coro.end.
static void markCoroutineAsDone (IRBuilder<> &Builder, const coro::Shape &Shape, Value *FramePtr)
static void replaceUnwindCoroEnd (AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG)
 Replace an unwind call to llvm.coro.end.
static void replaceCoroEnd (AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG)
static FunctionTypegetFunctionTypeFromAsyncSuspend (AnyCoroSuspendInst *Suspend)
static FunctioncreateCloneDeclaration (Function &OrigF, coro::Shape &Shape, const Twine &Suffix, Module::iterator InsertBefore, AnyCoroSuspendInst *ActiveSuspend)
static void replaceSwiftErrorOps (Function &F, coro::Shape &Shape, ValueToValueMapTy *VMap)
static SmallVector< DbgVariableRecord * > collectDbgVariableRecords (Function &F)
 Returns all debug records in F.
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 addFramePointerAttrs (AttributeList &Attrs, LLVMContext &Context, unsigned ParamIndex, uint64_t Size, Align Alignment, bool NoAlias)
static void addAsyncContextAttrs (AttributeList &Attrs, LLVMContext &Context, unsigned ParamIndex)
static void addSwiftSelfAttrs (AttributeList &Attrs, LLVMContext &Context, unsigned ParamIndex)
static void updateAsyncFuncPointerContextSize (coro::Shape &Shape)
static TypeSize getFrameSizeForShape (coro::Shape &Shape)
static void replaceFrameSizeAndAlignment (coro::Shape &Shape)
static void postSplitCleanup (Function &F)
static void handleNoSuspendCoroutine (coro::Shape &Shape)
static bool hasCallsInBlockBetween (iterator_range< BasicBlock::iterator > R)
static bool hasCallsInBlocksBetween (BasicBlock *SaveBB, BasicBlock *ResDesBB)
static bool hasCallsBetween (Instruction *Save, Instruction *ResumeOrDestroy)
static bool simplifySuspendPoint (CoroSuspendInst *Suspend, CoroBeginInst *CoroBegin)
static void simplifySuspendPoints (coro::Shape &Shape)
static void replaceAsyncResumeFunction (CoroSuspendAsyncInst *Suspend, Value *Continuation)
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 removeCoroEndsFromRampFunction (const coro::Shape &Shape)
 Remove calls to llvm.coro.end in the original function.
static bool hasSafeElideCaller (Function &F)
static void doSplitCoroutine (Function &F, SmallVectorImpl< Function * > &Clones, coro::BaseABI &ABI, TargetTransformInfo &TTI, bool OptimizeFrame)
static LazyCallGraph::SCCupdateCallGraphAfterCoroutineSplit (LazyCallGraph::Node &N, const coro::Shape &Shape, const SmallVectorImpl< Function * > &Clones, LazyCallGraph::SCC &C, LazyCallGraph &CG, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, FunctionAnalysisManager &FAM)
static void replacePrepare (CallInst *Prepare, LazyCallGraph &CG, LazyCallGraph::SCC &C)
 Replace a call to llvm.coro.prepare.retcon.
static bool replaceAllPrepares (Function *PrepareFn, LazyCallGraph &CG, LazyCallGraph::SCC &C)
static void addPrepareFunction (const Module &M, SmallVectorImpl< Function * > &Fns, StringRef Name)
static std::unique_ptr< coro::BaseABICreateNewABI (Function &F, coro::Shape &S, std::function< bool(Instruction &)> IsMatCallback, const SmallVector< CoroSplitPass::BaseABITy > GenCustomABIs)

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "coro-split"

Definition at line 80 of file CoroSplit.cpp.

Function Documentation

◆ addAsyncContextAttrs()

void addAsyncContextAttrs ( AttributeList & Attrs,
LLVMContext & Context,
unsigned ParamIndex )
static

Definition at line 856 of file CoroSplit.cpp.

Referenced by llvm::coro::BaseCloner::create().

◆ addFramePointerAttrs()

void addFramePointerAttrs ( AttributeList & Attrs,
LLVMContext & Context,
unsigned ParamIndex,
uint64_t Size,
Align Alignment,
bool NoAlias )
static

Definition at line 841 of file CoroSplit.cpp.

References Size.

Referenced by llvm::coro::BaseCloner::create().

◆ addPrepareFunction()

void addPrepareFunction ( const Module & M,
SmallVectorImpl< Function * > & Fns,
StringRef Name )
static

◆ addSwiftSelfAttrs()

void addSwiftSelfAttrs ( AttributeList & Attrs,
LLVMContext & Context,
unsigned ParamIndex )
static

Definition at line 863 of file CoroSplit.cpp.

Referenced by llvm::coro::BaseCloner::create().

◆ coerceArguments()

void coerceArguments ( IRBuilder<> & Builder,
FunctionType * FnTy,
ArrayRef< Value * > FnArgs,
SmallVectorImpl< Value * > & CallArgs )
static

Coerce the arguments in FnArgs according to FnTy in CallArgs.

Definition at line 1677 of file CoroSplit.cpp.

References assert(), getType(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), and llvm::ArrayRef< T >::size().

Referenced by llvm::coro::createMustTailCall().

◆ collectDbgVariableRecords()

SmallVector< DbgVariableRecord * > collectDbgVariableRecords ( Function & F)
static

Returns all debug records in F.

Definition at line 623 of file CoroSplit.cpp.

References F, llvm::filterDbgVars(), I, instructions, and llvm::SmallVectorTemplateBase< T, bool >::push_back().

Referenced by doSplitCoroutine(), and llvm::coro::BaseCloner::salvageDebugInfo().

◆ createCloneDeclaration()

◆ CreateNewABI()

◆ doSplitCoroutine()

◆ getFrameSizeForShape()

TypeSize getFrameSizeForShape ( coro::Shape & Shape)
static

◆ getFunctionTypeFromAsyncSuspend()

◆ handleNoSuspendCoroutine()

◆ hasCallsBetween()

◆ hasCallsInBlockBetween()

bool hasCallsInBlockBetween ( iterator_range< BasicBlock::iterator > R)
static

Definition at line 1193 of file CoroSplit.cpp.

References I, and llvm::isa().

Referenced by hasCallsBetween(), and hasCallsInBlocksBetween().

◆ hasCallsInBlocksBetween()

◆ hasSafeElideCaller()

bool hasSafeElideCaller ( Function & F)
static

Definition at line 1970 of file CoroSplit.cpp.

References llvm::dyn_cast(), and F.

Referenced by doSplitCoroutine().

◆ lowerAwaitSuspend()

◆ lowerAwaitSuspends()

void lowerAwaitSuspends ( Function & F,
coro::Shape & Shape )
static

Definition at line 152 of file CoroSplit.cpp.

References llvm::coro::Shape::CoroAwaitSuspends, F, and lowerAwaitSuspend().

Referenced by doSplitCoroutine().

◆ markCoroutineAsDone()

◆ maybeFreeRetconStorage()

◆ postSplitCleanup()

void postSplitCleanup ( Function & F)
static

◆ removeCoroEndsFromRampFunction()

void removeCoroEndsFromRampFunction ( const coro::Shape & Shape)
static

◆ replaceAllPrepares()

bool replaceAllPrepares ( Function * PrepareFn,
LazyCallGraph & CG,
LazyCallGraph::SCC & C )
static

◆ replaceAsyncResumeFunction()

◆ replaceCoroEnd()

◆ replaceCoroEndAsync()

bool replaceCoroEndAsync ( AnyCoroEndInst * End)
static

Replace an llvm.coro.end.async.

Will inline the must tail call function call if there is one.

Returns
true if cleanup of the coro.end block is needed, false otherwise.

Definition at line 171 of file CoroSplit.cpp.

References assert(), llvm::cast(), llvm::dyn_cast(), llvm::ilist_node_impl< OptionsT >::getIterator(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), and llvm::InlineFunction().

Referenced by replaceFallthroughCoroEnd().

◆ replaceFallthroughCoroEnd()

◆ replaceFrameSizeAndAlignment()

◆ replacePrepare()

◆ replaceSwiftErrorOps()

◆ replaceUnwindCoroEnd()

◆ simplifySuspendPoint()

◆ simplifySuspendPoints()

◆ updateAsyncFuncPointerContextSize()

◆ updateCallGraphAfterCoroutineSplit()

◆ updateScopeLine()

void updateScopeLine ( Instruction * ActiveSuspend,
DISubprogram & SPToUpdate )
static

Adjust the scope line of the funclet to the first line number after the suspend point.

This avoids a jump in the line table from the function declaration (where prologue instructions are attributed to) to the suspend point. Only adjust the scope line when the files are the same. If no candidate line number is found, fallback to the line of ActiveSuspend.

Definition at line 798 of file CoroSplit.cpp.

References DL, llvm::dyn_cast_or_null(), llvm::BasicBlock::end(), llvm::Instruction::getDebugLoc(), llvm::DIScope::getFile(), llvm::ilist_node_impl< OptionsT >::getIterator(), llvm::ilist_node_with_parent< NodeTy, ParentTy, Options >::getNextNode(), llvm::skipDebugIntrinsics(), and llvm::Successor.

Referenced by llvm::coro::BaseCloner::create().