25#ifndef LLVM_LIB_TRANSFORMS_COROUTINES_COROINSTR_H
26#define LLVM_LIB_TRANSFORMS_COROUTINES_COROINSTR_H
36 enum { FrameArg, IndexArg };
45 IndexFirst = RestartTrigger
50 int64_t
Index = getRawIndex()->getValue().getSExtValue();
52 "unexpected CoroSubFnInst index argument");
57 return cast<ConstantInt>(getArgOperand(IndexArg));
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 if (
auto *CA = dyn_cast<CoroAllocInst>(U))
93 if (
auto *II = dyn_cast<IntrinsicInst>(U))
94 if (II->getIntrinsicID() == Intrinsic::coro_begin)
101 auto ID =
I->getIntrinsicID();
102 return ID == Intrinsic::coro_id ||
ID == Intrinsic::coro_id_retcon ||
103 ID == Intrinsic::coro_id_retcon_once ||
104 ID == Intrinsic::coro_id_async;
108 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
114 enum { AlignArg, PromiseArg, CoroutineArg, InfoArg };
118 Value *
Arg = getArgOperand(PromiseArg);
119 return isa<ConstantPointerNull>(
Arg)
121 : cast<AllocaInst>(
Arg->stripPointerCasts());
125 Value *
Arg = getArgOperand(PromiseArg);
126 setArgOperand(PromiseArg,
128 if (isa<AllocaInst>(
Arg))
130 assert((isa<BitCastInst>(
Arg) || isa<GetElementPtrInst>(
Arg)) &&
131 "unexpected instruction designating the promise");
134 auto *Inst = cast<Instruction>(
Arg);
135 if (Inst->use_empty()) {
136 Inst->eraseFromParent();
139 Inst->moveBefore(getCoroBegin()->getNextNode());
164 auto *GV = dyn_cast<GlobalVariable>(getRawInfo());
168 assert(GV->isConstant() && GV->hasDefinitiveInitializer());
169 Constant *Initializer = GV->getInitializer();
170 if ((Result.OutlinedParts = dyn_cast<ConstantStruct>(Initializer)))
173 Result.Resumers = cast<ConstantArray>(Initializer);
177 return cast<Constant>(getArgOperand(InfoArg)->stripPointerCasts());
183 return cast<Function>(getArgOperand(CoroutineArg)->stripPointerCasts());
186 assert(isa<ConstantPointerNull>(getArgOperand(CoroutineArg)) &&
187 "Coroutine argument is already assigned");
189 setArgOperand(CoroutineArg,
195 return I->getIntrinsicID() == Intrinsic::coro_id;
198 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
205 enum { SizeArg, AlignArg, StorageArg, PrototypeArg, AllocArg, DeallocArg };
208 void checkWellFormed()
const;
211 return cast<ConstantInt>(getArgOperand(SizeArg))->getZExtValue();
215 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
219 return getArgOperand(StorageArg);
226 return cast<Function>(getArgOperand(PrototypeArg)->stripPointerCasts());
231 return cast<Function>(getArgOperand(AllocArg)->stripPointerCasts());
236 return cast<Function>(getArgOperand(DeallocArg)->stripPointerCasts());
241 auto ID =
I->getIntrinsicID();
242 return ID == Intrinsic::coro_id_retcon
243 ||
ID == Intrinsic::coro_id_retcon_once;
246 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
256 return I->getIntrinsicID() == Intrinsic::coro_id_retcon;
259 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
269 return I->getIntrinsicID() == Intrinsic::coro_id_retcon_once;
272 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
278 enum { SizeArg, AlignArg, StorageArg, AsyncFuncPtrArg };
281 void checkWellFormed()
const;
287 return cast<ConstantInt>(getArgOperand(SizeArg))->getZExtValue();
292 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
297 return getParent()->getParent()->getArg(getStorageArgumentIndex());
301 auto *
Arg = cast<ConstantInt>(getArgOperand(StorageArg));
302 return Arg->getZExtValue();
312 return cast<GlobalVariable>(
313 getArgOperand(AsyncFuncPtrArg)->stripPointerCasts());
318 auto ID =
I->getIntrinsicID();
319 return ID == Intrinsic::coro_id_async;
323 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
329 enum { AsyncFuncPtrArg };
333 return cast<GlobalVariable>(
334 getArgOperand(AsyncFuncPtrArg)->stripPointerCasts());
339 return I->getIntrinsicID() == Intrinsic::coro_async_context_alloc;
342 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
349 enum { AsyncContextArg };
358 return I->getIntrinsicID() == Intrinsic::coro_async_context_dealloc;
361 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
372 return I->getIntrinsicID() == Intrinsic::coro_async_resume;
375 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
384 return I->getIntrinsicID() == Intrinsic::coro_async_size_replace;
387 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
396 return I->getIntrinsicID() == Intrinsic::coro_frame;
399 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
405 enum { IdArg, FrameArg };
412 return I->getIntrinsicID() == Intrinsic::coro_free;
415 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
421 enum { IdArg, MemArg };
425 return cast<AnyCoroIdInst>(getArgOperand(IdArg));
432 return I->getIntrinsicID() == Intrinsic::coro_begin;
435 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
444 return I->getIntrinsicID() == Intrinsic::coro_save;
447 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
453 enum { FrameArg, AlignArg, FromArg };
459 return cast<Constant>(getArgOperand(FromArg))->isOneValue();
465 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
470 return I->getIntrinsicID() == Intrinsic::coro_promise;
473 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
483 return I->getIntrinsicID() == Intrinsic::coro_suspend ||
484 I->getIntrinsicID() == Intrinsic::coro_suspend_async ||
485 I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
488 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
494 enum { SaveArg, FinalArg };
498 Value *
Arg = getArgOperand(SaveArg);
499 if (
auto *
SI = dyn_cast<CoroSaveInst>(
Arg))
506 return cast<Constant>(getArgOperand(FinalArg))->isOneValue();
511 return I->getIntrinsicID() == Intrinsic::coro_suspend;
514 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
519 if (
auto Suspend = dyn_cast<CoroSuspendInst>(
this))
520 return Suspend->getCoroSave();
534 void checkWellFormed()
const;
537 auto *
Arg = cast<ConstantInt>(getArgOperand(StorageArgNoArg));
538 return Arg->getZExtValue();
542 return cast<Function>(
543 getArgOperand(AsyncContextProjectionArg)->stripPointerCasts());
547 return cast<CoroAsyncResumeInst>(
548 getArgOperand(ResumeFunctionArg)->stripPointerCasts());
552 return cast<Function>(
553 getArgOperand(MustTailCallFuncArg)->stripPointerCasts());
558 return I->getIntrinsicID() == Intrinsic::coro_suspend_async;
561 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
575 return make_range(value_begin(), value_end());
578 return make_range(value_begin(), value_end());
583 return I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
586 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
595 return I->getIntrinsicID() == Intrinsic::coro_size;
598 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
607 return I->getIntrinsicID() == Intrinsic::coro_align;
610 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
615 enum { FrameArg, UnwindArg };
620 return cast<Constant>(getArgOperand(UnwindArg))->isOneValue();
625 auto ID =
I->getIntrinsicID();
626 return ID == Intrinsic::coro_end ||
ID == Intrinsic::coro_end_async;
629 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
638 return I->getIntrinsicID() == Intrinsic::coro_end;
641 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
647 enum { FrameArg, UnwindArg, MustTailCallFuncArg };
650 void checkWellFormed()
const;
656 return cast<Function>(
657 getArgOperand(MustTailCallFuncArg)->stripPointerCasts());
662 return I->getIntrinsicID() == Intrinsic::coro_end_async;
665 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
671 enum { SizeArg, AlignArg };
674 return getArgOperand(SizeArg);
677 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
682 return I->getIntrinsicID() == Intrinsic::coro_alloca_alloc;
685 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
694 return cast<CoroAllocaAllocInst>(getArgOperand(AllocArg));
699 return I->getIntrinsicID() == Intrinsic::coro_alloca_get;
702 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
711 return cast<CoroAllocaAllocInst>(getArgOperand(AllocArg));
716 return I->getIntrinsicID() == Intrinsic::coro_alloca_free;
719 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static const Function * getParent(const Value *V)
#define LLVM_LIBRARY_VISIBILITY
LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked into a shared library,...
static Function * getFunction(Constant *C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
an instruction to allocate memory on the stack
bool isFallthrough() const
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
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
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
ConstantArray - Constant Array Declarations.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
This is the shared class of boolean and integer constants.
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
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 class represents the llvm.coro.begin instruction.
AnyCoroIdInst * getId() const
static bool classof(const IntrinsicInst *I)
static bool classof(const Value *V)
This represents the llvm.coro.end instruction.
static bool classof(const Value *V)
static bool classof(const IntrinsicInst *I)
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.
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
@ 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)
A wrapper class for inspecting calls to intrinsic functions.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
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.
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