#include "llvm/Transforms/Coroutines/CoroSplit.h"
#include "CoroInternal.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PriorityWorklist.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/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/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/ABI.h"
#include "llvm/Transforms/Coroutines/CoroInstr.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 "llvm/Transforms/Utils/ValueMapper.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <initializer_list>
#include <iterator>
usingnamespacellvm;
#define DEBUG_TYPE …
namespace {
class CoroCloner { … };
}
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) { … }
static void replaceFallthroughCoroEnd(AnyCoroEndInst *End,
const coro::Shape &Shape, Value *FramePtr,
bool InResume, CallGraph *CG) { … }
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) { … }
static void replaceCoroEnd(AnyCoroEndInst *End, const coro::Shape &Shape,
Value *FramePtr, bool InResume, CallGraph *CG) { … }
void CoroCloner::handleFinalSuspend() { … }
static FunctionType *
getFunctionTypeFromAsyncSuspend(AnyCoroSuspendInst *Suspend) { … }
static Function *createCloneDeclaration(Function &OrigF, coro::Shape &Shape,
const Twine &Suffix,
Module::iterator InsertBefore,
AnyCoroSuspendInst *ActiveSuspend) { … }
void CoroCloner::replaceRetconOrAsyncSuspendUses() { … }
void CoroCloner::replaceCoroSuspends() { … }
void CoroCloner::replaceCoroEnds() { … }
static void replaceSwiftErrorOps(Function &F, coro::Shape &Shape,
ValueToValueMapTy *VMap) { … }
static std::pair<SmallVector<DbgVariableIntrinsic *, 8>,
SmallVector<DbgVariableRecord *>>
collectDbgVariableIntrinsics(Function &F) { … }
void CoroCloner::replaceSwiftErrorOps() { … }
void CoroCloner::salvageDebugInfo() { … }
void CoroCloner::replaceEntryBlock() { … }
Value *CoroCloner::deriveNewFramePointer() { … }
static void updateScopeLine(Instruction *ActiveSuspend,
DISubprogram &SPToUpdate) { … }
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) { … }
void CoroCloner::create() { … }
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) { … }
namespace {
struct SwitchCoroutineSplitter { … };
}
static void replaceAsyncResumeFunction(CoroSuspendAsyncInst *Suspend,
Value *Continuation) { … }
static void coerceArguments(IRBuilder<> &Builder, FunctionType *FnTy,
ArrayRef<Value *> FnArgs,
SmallVectorImpl<Value *> &CallArgs) { … }
CallInst *coro::createMustTailCall(DebugLoc Loc, Function *MustTailCallFn,
TargetTransformInfo &TTI,
ArrayRef<Value *> Arguments,
IRBuilder<> &Builder) { … }
void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) { … }
void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) { … }
namespace {
class PrettyStackTraceFunction : public PrettyStackTraceEntry { … };
}
static void removeCoroEndsFromRampFunction(const coro::Shape &Shape) { … }
static bool hasSafeElideCaller(Function &F) { … }
void coro::SwitchABI::splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) { … }
static void doSplitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones,
coro::BaseABI &ABI, TargetTransformInfo &TTI,
bool OptimizeFrame) { … }
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 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::BaseABI>
CreateNewABI(Function &F, coro::Shape &S,
std::function<bool(Instruction &)> IsMatCallback,
const SmallVector<CoroSplitPass::BaseABITy> GenCustomABIs) { … }
CoroSplitPass::CoroSplitPass(bool OptimizeFrame)
: … { … }
CoroSplitPass::CoroSplitPass(
SmallVector<CoroSplitPass::BaseABITy> GenCustomABIs, bool OptimizeFrame)
: … { … }
CoroSplitPass::CoroSplitPass(std::function<bool(Instruction &)> IsMatCallback,
bool OptimizeFrame)
: … { … }
CoroSplitPass::CoroSplitPass(
std::function<bool(Instruction &)> IsMatCallback,
SmallVector<CoroSplitPass::BaseABITy> GenCustomABIs, bool OptimizeFrame)
: … { … }
PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
CGSCCAnalysisManager &AM,
LazyCallGraph &CG, CGSCCUpdateResult &UR) { … }