1 //===- CoroInternal.h - Internal Coroutine interfaces ---------*- C++ -*---===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
9 // Common definitions/declarations used internally by coroutine lowering passes.
10 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_LIB_TRANSFORMS_COROUTINES_COROINTERNAL_H
13 #define LLVM_LIB_TRANSFORMS_COROUTINES_COROINTERNAL_H
15 #include "CoroInstr.h"
16 #include "llvm/Transforms/Coroutines.h"
24 void initializeCoroEarlyPass(PassRegistry &);
25 void initializeCoroSplitPass(PassRegistry &);
26 void initializeCoroElidePass(PassRegistry &);
27 void initializeCoroCleanupPass(PassRegistry &);
29 // CoroEarly pass marks every function that has coro.begin with a string
30 // attribute "coroutine.presplit"="0". CoroSplit pass processes the coroutine
31 // twice. First, it lets it go through complete IPO optimization pipeline as a
32 // single function. It forces restart of the pipeline by inserting an indirect
33 // call to an empty function "coro.devirt.trigger" which is devirtualized by
34 // CoroElide pass that triggers a restart of the pipeline by CGPassManager.
35 // When CoroSplit pass sees the same coroutine the second time, it splits it up,
36 // adds coroutine subfunctions to the SCC to be processed by IPO pipeline.
38 #define CORO_PRESPLIT_ATTR "coroutine.presplit"
39 #define UNPREPARED_FOR_SPLIT "0"
40 #define PREPARED_FOR_SPLIT "1"
42 #define CORO_DEVIRT_TRIGGER_FN "coro.devirt.trigger"
46 bool declaresIntrinsics(Module &M, std::initializer_list<StringRef>);
47 void replaceAllCoroAllocs(CoroBeginInst *CB, bool Replacement);
48 void replaceAllCoroFrees(CoroBeginInst *CB, Value *Replacement);
49 void replaceCoroFree(CoroIdInst *CoroId, bool Elide);
50 void updateCallGraph(Function &Caller, ArrayRef<Function *> Funcs,
51 CallGraph &CG, CallGraphSCC &SCC);
53 // Keeps data and helper functions for lowering coroutine intrinsics.
57 PointerType *const Int8Ptr;
58 FunctionType *const ResumeFnType;
59 ConstantPointerNull *const NullPtr;
61 LowererBase(Module &M);
62 Value *makeSubFnCall(Value *Arg, int Index, Instruction *InsertPt);
65 // Holds structural Coroutine Intrinsics for a particular function and other
66 // values used during CoroSplit pass.
67 struct LLVM_LIBRARY_VISIBILITY Shape {
68 CoroBeginInst *CoroBegin;
69 SmallVector<CoroEndInst *, 4> CoroEnds;
70 SmallVector<CoroSizeInst *, 2> CoroSizes;
71 SmallVector<CoroSuspendInst *, 4> CoroSuspends;
73 // Field Indexes for known coroutine frame fields.
79 LastKnownField = IndexField
83 Instruction *FramePtr;
84 BasicBlock *AllocaSpillBlock;
85 SwitchInst *ResumeSwitch;
86 AllocaInst *PromiseAlloca;
89 IntegerType *getIndexType() const {
90 assert(FrameTy && "frame type not assigned");
91 return cast<IntegerType>(FrameTy->getElementType(IndexField));
93 ConstantInt *getIndex(uint64_t Value) const {
94 return ConstantInt::get(getIndexType(), Value);
98 explicit Shape(Function &F) { buildFrom(F); }
99 void buildFrom(Function &F);
102 void buildCoroutineFrame(Function &F, Shape &Shape);
104 } // End namespace coro.
105 } // End namespace llvm