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 enum { AwaiterArg, FrameArg, WrapperArg };
94 return cast<Function>(getArgOperand(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)
134 auto ID =
I->getIntrinsicID();
135 return ID == Intrinsic::coro_id ||
ID == Intrinsic::coro_id_retcon ||
136 ID == Intrinsic::coro_id_retcon_once ||
137 ID == Intrinsic::coro_id_async;
141 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
147 enum { AlignArg, PromiseArg, CoroutineArg, InfoArg };
151 Value *Arg = getArgOperand(PromiseArg);
152 return isa<ConstantPointerNull>(Arg)
158 Value *Arg = getArgOperand(PromiseArg);
159 setArgOperand(PromiseArg, ConstantPointerNull::get(
160 PointerType::getUnqual(getContext())));
161 if (isa<AllocaInst>(Arg))
163 assert((isa<BitCastInst>(Arg) || isa<GetElementPtrInst>(Arg)) &&
164 "unexpected instruction designating the promise");
167 auto *Inst = cast<Instruction>(Arg);
168 if (Inst->use_empty()) {
169 Inst->eraseFromParent();
197 auto *GV = dyn_cast<GlobalVariable>(getRawInfo());
201 assert(GV->isConstant() && GV->hasDefinitiveInitializer());
202 Constant *Initializer = GV->getInitializer();
203 if ((Result.OutlinedParts = dyn_cast<ConstantStruct>(Initializer)))
206 Result.Resumers = cast<ConstantArray>(Initializer);
210 return cast<Constant>(getArgOperand(InfoArg)->stripPointerCasts());
216 return cast<Function>(getArgOperand(CoroutineArg)->stripPointerCasts());
219 assert(isa<ConstantPointerNull>(getArgOperand(CoroutineArg)) &&
220 "Coroutine argument is already assigned");
226 return I->getIntrinsicID() == Intrinsic::coro_id;
229 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
236 enum { SizeArg, AlignArg, StorageArg, PrototypeArg, AllocArg, DeallocArg };
239 void checkWellFormed()
const;
242 return cast<ConstantInt>(getArgOperand(SizeArg))->getZExtValue();
246 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
250 return getArgOperand(StorageArg);
257 return cast<Function>(getArgOperand(PrototypeArg)->stripPointerCasts());
262 return cast<Function>(getArgOperand(AllocArg)->stripPointerCasts());
267 return cast<Function>(getArgOperand(DeallocArg)->stripPointerCasts());
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));
287 return I->getIntrinsicID() == Intrinsic::coro_id_retcon;
290 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
300 return I->getIntrinsicID() == Intrinsic::coro_id_retcon_once;
303 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
309 enum { SizeArg, AlignArg, StorageArg, AsyncFuncPtrArg };
312 void checkWellFormed()
const;
318 return cast<ConstantInt>(getArgOperand(SizeArg))->getZExtValue();
323 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
328 return getParent()->getParent()->getArg(getStorageArgumentIndex());
332 auto *Arg = cast<ConstantInt>(getArgOperand(StorageArg));
333 return Arg->getZExtValue();
343 return cast<GlobalVariable>(
344 getArgOperand(AsyncFuncPtrArg)->stripPointerCasts());
349 auto ID =
I->getIntrinsicID();
350 return ID == Intrinsic::coro_id_async;
354 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
360 enum { AsyncFuncPtrArg };
364 return cast<GlobalVariable>(
365 getArgOperand(AsyncFuncPtrArg)->stripPointerCasts());
370 return I->getIntrinsicID() == Intrinsic::coro_async_context_alloc;
373 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
380 enum { AsyncContextArg };
389 return I->getIntrinsicID() == Intrinsic::coro_async_context_dealloc;
392 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
403 return I->getIntrinsicID() == Intrinsic::coro_async_resume;
406 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
415 return I->getIntrinsicID() == Intrinsic::coro_async_size_replace;
418 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
427 return I->getIntrinsicID() == Intrinsic::coro_frame;
430 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
436 enum { IdArg, FrameArg };
443 return I->getIntrinsicID() == Intrinsic::coro_free;
446 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
452 enum { IdArg, MemArg };
456 return cast<AnyCoroIdInst>(getArgOperand(IdArg));
463 return I->getIntrinsicID() == Intrinsic::coro_begin;
466 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
475 return I->getIntrinsicID() == Intrinsic::coro_save;
478 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
484 enum { FrameArg, AlignArg, FromArg };
490 return cast<Constant>(getArgOperand(FromArg))->isOneValue();
496 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
501 return I->getIntrinsicID() == Intrinsic::coro_promise;
504 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
514 return I->getIntrinsicID() == Intrinsic::coro_suspend ||
515 I->getIntrinsicID() == Intrinsic::coro_suspend_async ||
516 I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
519 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
525 enum { SaveArg, FinalArg };
529 Value *Arg = getArgOperand(SaveArg);
530 if (
auto *
SI = dyn_cast<CoroSaveInst>(Arg))
532 assert(isa<ConstantTokenNone>(Arg));
537 return cast<Constant>(getArgOperand(FinalArg))->isOneValue();
542 return I->getIntrinsicID() == Intrinsic::coro_suspend;
545 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
550 if (
auto Suspend = dyn_cast<CoroSuspendInst>(
this))
551 return Suspend->getCoroSave();
565 void checkWellFormed()
const;
568 auto *Arg = cast<ConstantInt>(getArgOperand(StorageArgNoArg));
569 return Arg->getZExtValue();
573 return cast<Function>(
574 getArgOperand(AsyncContextProjectionArg)->stripPointerCasts());
578 return cast<CoroAsyncResumeInst>(
579 getArgOperand(ResumeFunctionArg)->stripPointerCasts());
583 return cast<Function>(
584 getArgOperand(MustTailCallFuncArg)->stripPointerCasts());
589 return I->getIntrinsicID() == Intrinsic::coro_suspend_async;
592 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
606 return make_range(value_begin(), value_end());
609 return make_range(value_begin(), value_end());
614 return I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
617 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
626 return I->getIntrinsicID() == Intrinsic::coro_size;
629 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
638 return I->getIntrinsicID() == Intrinsic::coro_align;
641 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
655 return make_range(retval_begin(), retval_end());
658 return make_range(retval_begin(), retval_end());
662 return std::distance(retval_begin(), retval_end());
667 return I->getIntrinsicID() == Intrinsic::coro_end_results;
670 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
675 enum { FrameArg, UnwindArg, TokenArg };
680 return cast<Constant>(getArgOperand(UnwindArg))->isOneValue();
684 return !isa<ConstantTokenNone>(getArgOperand(TokenArg));
689 return cast<CoroEndResults>(getArgOperand(TokenArg));
694 auto ID =
I->getIntrinsicID();
695 return ID == Intrinsic::coro_end ||
ID == Intrinsic::coro_end_async;
698 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
707 return I->getIntrinsicID() == Intrinsic::coro_end;
710 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
716 enum { FrameArg, UnwindArg, MustTailCallFuncArg };
719 void checkWellFormed()
const;
725 return cast<Function>(
726 getArgOperand(MustTailCallFuncArg)->stripPointerCasts());
731 return I->getIntrinsicID() == Intrinsic::coro_end_async;
734 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
740 enum { SizeArg, AlignArg };
743 return getArgOperand(SizeArg);
746 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
751 return I->getIntrinsicID() == Intrinsic::coro_alloca_alloc;
754 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
763 return cast<CoroAllocaAllocInst>(getArgOperand(AllocArg));
768 return I->getIntrinsicID() == Intrinsic::coro_alloca_get;
771 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
780 return cast<CoroAllocaAllocInst>(getArgOperand(AllocArg));
785 return I->getIntrinsicID() == Intrinsic::coro_alloca_free;
788 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
VarLocInsertPt getNextNode(const DbgRecord *DVR)
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
#define LLVM_LIBRARY_VISIBILITY
static Function * getFunction(Constant *C)
uint64_t IntrinsicInst * II
StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach)
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)
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
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...
ConstantArray - Constant Array Declarations.
This is the shared class of boolean and integer constants.
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 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 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.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.
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)
@ AsyncContextProjectionArg
unsigned getStorageArgumentIndex() 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)
A wrapper class for inspecting calls to intrinsic functions.
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.
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