LLVM 20.0.0git
Macros | Functions
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/DataLayout.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 std::pair< SmallVector< DbgVariableIntrinsic *, 8 >, SmallVector< DbgVariableRecord * > > collectDbgVariableIntrinsics (Function &F)
 Returns all DbgVariableIntrinsic 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 (Instruction *From, Instruction *To)
 
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)
 
Coerce the arguments in p FnArgs according to p FnTy in p static CallArgs void coerceArguments (IRBuilder<> &Builder, FunctionType *FnTy, ArrayRef< Value * > FnArgs, SmallVectorImpl< Value * > &CallArgs)
 
Remove calls to llvm coro end in the original static function void removeCoroEndsFromRampFunction (const coro::Shape &Shape)
 
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)
 
Replace a call to llvm coro prepare static retcon void replacePrepare (CallInst *Prepare, LazyCallGraph &CG, LazyCallGraph::SCC &C)
 
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 78 of file CoroSplit.cpp.

Function Documentation

◆ addAsyncContextAttrs()

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

Definition at line 850 of file CoroSplit.cpp.

References llvm::AttrBuilder::addAttribute().

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

◆ addFramePointerAttrs()

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

◆ addPrepareFunction()

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

◆ addSwiftSelfAttrs()

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

Definition at line 857 of file CoroSplit.cpp.

References llvm::AttrBuilder::addAttribute().

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

◆ coerceArguments()

Coerce the arguments in p FnArgs according to p FnTy in p static CallArgs void coerceArguments ( IRBuilder<> &  Builder,
FunctionType FnTy,
ArrayRef< Value * >  FnArgs,
SmallVectorImpl< Value * > &  CallArgs 
)
static

◆ collectDbgVariableIntrinsics()

static std::pair< SmallVector< DbgVariableIntrinsic *, 8 >, SmallVector< DbgVariableRecord * > > collectDbgVariableIntrinsics ( Function F)
static

Returns all DbgVariableIntrinsic in F.

Definition at line 621 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()

static Function * createCloneDeclaration ( Function OrigF,
coro::Shape Shape,
const Twine Suffix,
Module::iterator  InsertBefore,
AnyCoroSuspendInst ActiveSuspend 
)
static

◆ CreateNewABI()

static std::unique_ptr< coro::BaseABI > CreateNewABI ( Function F,
coro::Shape S,
std::function< bool(Instruction &)>  IsMatCallback,
const SmallVector< CoroSplitPass::BaseABITy GenCustomABIs 
)
static

◆ doSplitCoroutine()

static void doSplitCoroutine ( Function F,
SmallVectorImpl< Function * > &  Clones,
coro::BaseABI ABI,
TargetTransformInfo TTI,
bool  OptimizeFrame 
)
static

◆ getFrameSizeForShape()

static TypeSize getFrameSizeForShape ( coro::Shape Shape)
static

◆ getFunctionTypeFromAsyncSuspend()

static FunctionType * getFunctionTypeFromAsyncSuspend ( AnyCoroSuspendInst Suspend)
static

◆ handleNoSuspendCoroutine()

static void handleNoSuspendCoroutine ( coro::Shape Shape)
static

◆ hasCallsBetween()

static bool hasCallsBetween ( Instruction Save,
Instruction ResumeOrDestroy 
)
static

◆ hasCallsInBlockBetween()

static bool hasCallsInBlockBetween ( Instruction From,
Instruction To 
)
static

Definition at line 1202 of file CoroSplit.cpp.

References From, and I.

Referenced by hasCallsBetween(), and hasCallsInBlocksBetween().

◆ hasCallsInBlocksBetween()

static bool hasCallsInBlocksBetween ( BasicBlock SaveBB,
BasicBlock ResDesBB 
)
static

◆ hasSafeElideCaller()

static bool hasSafeElideCaller ( Function F)
static

Definition at line 1940 of file CoroSplit.cpp.

References F.

Referenced by doSplitCoroutine().

◆ lowerAwaitSuspend()

static void lowerAwaitSuspend ( IRBuilder<> &  Builder,
CoroAwaitSuspendInst CB,
coro::Shape Shape 
)
static

◆ lowerAwaitSuspends()

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

Definition at line 150 of file CoroSplit.cpp.

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

Referenced by doSplitCoroutine().

◆ markCoroutineAsDone()

static void markCoroutineAsDone ( IRBuilder<> &  Builder,
const coro::Shape Shape,
Value FramePtr 
)
static

◆ maybeFreeRetconStorage()

static void maybeFreeRetconStorage ( IRBuilder<> &  Builder,
const coro::Shape Shape,
Value FramePtr,
CallGraph CG 
)
static

◆ postSplitCleanup()

static void postSplitCleanup ( Function F)
static

◆ removeCoroEndsFromRampFunction()

Remove calls to llvm coro end in the original static function void removeCoroEndsFromRampFunction ( const coro::Shape Shape)
static

◆ replaceAllPrepares()

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

◆ replaceAsyncResumeFunction()

static void replaceAsyncResumeFunction ( CoroSuspendAsyncInst Suspend,
Value Continuation 
)
static

◆ replaceCoroEnd()

static void replaceCoroEnd ( AnyCoroEndInst End,
const coro::Shape Shape,
Value FramePtr,
bool  InResume,
CallGraph CG 
)
static

◆ replaceCoroEndAsync()

static 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 169 of file CoroSplit.cpp.

References assert(), llvm::IRBuilderBase::CreateRetVoid(), End, llvm::InlineFunction(), and llvm::IRBuilderBase::SetInsertPoint().

Referenced by replaceFallthroughCoroEnd().

◆ replaceFallthroughCoroEnd()

static void replaceFallthroughCoroEnd ( AnyCoroEndInst End,
const coro::Shape Shape,
Value FramePtr,
bool  InResume,
CallGraph CG 
)
static

◆ replaceFrameSizeAndAlignment()

static void replaceFrameSizeAndAlignment ( coro::Shape Shape)
static

◆ replacePrepare()

Replace a call to llvm coro prepare static retcon void replacePrepare ( CallInst Prepare,
LazyCallGraph CG,
LazyCallGraph::SCC C 
)
static

◆ replaceSwiftErrorOps()

static void replaceSwiftErrorOps ( Function F,
coro::Shape Shape,
ValueToValueMapTy VMap 
)
static

◆ replaceUnwindCoroEnd()

static void replaceUnwindCoroEnd ( AnyCoroEndInst End,
const coro::Shape Shape,
Value FramePtr,
bool  InResume,
CallGraph CG 
)
static

◆ simplifySuspendPoint()

static bool simplifySuspendPoint ( CoroSuspendInst Suspend,
CoroBeginInst CoroBegin 
)
static

◆ simplifySuspendPoints()

static void simplifySuspendPoints ( coro::Shape Shape)
static

◆ updateAsyncFuncPointerContextSize()

static void updateAsyncFuncPointerContextSize ( coro::Shape Shape)
static

◆ updateCallGraphAfterCoroutineSplit()

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

◆ updateScopeLine()

static 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 802 of file CoroSplit.cpp.

References DL, llvm::Instruction::getDebugLoc(), llvm::DIScope::getFile(), llvm::Instruction::getNextNonDebugInstruction(), and llvm::Successor.

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