LLVM  14.0.0git
Macros | Functions | Variables
CoroSplit.cpp File Reference
#include "llvm/Transforms/Coroutines/CoroSplit.h"
#include "CoroInstr.h"
#include "CoroInternal.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/LazyCallGraph.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/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.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/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/Verifier.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.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/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 "llvm/Transforms/Utils/ValueMapper.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 maybeFreeRetconStorage (IRBuilder<> &Builder, const coro::Shape &Shape, Value *FramePtr, CallGraph *CG)
 
static bool replaceCoroEndAsync (AnyCoroEndInst *End)
 Replace an llvm.coro.end.async. More...
 
static void replaceFallthroughCoroEnd (AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG)
 Replace a non-unwind call to llvm.coro.end. More...
 
static void replaceUnwindCoroEnd (AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG)
 Replace an unwind call to llvm.coro.end. More...
 
static void replaceCoroEnd (AnyCoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG)
 
static void createResumeEntryBlock (Function &F, coro::Shape &Shape)
 
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 void addFramePointerAttrs (AttributeList &Attrs, LLVMContext &Context, unsigned ParamIndex, uint64_t Size, Align Alignment)
 
static void addAsyncContextAttrs (AttributeList &Attrs, LLVMContext &Context, unsigned ParamIndex)
 
static void addSwiftSelfAttrs (AttributeList &Attrs, LLVMContext &Context, unsigned ParamIndex)
 
static FunctioncreateClone (Function &F, const Twine &Suffix, coro::Shape &Shape, CoroCloner::Kind FKind)
 
static void removeCoroEnds (const coro::Shape &Shape, CallGraph *CG)
 Remove calls to llvm.coro.end in the original function. More...
 
static void updateAsyncFuncPointerContextSize (coro::Shape &Shape)
 
static void replaceFrameSize (coro::Shape &Shape)
 
static void setCoroInfo (Function &F, coro::Shape &Shape, ArrayRef< Function * > Fns)
 
static void updateCoroFrame (coro::Shape &Shape, Function *ResumeFn, Function *DestroyFn, Function *CleanupFn)
 
static void postSplitCleanup (Function &F)
 
static void scanPHIsAndUpdateValueMap (Instruction *Prev, BasicBlock *NewBlock, DenseMap< Value *, Value * > &ResolvedValues)
 
static bool simplifyTerminatorLeadingToRet (Instruction *InitialInst)
 
static bool shouldBeMustTail (const CallInst &CI, const Function &F)
 
