25#ifndef LLVM_TRANSFORMS_COROUTINES_COROINSTR_H
26#define LLVM_TRANSFORMS_COROUTINES_COROINSTR_H
37 enum { FrameArg, IndexArg };
53 "unexpected CoroSubFnInst index argument");
63 return I->getIntrinsicID() == Intrinsic::coro_subfn_addr;
66 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
75 return I->getIntrinsicID() == Intrinsic::coro_alloc;
78 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
87 enum { AwaiterArg, FrameArg, WrapperArg };
101 auto IID = CF->getIntrinsicID();
102 return IID == Intrinsic::coro_await_suspend_void ||
103 IID == Intrinsic::coro_await_suspend_bool ||
104 IID == Intrinsic::coro_await_suspend_handle;
111 return isa<CallBase>(V) &&
classof(cast<CallBase>(V));
120 if (
auto *CA = dyn_cast<CoroAllocInst>(U))
127 if (
auto *
II = dyn_cast<IntrinsicInst>(U))
128 if (
II->getIntrinsicID() == Intrinsic::coro_begin ||
129 II->getIntrinsicID() == Intrinsic::coro_begin_custom_abi)
136 auto ID =
I->getIntrinsicID();
137 return ID == Intrinsic::coro_id ||
ID == Intrinsic::coro_id_retcon ||
138 ID == Intrinsic::coro_id_retcon_once ||
139 ID == Intrinsic::coro_id_async;
143 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
149 enum { AlignArg, PromiseArg, CoroutineArg, InfoArg };
154 return isa<ConstantPointerNull>(Arg)
163 if (isa<AllocaInst>(Arg))
165 assert((isa<BitCastInst>(Arg) || isa<GetElementPtrInst>(Arg)) &&
166 "unexpected instruction designating the promise");
169 auto *Inst = cast<Instruction>(Arg);
170 if (Inst->use_empty()) {
171 Inst->eraseFromParent();
199 auto *GV = dyn_cast<GlobalVariable>(
getRawInfo());
203 assert(GV->isConstant() && GV->hasDefinitiveInitializer());
204 Constant *Initializer = GV->getInitializer();
205 if ((Result.OutlinedParts = dyn_cast<ConstantStruct>(Initializer)))
208 Result.Resumers = cast<ConstantArray>(Initializer);
228 return I->getIntrinsicID() == Intrinsic::coro_id;
231 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
238 enum { SizeArg, AlignArg, StorageArg, PrototypeArg, AllocArg, DeallocArg };
244 return cast<ConstantInt>(
getArgOperand(SizeArg))->getZExtValue();
248 return cast<ConstantInt>(
getArgOperand(AlignArg))->getAlignValue();
272 auto ID =
I->getIntrinsicID();
273 return ID == Intrinsic::coro_id_retcon ||
274 ID == Intrinsic::coro_id_retcon_once;
277 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
286 return I->getIntrinsicID() == Intrinsic::coro_id_retcon;
289 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
298 return I->getIntrinsicID() == Intrinsic::coro_id_retcon_once;
301 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
307 enum { SizeArg, AlignArg, StorageArg, AsyncFuncPtrArg };
316 return cast<ConstantInt>(
getArgOperand(SizeArg))->getZExtValue();
321 return cast<ConstantInt>(
getArgOperand(AlignArg))->getAlignValue();
331 return Arg->getZExtValue();
341 return cast<GlobalVariable>(
347 auto ID =
I->getIntrinsicID();
348 return ID == Intrinsic::coro_id_async;
352 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
358 enum { AsyncFuncPtrArg };
362 return cast<GlobalVariable>(
368 return I->getIntrinsicID() == Intrinsic::coro_async_context_alloc;
371 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
377 enum { AsyncContextArg };
386 return I->getIntrinsicID() == Intrinsic::coro_async_context_dealloc;
389 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
400 return I->getIntrinsicID() == Intrinsic::coro_async_resume;
403 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
412 return I->getIntrinsicID() == Intrinsic::coro_async_size_replace;
415 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
424 return I->getIntrinsicID() == Intrinsic::coro_frame;
427 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
433 enum { IdArg, FrameArg };
440 return I->getIntrinsicID() == Intrinsic::coro_free;
443 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
450 enum { IdArg, MemArg, CustomABIArg };
462 return cast<ConstantInt>(
getArgOperand(CustomABIArg))->getZExtValue();
469 return I->getIntrinsicID() == Intrinsic::coro_begin ||
470 I->getIntrinsicID() == Intrinsic::coro_begin_custom_abi;
473 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
482 return I->getIntrinsicID() == Intrinsic::coro_save;
485 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
491 enum { FrameArg, AlignArg, FromArg };
503 return cast<ConstantInt>(
getArgOperand(AlignArg))->getAlignValue();
508 return I->getIntrinsicID() == Intrinsic::coro_promise;
511 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
521 return I->getIntrinsicID() == Intrinsic::coro_suspend ||
522 I->getIntrinsicID() == Intrinsic::coro_suspend_async ||
523 I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
526 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
532 enum { SaveArg, FinalArg };
537 if (
auto *SI = dyn_cast<CoroSaveInst>(Arg))
539 assert(isa<ConstantTokenNone>(Arg));
544 return cast<Constant>(
getArgOperand(FinalArg))->isOneValue();
549 return I->getIntrinsicID() == Intrinsic::coro_suspend;
552 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
557 if (
auto Suspend = dyn_cast<CoroSuspendInst>(
this))
558 return Suspend->getCoroSave();
576 return Arg->getZExtValue();
580 return cast<Function>(
585 return cast<CoroAsyncResumeInst>(
590 return cast<Function>(
596 return I->getIntrinsicID() == Intrinsic::coro_suspend_async;
599 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
621 return I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
624 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
633 return I->getIntrinsicID() == Intrinsic::coro_size;
636 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
645 return I->getIntrinsicID() == Intrinsic::coro_align;
648 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
674 return I->getIntrinsicID() == Intrinsic::coro_end_results;
677 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
682 enum { FrameArg, UnwindArg, TokenArg };
687 return cast<Constant>(
getArgOperand(UnwindArg))->isOneValue();
701 auto ID =
I->getIntrinsicID();
702 return ID == Intrinsic::coro_end ||
ID == Intrinsic::coro_end_async;
705 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
714 return I->getIntrinsicID() == Intrinsic::coro_end;
717 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
723 enum { FrameArg, UnwindArg, MustTailCallFuncArg };
732 return cast<Function>(
738 return I->getIntrinsicID() == Intrinsic::coro_end_async;
741 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
747 enum { SizeArg, AlignArg };
752 return cast<ConstantInt>(
getArgOperand(AlignArg))->getAlignValue();
757 return I->getIntrinsicID() == Intrinsic::coro_alloca_alloc;
760 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
775 return I->getIntrinsicID() == Intrinsic::coro_alloca_get;
778 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
793 return I->getIntrinsicID() == Intrinsic::coro_alloca_free;
796 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t IntrinsicInst * II
int64_t getSExtValue() const
Get sign extended value.
an instruction to allocate memory on the stack
bool isFallthrough() const
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
CoroEndResults * getResults() const
This represents a common base class for llvm.coro.id instructions.
IntrinsicInst * getCoroBegin()
static bool classof(const IntrinsicInst *I)
static bool classof(const Value *V)
CoroAllocInst * getCoroAlloc()
This represents either the llvm.coro.id.retcon or llvm.coro.id.retcon.once instruction.
static bool classof(const IntrinsicInst *I)
Value * getStorage() const
Align getStorageAlignment() const
Function * getPrototype() const
Return the prototype for the continuation function.
uint64_t getStorageSize() const
LLVM_ABI void checkWellFormed() const
Function * getAllocFunction() const
Return the function to use for allocating memory.
static bool classof(const Value *V)
Function * getDeallocFunction() const
Return the function to use for deallocating memory.
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
CoroSaveInst * getCoroSave() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
ConstantArray - Constant Array Declarations.
This is the shared class of boolean and integer constants.
const APInt & getValue() const
Return the constant as an APInt value reference.
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
This is an important base class in LLVM.
This represents the llvm.coro.align instruction.
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
This represents the llvm.coro.alloc instruction.
static bool classof(const IntrinsicInst *I)
static bool classof(const Value *V)
This represents the llvm.coro.alloca.alloc instruction.
static bool classof(const IntrinsicInst *I)
Align getAlignment() const
static bool classof(const Value *V)
This represents the llvm.coro.alloca.free instruction.
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
CoroAllocaAllocInst * getAlloc() const
This represents the llvm.coro.alloca.get instruction.
static bool classof(const Value *V)
CoroAllocaAllocInst * getAlloc() const
static bool classof(const IntrinsicInst *I)
This represents the llvm.coro.context.alloc instruction.
static bool classof(const IntrinsicInst *I)
static bool classof(const Value *V)
GlobalVariable * getAsyncFunctionPointer() const
This represents the llvm.coro.context.dealloc instruction.
Value * getAsyncContext() const
static bool classof(const IntrinsicInst *I)
static bool classof(const Value *V)
This represents the llvm.coro.end instruction.
Function * getMustTailCallFunction() const
LLVM_ABI void checkWellFormed() const
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
This represents the llvm.coro.async.resume instruction.
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
This represents the llvm.coro.async.size.replace instruction.
static bool classof(const IntrinsicInst *I)
static bool classof(const Value *V)
This represents the llvm.coro.await.suspend.{void,bool,handle} instructions.
static bool classof(const CallBase *CB)
static bool classof(const Value *V)
Value * getAwaiter() const
Function * getWrapperFunction() const
This class represents the llvm.coro.begin or llvm.coro.begin.custom.abi instructions.
AnyCoroIdInst * getId() const
static bool classof(const IntrinsicInst *I)
static bool classof(const Value *V)
bool hasCustomABI() const
This represents the llvm.coro.end instruction.
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
This represents the llvm.end.results instruction.
op_iterator retval_begin()
const_op_iterator retval_begin() const
iterator_range< const_op_iterator > return_values() const
iterator_range< op_iterator > return_values()
static bool classof(const IntrinsicInst *I)
const_op_iterator retval_end() const
static bool classof(const Value *V)
unsigned numReturns() const
This represents the llvm.coro.frame instruction.
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
This represents the llvm.coro.free instruction.
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
This represents the llvm.coro.id.async instruction.
Align getStorageAlignment() const
The alignment of the initial async function context.
uint64_t getStorageSize() const
The initial async function context size.
LLVM_ABI void checkWellFormed() const
GlobalVariable * getAsyncFunctionPointer() const
Return the async function pointer address.
static bool classof(const IntrinsicInst *I)
Value * getStorage() const
The async context parameter.
unsigned getStorageArgumentIndex() const
static bool classof(const Value *V)
This represents the llvm.coro.id instruction.
static bool classof(const Value *V)
void setInfo(Constant *C)
static bool classof(const IntrinsicInst *I)
Function * getCoroutine() const
Constant * getRawInfo() const
AllocaInst * getPromise() const
This represents the llvm.coro.id.retcon instruction.
static bool classof(const IntrinsicInst *I)
static bool classof(const Value *V)
This represents the llvm.coro.id.retcon.once instruction.
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
This represents the llvm.coro.promise instruction.
static bool classof(const Value *V)
Align getAlignment() const
The required alignment of the promise.
bool isFromPromise() const
Are we translating from the frame to the promise (false) or from the promise to the frame (true)?
static bool classof(const IntrinsicInst *I)
This represents the llvm.coro.save instruction.
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
This represents the llvm.coro.size instruction.
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
This class represents the llvm.coro.subfn.addr instruction.
static bool classof(const Value *V)
ResumeKind getIndex() const
ConstantInt * getRawIndex() const
static bool classof(const IntrinsicInst *I)
This represents the llvm.coro.suspend.async instruction.
@ AsyncContextProjectionArg
Function * getAsyncContextProjectionFunction() const
static bool classof(const Value *V)
unsigned getStorageArgumentIndex() const
LLVM_ABI void checkWellFormed() const
CoroAsyncResumeInst * getResumeFunction() const
static bool classof(const IntrinsicInst *I)
Function * getMustTailCallFunction() const
This represents the llvm.coro.suspend instruction.
CoroSaveInst * getCoroSave() const
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
This represents the llvm.coro.suspend.retcon instruction.
op_iterator value_begin()
static bool classof(const Value *V)
const_op_iterator value_begin() const
const_op_iterator value_end() const
iterator_range< const_op_iterator > value_operands() const
iterator_range< op_iterator > value_operands()
static bool classof(const IntrinsicInst *I)
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
const ParentTy * getParent() const
self_iterator getIterator()
A range adaptor for a pair of iterators.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool hasOutlinedParts() const
ConstantStruct * OutlinedParts