23 #define DEBUG_TYPE "coro-early" 39 : LowererBase(M), Builder(
Context),
51 void Lowerer::lowerResumeOrDestroy(
CallSite CS,
73 const DataLayout &DL = TheModule.getDataLayout();
75 DL.getStructLayout(SampleStruct)->getElementOffset(2), Alignement);
79 Builder.SetInsertPoint(Intrin);
81 Builder.CreateConstInBoundsGEP1_32(Int8Ty, Operand, Offset);
95 auto *FrameTy = Int8Ptr;
98 Builder.SetInsertPoint(II);
99 auto *BCI = Builder.CreateBitCast(Operand, FramePtrTy);
100 auto *Gep = Builder.CreateConstInBoundsGEP1_32(FrameTy, BCI, 0);
101 auto *
Load = Builder.CreateLoad(Gep);
102 auto *Cond = Builder.CreateICmpEQ(
Load, NullPtr);
118 auto *FnPtrTy = FnTy->getPointerTo();
119 FrameTy->
setBody({FnPtrTy, FnPtrTy});
124 "NoopCoro.ResumeDestroy", &M);
130 Constant* Values[] = {NoopFn, NoopFn};
134 "NoopCoro.Frame.Const");
137 Builder.SetInsertPoint(II);
138 auto *NoopCoroVoidPtr = Builder.CreateBitCast(NoopCoro, Int8Ptr);
149 if (
auto *CB = dyn_cast<CoroBeginInst>(U))
150 CB->setCannotDuplicate();
153 bool Lowerer::lowerEarlyIntrinsics(
Function &
F) {
154 bool Changed =
false;
164 CoroFrees.
push_back(cast<CoroFreeInst>(&I));
169 if (cast<CoroSuspendInst>(&I)->isFinal())
175 if (cast<CoroEndInst>(&I)->isFallthrough())
179 lowerCoroNoop(cast<IntrinsicInst>(&I));
184 if (
auto *CII = cast<CoroIdInst>(&I)) {
185 if (CII->getInfo().isPreSplit()) {
188 CII->setCoroutineSelf();
189 CoroId = cast<CoroIdInst>(&
I);
200 lowerCoroPromise(cast<CoroPromiseInst>(&I));
203 lowerCoroDone(cast<IntrinsicInst>(&I));
214 CF->setArgOperand(0, CoroId);
230 std::unique_ptr<Lowerer> L;
234 bool doInitialization(
Module &M)
override {
236 M, {
"llvm.coro.id",
"llvm.coro.destroy",
"llvm.coro.done",
237 "llvm.coro.end",
"llvm.coro.noop",
"llvm.coro.free",
238 "llvm.coro.promise",
"llvm.coro.resume",
"llvm.coro.suspend"}))
239 L = llvm::make_unique<Lowerer>(M);
247 return L->lowerEarlyIntrinsics(F);
254 return "Lower early coroutine intrinsics";
Pass interface - Implemented by all 'passes'.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A parsed version of the target data layout string in and methods for querying it. ...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This represents the llvm.coro.promise instruction.
This represents the llvm.coro.alloc instruction.
This class represents lattice values for constants.
void initializeCoroEarlyPass(PassRegistry &)
A Module instance is used to store all the information related to an LLVM module. ...
void push_back(const T &Elt)
Like Internal, but omit from symbol table.
LLVMContext & getContext() const
All values hold a context through their type.
Pass * createCoroEarlyPass()
Lower coroutine intrinsics that are not needed by later passes.
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
unsigned getAlignment() const
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
Value * getArgOperand(unsigned i) const
inst_iterator inst_begin(Function *F)
Class to represent struct types.
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
InstrTy * getInstruction() const
INITIALIZE_PASS(CoroEarly, "coro-early", "Lower early coroutine intrinsics", false, false) Pass *llvm
static StructType * get(LLVMContext &Context, ArrayRef< Type *> Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Type * getType() const
All values are typed, get the type of this value.
ValTy * getArgOperand(unsigned i) const
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of the intrinsic called by this CallSite, or Intrinsic::not_intrinsic if the ...
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
void setBody(ArrayRef< Type *> Elements, bool isPacked=false)
Specify a body for an opaque identified type.
Class to represent pointers.
static bool runOnFunction(Function &F, bool PostInlining)
void setCallingConv(CallingConv::ID CC)
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
#define CORO_PRESPLIT_ATTR
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
This is an important base class in LLVM.
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
void setCallingConv(CallingConv::ID CC)
Set the calling convention of the call.
FunctionPass class - This class is used to implement most global optimizations.
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Constant * get(StructType *T, ArrayRef< Constant *> V)
bool isFromPromise() const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
This represents the llvm.coro.free instruction.
void setCannotDuplicate()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
#define UNPREPARED_FOR_SPLIT
void setPreservesCFG()
This function should be called by the pass, iff they do not:
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
iterator_range< user_iterator > users()
static void setCannotDuplicate(CoroIdInst *CoroId)
LLVM Value Representation.
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
bool declaresIntrinsics(Module &M, std::initializer_list< StringRef >)
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
StringRef - Represent a constant reference to a string, i.e.
inst_iterator inst_end(Function *F)
static IntegerType * getInt8Ty(LLVMContext &C)
void setCalledFunction(Value *V)
Set the callee to the specified value.
A wrapper class for inspecting calls to intrinsic functions.