25#ifndef LLVM_TRANSFORMS_COROUTINES_COROINSTR_H
26#define LLVM_TRANSFORMS_COROUTINES_COROINSTR_H
36 enum { FrameArg, IndexArg };
52 "unexpected CoroSubFnInst index argument");
62 return I->getIntrinsicID() == Intrinsic::coro_subfn_addr;
65 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
74 return I->getIntrinsicID() == Intrinsic::coro_alloc;
77 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
86 enum { AwaiterArg, FrameArg, WrapperArg };
100 auto IID = CF->getIntrinsicID();
101 return IID == Intrinsic::coro_await_suspend_void ||
102 IID == Intrinsic::coro_await_suspend_bool ||
103 IID == Intrinsic::coro_await_suspend_handle;
110 return isa<CallBase>(V) &&
classof(cast<CallBase>(V));
119 if (
auto *CA = dyn_cast<CoroAllocInst>(U))
126 if (
auto *
II = dyn_cast<IntrinsicInst>(U))
127 if (
II->getIntrinsicID() == Intrinsic::coro_begin ||
128 II->getIntrinsicID() == Intrinsic::coro_begin_custom_abi)
135 auto ID =
I->getIntrinsicID();
136 return ID == Intrinsic::coro_id ||
ID == Intrinsic::coro_id_retcon ||
137 ID == Intrinsic::coro_id_retcon_once ||
138 ID == Intrinsic::coro_id_async;
142 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
148 enum { AlignArg, PromiseArg, CoroutineArg, InfoArg };
153 return isa<ConstantPointerNull>(Arg)
162 if (isa<AllocaInst>(Arg))
164 assert((isa<BitCastInst>(Arg) || isa<GetElementPtrInst>(Arg)) &&
165 "unexpected instruction designating the promise");
168 auto *Inst = cast<Instruction>(Arg);
169 if (Inst->use_empty()) {
170 Inst->eraseFromParent();
198 auto *GV = dyn_cast<GlobalVariable>(
getRawInfo());
202 assert(GV->isConstant() && GV->hasDefinitiveInitializer());
203 Constant *Initializer = GV->getInitializer();
204 if ((Result.OutlinedParts = dyn_cast<ConstantStruct>(Initializer)))
207 Result.Resumers = cast<ConstantArray>(Initializer);
221 "Coroutine argument is already assigned");
227 return I->getIntrinsicID() == Intrinsic::coro_id;
230 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
237 enum { SizeArg, AlignArg, StorageArg, PrototypeArg, AllocArg, DeallocArg };
243 return cast<ConstantInt>(
getArgOperand(SizeArg))->getZExtValue();
247 return cast<ConstantInt>(
getArgOperand(AlignArg))->getAlignValue();
271 auto ID =
I->getIntrinsicID();
272 return ID == Intrinsic::coro_id_retcon ||
273 ID == Intrinsic::coro_id_retcon_once;
276 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
285 return I->getIntrinsicID() == Intrinsic::coro_id_retcon;
288 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
297 return I->getIntrinsicID() == Intrinsic::coro_id_retcon_once;
300 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
306 enum { SizeArg, AlignArg, StorageArg, AsyncFuncPtrArg };
315 return cast<ConstantInt>(
getArgOperand(SizeArg))->getZExtValue();
320 return cast<ConstantInt>(
getArgOperand(AlignArg))->getAlignValue();
330 return Arg->getZExtValue();
340 return cast<GlobalVariable>(
346 auto ID =
I->getIntrinsicID();
347 return ID == Intrinsic::coro_id_async;
351 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
357 enum { AsyncFuncPtrArg };
361 return cast<GlobalVariable>(
367 return I->getIntrinsicID() == Intrinsic::coro_async_context_alloc;
370 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
376 enum { AsyncContextArg };
385 return I->getIntrinsicID() == Intrinsic::coro_async_context_dealloc;
388 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
399 return I->getIntrinsicID() == Intrinsic::coro_async_resume;
402 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
411 return I->getIntrinsicID() == Intrinsic::coro_async_size_replace;
414 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
423 return I->getIntrinsicID() == Intrinsic::coro_frame;
426 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
432 enum { IdArg, FrameArg };
439 return I->getIntrinsicID() == Intrinsic::coro_free;
442 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
449 enum { IdArg, MemArg, CustomABIArg };
461 return cast<ConstantInt>(
getArgOperand(CustomABIArg))->getZExtValue();
468 return I->getIntrinsicID() == Intrinsic::coro_begin ||
469 I->getIntrinsicID() == Intrinsic::coro_begin_custom_abi;
472 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
481 return I->getIntrinsicID() == Intrinsic::coro_save;
484 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
490 enum { FrameArg, AlignArg, FromArg };
502 return cast<ConstantInt>(
getArgOperand(AlignArg))->getAlignValue();
507 return I->getIntrinsicID() == Intrinsic::coro_promise;
510 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
520 return I->getIntrinsicID() == Intrinsic::coro_suspend ||
521 I->getIntrinsicID() == Intrinsic::coro_suspend_async ||
522 I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
525 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
531 enum { SaveArg, FinalArg };
536 if (
auto *SI = dyn_cast<CoroSaveInst>(Arg))
538 assert(isa<ConstantTokenNone>(Arg));
543 return cast<Constant>(
getArgOperand(FinalArg))->isOneValue();
548 return I->getIntrinsicID() == Intrinsic::coro_suspend;
551 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
556 if (
auto Suspend = dyn_cast<CoroSuspendInst>(
this))
557 return Suspend->getCoroSave();
575 return Arg->getZExtValue();
579 return cast<Function>(
584 return cast<CoroAsyncResumeInst>(
589 return cast<Function>(
595 return I->getIntrinsicID() == Intrinsic::coro_suspend_async;
598 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
620 return I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
623 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
632 return I->getIntrinsicID() == Intrinsic::coro_size;
635 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
644 return I->getIntrinsicID() == Intrinsic::coro_align;
647 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
673 return I->getIntrinsicID() == Intrinsic::coro_end_results;
676 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
681 enum { FrameArg, UnwindArg, TokenArg };
686 return cast<Constant>(
getArgOperand(UnwindArg))->isOneValue();
700 auto ID =
I->getIntrinsicID();
701 return ID == Intrinsic::coro_end ||
ID == Intrinsic::coro_end_async;
704 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
713 return I->getIntrinsicID() == Intrinsic::coro_end;
716 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
722 enum { FrameArg, UnwindArg, MustTailCallFuncArg };
731 return cast<Function>(
737 return I->getIntrinsicID() == Intrinsic::coro_end_async;
740 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
746 enum { SizeArg, AlignArg };
751 return cast<ConstantInt>(
getArgOperand(AlignArg))->getAlignValue();
756 return I->getIntrinsicID() == Intrinsic::coro_alloca_alloc;
759 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
774 return I->getIntrinsicID() == Intrinsic::coro_alloca_get;
777 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
792 return I->getIntrinsicID() == Intrinsic::coro_alloca_free;
795 return isa<IntrinsicInst>(V) &&
classof(cast<IntrinsicInst>(V));
uint64_t IntrinsicInst * II
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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
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 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
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.
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.
Function * getAsyncContextProjectionFunction() const
static bool classof(const Value *V)
unsigned getStorageArgumentIndex() const
void checkWellFormed() const
@ AsyncContextProjectionArg
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)
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.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVMContext & getContext() const
All values hold a context through their type.
const ParentTy * getParent() const
Instruction * getNextNode()
Get the next node, or nullptr for the list tail.
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