static void addMustTailToCoroResumes (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 splitSwitchCoroutine (Function &F, coro::Shape &Shape, SmallVectorImpl< Function * > &Clones)
 
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. More...
 
static void splitAsyncCoroutine (Function &F, coro::Shape &Shape, SmallVectorImpl< Function * > &Clones)
 
static void splitRetconCoroutine (Function &F, coro::Shape &Shape, SmallVectorImpl< Function * > &Clones)
 
static coro::Shape splitCoroutine (Function &F, SmallVectorImpl< Function * > &Clones, bool ReuseFrameSlot)
 
static void updateCallGraphAfterCoroutineSplit (Function &F, const coro::Shape &Shape, const SmallVectorImpl< Function * > &Clones, CallGraph &CG, CallGraphSCC &SCC)
 
static void 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 prepareForSplit (Function &F, CallGraph &CG, bool MarkForAsyncRestart=false)
 
static void createDevirtTriggerFunc (CallGraph &CG, CallGraphSCC &SCC)
 
static void replacePrepare (CallInst *Prepare, LazyCallGraph &CG, LazyCallGraph::SCC &C)
 Replace a call to llvm.coro.prepare.retcon. More...
 
static void replacePrepare (CallInst *Prepare, CallGraph &CG)
 Replace a call to llvm.coro.prepare.retcon. More...
 
static bool replaceAllPrepares (Function *PrepareFn, LazyCallGraph &CG, LazyCallGraph::SCC &C)
 
static bool replaceAllPrepares (Function *PrepareFn, CallGraph &CG)
 Remove calls to llvm.coro.prepare.retcon, a barrier meant to prevent IPO from operating on calls to a retcon coroutine before it's been split. More...
 
static bool declaresCoroSplitIntrinsics (const Module &M)
 
static void addPrepareFunction (const Module &M, SmallVectorImpl< Function * > &Fns, StringRef Name)
 
 INITIALIZE_PASS_BEGIN (CoroSplitLegacy, "coro-split", "Split coroutine into a set of functions driving its state machine", false, false) INITIALIZE_PASS_END(CoroSplitLegacy
 

Variables

coro split
 
coro Split coroutine into a set of functions driving its state machine
 
coro Split coroutine into a set of functions driving its state false
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "coro-split"

Definition at line 77 of file CoroSplit.cpp.

Function Documentation

◆ addAsyncContextAttrs()

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

Definition at line 823 of file CoroSplit.cpp.

References llvm::AttrBuilder::addAttribute(), Attrs, and Context.

◆ addFramePointerAttrs()

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

◆ addMustTailToCoroResumes()

static void addMustTailToCoroResumes ( Function F)
static

◆ addPrepareFunction()

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

Definition at line 2097 of file CoroSplit.cpp.

References M.

Referenced by llvm::CoroSplitPass::run().

◆ addSwiftSelfAttrs()

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

Definition at line 830 of file CoroSplit.cpp.

References llvm::AttrBuilder::addAttribute(), Attrs, and Context.

◆ coerceArguments()

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

References assert(), Builder, llvm::Intrinsic::getType(), llvm::FunctionType::params(), and llvm::ArrayRef< T >::size().

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

◆ createClone()

static Function* createClone ( Function F,
const Twine Suffix,
coro::Shape Shape,
CoroCloner::Kind  FKind 
)
static

Definition at line 1035 of file CoroSplit.cpp.

References F.

Referenced by splitSwitchCoroutine().

◆ createCloneDeclaration()

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

◆ createDevirtTriggerFunc()

static void createDevirtTriggerFunc ( CallGraph CG,
CallGraphSCC SCC 
)
static

◆ createResumeEntryBlock()

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

◆ declaresCoroSplitIntrinsics()

static bool declaresCoroSplitIntrinsics ( const Module M)
static

Definition at line 2091 of file CoroSplit.cpp.

References llvm::coro::declaresIntrinsics(), and M.

Referenced by llvm::CoroSplitPass::run().

◆ 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 1334 of file CoroSplit.cpp.

References From, and I.

Referenced by hasCallsBetween(), and hasCallsInBlocksBetween().

◆ hasCallsInBlocksBetween()

static bool hasCallsInBlocksBetween ( BasicBlock SaveBB,
BasicBlock ResDesBB 
)
static

◆ INITIALIZE_PASS_BEGIN()

INITIALIZE_PASS_BEGIN ( CoroSplitLegacy  ,
"coro-split ,
"Split coroutine into a set of functions driving its state machine ,
false  ,
false   
)

◆ maybeFreeRetconStorage()

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

◆ postSplitCleanup()

static void postSplitCleanup ( Function F)
static

◆ prepareForSplit()

static void prepareForSplit ( Function F,
CallGraph CG,
bool  MarkForAsyncRestart = false 
)
static

◆ removeCoroEnds()

static void removeCoroEnds ( const coro::Shape Shape,
CallGraph CG 
)
static

Remove calls to llvm.coro.end in the original function.

Definition at line 1043 of file CoroSplit.cpp.

Referenced by updateCallGraphAfterCoroutineSplit().

◆ replaceAllPrepares() [1/2]

static bool replaceAllPrepares ( Function PrepareFn,
CallGraph CG 
)
static

Remove calls to llvm.coro.prepare.retcon, a barrier meant to prevent IPO from operating on calls to a retcon coroutine before it's been split.

This is only safe to do after we've split all retcon coroutines in the module. We can do that this in this pass because this pass does promise to split all retcon coroutines (as opposed to switch coroutines, which are lowered in multiple stages).

Definition at line 2078 of file CoroSplit.cpp.

References replacePrepare(), llvm::Value::use_begin(), and llvm::Value::use_end().

◆ replaceAllPrepares() [2/2]

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

Definition at line 314 of file CoroSplit.cpp.

◆ 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 183 of file CoroSplit.cpp.

◆ replaceFallthroughCoroEnd()

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

Replace a non-unwind call to llvm.coro.end.

Definition at line 226 of file CoroSplit.cpp.

◆ replaceFrameSize()

static void replaceFrameSize ( coro::Shape Shape)
static

◆ replacePrepare() [1/2]

static void replacePrepare ( CallInst Prepare,
CallGraph CG 
)
static

◆ replacePrepare() [2/2]

static 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

Replace an unwind call to llvm.coro.end.

Definition at line 284 of file CoroSplit.cpp.

◆ scanPHIsAndUpdateValueMap()

static void scanPHIsAndUpdateValueMap ( Instruction Prev,
BasicBlock NewBlock,
DenseMap< Value *, Value * > &  ResolvedValues 
)
static

◆ setCoroInfo()

static void setCoroInfo ( Function F,
coro::Shape Shape,
ArrayRef< Function * >  Fns 
)
static

◆ shouldBeMustTail()

static bool shouldBeMustTail ( const CallInst CI,
const Function F 
)
static

◆ simplifySuspendPoint()

static bool simplifySuspendPoint ( CoroSuspendInst Suspend,
CoroBeginInst CoroBegin 
)
static

◆ simplifySuspendPoints()

static void simplifySuspendPoints ( coro::Shape Shape)
static

◆ simplifyTerminatorLeadingToRet()

static bool simplifyTerminatorLeadingToRet ( Instruction InitialInst)
static

◆ splitAsyncCoroutine()

static void splitAsyncCoroutine ( Function F,
coro::Shape Shape,
SmallVectorImpl< Function * > &  Clones 
)
static

◆ splitCoroutine()

static coro::Shape splitCoroutine ( Function F,
SmallVectorImpl< Function * > &  Clones,
bool  ReuseFrameSlot 
)
static

◆ splitRetconCoroutine()

static void splitRetconCoroutine ( Function F,
coro::Shape Shape,
SmallVectorImpl< Function * > &  Clones 
)
static

◆ splitSwitchCoroutine()

static void splitSwitchCoroutine ( Function F,
coro::Shape Shape,
SmallVectorImpl< Function * > &  Clones 
)
static

◆ updateAsyncFuncPointerContextSize()

static void updateAsyncFuncPointerContextSize ( coro::Shape Shape)
static

◆ updateCallGraphAfterCoroutineSplit() [1/2]

static void updateCallGraphAfterCoroutineSplit ( Function F,
const coro::Shape Shape,
const SmallVectorImpl< Function * > &  Clones,
CallGraph CG,
CallGraphSCC SCC 
)
static

◆ updateCallGraphAfterCoroutineSplit() [2/2]

static void updateCallGraphAfterCoroutineSplit ( LazyCallGraph::Node N,
const coro::Shape Shape,
const SmallVectorImpl< Function * > &  Clones,
LazyCallGraph::SCC C,
LazyCallGraph CG,
CGSCCAnalysisManager AM,
CGSCCUpdateResult UR,
FunctionAnalysisManager FAM 
)
static

Definition at line 1862 of file CoroSplit.cpp.

References llvm::coro::Shape::CoroBegin.

◆ updateCoroFrame()

static void updateCoroFrame ( coro::Shape Shape,
Function ResumeFn,
Function DestroyFn,
Function CleanupFn 
)
static

Variable Documentation

◆ false

coro Split coroutine into a set of functions driving its state false

Definition at line 2280 of file CoroSplit.cpp.

◆ machine

coro Split coroutine into a set of functions driving its state machine

Definition at line 2280 of file CoroSplit.cpp.

◆ split

coro split

Definition at line 2279 of file CoroSplit.cpp.

Referenced by llvm::StringRef::split().