LLVM 19.0.0git
CoroInstr.h
Go to the documentation of this file.
1//===-- CoroInstr.h - Coroutine Intrinsics Instruction Wrappers -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8// This file defines classes that make it really easy to deal with intrinsic
9// functions with the isa/dyncast family of functions. In particular, this
10// allows you to do things like:
11//
12// if (auto *SF = dyn_cast<CoroSubFnInst>(Inst))
13// ... SF->getFrame() ...
14//
15// All intrinsic function calls are instances of the call instruction, so these
16// are all subclasses of the CallInst class. Note that none of these classes
17// has state or virtual methods, which is an important part of this gross/neat
18// hack working.
19//
20// The helpful comment above is borrowed from llvm/IntrinsicInst.h, we keep
21// coroutine intrinsic wrappers here since they are only used by the passes in
22// the Coroutine library.
23//===----------------------------------------------------------------------===//
24
25#ifndef LLVM_LIB_TRANSFORMS_COROUTINES_COROINSTR_H
26#define LLVM_LIB_TRANSFORMS_COROUTINES_COROINSTR_H
27
31
32namespace llvm {
33
34/// This class represents the llvm.coro.subfn.addr instruction.
36 enum { FrameArg, IndexArg };
37
38public:
40 RestartTrigger = -1,
45 IndexFirst = RestartTrigger
46 };
47
48 Value *getFrame() const { return getArgOperand(FrameArg); }
50 int64_t Index = getRawIndex()->getValue().getSExtValue();
51 assert(Index >= IndexFirst && Index < IndexLast &&
52 "unexpected CoroSubFnInst index argument");
53 return static_cast<ResumeKind>(Index);
54 }
55
57 return cast<ConstantInt>(getArgOperand(IndexArg));
58 }
59
60 // Methods to support type inquiry through isa, cast, and dyn_cast:
61 static bool classof(const IntrinsicInst *I) {
62 return I->getIntrinsicID() == Intrinsic::coro_subfn_addr;
63 }
64 static bool classof(const Value *V) {
65 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
66 }
67};
68
69/// This represents the llvm.coro.alloc instruction.
71public:
72 // Methods to support type inquiry through isa, cast, and dyn_cast:
73 static bool classof(const IntrinsicInst *I) {
74 return I->getIntrinsicID() == Intrinsic::coro_alloc;
75 }
76 static bool classof(const Value *V) {
77 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
78 }
79};
80
81/// This represents the llvm.coro.await.suspend instruction.
82// FIXME: add callback metadata
83// FIXME: make a proper IntrinisicInst. Currently this is not possible,
84// because llvm.coro.await.suspend can be invoked.
86 enum { AwaiterArg, FrameArg, WrapperArg };
87
88public:
89 Value *getAwaiter() const { return getArgOperand(AwaiterArg); }
90
91 Value *getFrame() const { return getArgOperand(FrameArg); }
92
94 return cast<Function>(getArgOperand(WrapperArg));
95 }
96
97 // Methods to support type inquiry through isa, cast, and dyn_cast:
98 static bool classof(const CallBase *CB) {
99 if (const Function *CF = CB->getCalledFunction()) {
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;
104 }
105
106 return false;
107 }
108
109 static bool classof(const Value *V) {
110 return isa<CallBase>(V) && classof(cast<CallBase>(V));
111 }
112};
113
114/// This represents a common base class for llvm.coro.id instructions.
116public:
118 for (User *U : users())
119 if (auto *CA = dyn_cast<CoroAllocInst>(U))
120 return CA;
121 return nullptr;
122 }
123
125 for (User *U : users())
126 if (auto *II = dyn_cast<IntrinsicInst>(U))
127 if (II->getIntrinsicID() == Intrinsic::coro_begin)
128 return II;
129 llvm_unreachable("no coro.begin associated with coro.id");
130 }
131
132 // Methods to support type inquiry through isa, cast, and dyn_cast:
133 static bool classof(const IntrinsicInst *I) {
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;
138 }
139
140 static bool classof(const Value *V) {
141 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
142 }
143};
144
145/// This represents the llvm.coro.id instruction.
147 enum { AlignArg, PromiseArg, CoroutineArg, InfoArg };
148
149public:
151 Value *Arg = getArgOperand(PromiseArg);
152 return isa<ConstantPointerNull>(Arg)
153 ? nullptr
154 : cast<AllocaInst>(Arg->stripPointerCasts());
155 }
156
158 Value *Arg = getArgOperand(PromiseArg);
159 setArgOperand(PromiseArg, ConstantPointerNull::get(
160 PointerType::getUnqual(getContext())));
161 if (isa<AllocaInst>(Arg))
162 return;
163 assert((isa<BitCastInst>(Arg) || isa<GetElementPtrInst>(Arg)) &&
164 "unexpected instruction designating the promise");
165 // TODO: Add a check that any remaining users of Inst are after coro.begin
166 // or add code to move the users after coro.begin.
167 auto *Inst = cast<Instruction>(Arg);
168 if (Inst->use_empty()) {
169 Inst->eraseFromParent();
170 return;
171 }
172 Inst->moveBefore(getCoroBegin()->getNextNode());
173 }
174
175 // Info argument of coro.id is
176 // fresh out of the frontend: null ;
177 // outlined : {Init, Return, Susp1, Susp2, ...} ;
178 // postsplit : [resume, destroy, cleanup] ;
179 //
180 // If parts of the coroutine were outlined to protect against undesirable
181 // code motion, these functions will be stored in a struct literal referred to
182 // by the Info parameter. Note: this is only needed before coroutine is split.
183 //
184 // After coroutine is split, resume functions are stored in an array
185 // referred to by this parameter.
186
187 struct Info {
188 ConstantStruct *OutlinedParts = nullptr;
189 ConstantArray *Resumers = nullptr;
190
191 bool hasOutlinedParts() const { return OutlinedParts != nullptr; }
192 bool isPostSplit() const { return Resumers != nullptr; }
193 bool isPreSplit() const { return !isPostSplit(); }
194 };
195 Info getInfo() const {
196 Info Result;
197 auto *GV = dyn_cast<GlobalVariable>(getRawInfo());
198 if (!GV)
199 return Result;
200
201 assert(GV->isConstant() && GV->hasDefinitiveInitializer());
202 Constant *Initializer = GV->getInitializer();
203 if ((Result.OutlinedParts = dyn_cast<ConstantStruct>(Initializer)))
204 return Result;
205
206 Result.Resumers = cast<ConstantArray>(Initializer);
207 return Result;
208 }
210 return cast<Constant>(getArgOperand(InfoArg)->stripPointerCasts());
211 }
212
213 void setInfo(Constant *C) { setArgOperand(InfoArg, C); }
214
216 return cast<Function>(getArgOperand(CoroutineArg)->stripPointerCasts());
217 }
219 assert(isa<ConstantPointerNull>(getArgOperand(CoroutineArg)) &&
220 "Coroutine argument is already assigned");
221 setArgOperand(CoroutineArg, getFunction());
222 }
223
224 // Methods to support type inquiry through isa, cast, and dyn_cast:
225 static bool classof(const IntrinsicInst *I) {
226 return I->getIntrinsicID() == Intrinsic::coro_id;
227 }
228 static bool classof(const Value *V) {
229 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
230 }
231};
232
233/// This represents either the llvm.coro.id.retcon or
234/// llvm.coro.id.retcon.once instruction.
236 enum { SizeArg, AlignArg, StorageArg, PrototypeArg, AllocArg, DeallocArg };
237
238public:
239 void checkWellFormed() const;
240
242 return cast<ConstantInt>(getArgOperand(SizeArg))->getZExtValue();
243 }
244
246 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
247 }
248
249 Value *getStorage() const {
250 return getArgOperand(StorageArg);
251 }
252
253 /// Return the prototype for the continuation function. The type,
254 /// attributes, and calling convention of the continuation function(s)
255 /// are taken from this declaration.
257 return cast<Function>(getArgOperand(PrototypeArg)->stripPointerCasts());
258 }
259
260 /// Return the function to use for allocating memory.
262 return cast<Function>(getArgOperand(AllocArg)->stripPointerCasts());
263 }
264
265 /// Return the function to use for deallocating memory.
267 return cast<Function>(getArgOperand(DeallocArg)->stripPointerCasts());
268 }
269
270 // Methods to support type inquiry through isa, cast, and dyn_cast:
271 static bool classof(const IntrinsicInst *I) {
272 auto ID = I->getIntrinsicID();
273 return ID == Intrinsic::coro_id_retcon
274 || ID == Intrinsic::coro_id_retcon_once;
275 }
276 static bool classof(const Value *V) {
277 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
278 }
279};
280
281/// This represents the llvm.coro.id.retcon instruction.
283 : public AnyCoroIdRetconInst {
284public:
285 // Methods to support type inquiry through isa, cast, and dyn_cast:
286 static bool classof(const IntrinsicInst *I) {
287 return I->getIntrinsicID() == Intrinsic::coro_id_retcon;
288 }
289 static bool classof(const Value *V) {
290 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
291 }
292};
293
294/// This represents the llvm.coro.id.retcon.once instruction.
296 : public AnyCoroIdRetconInst {
297public:
298 // Methods to support type inquiry through isa, cast, and dyn_cast:
299 static bool classof(const IntrinsicInst *I) {
300 return I->getIntrinsicID() == Intrinsic::coro_id_retcon_once;
301 }
302 static bool classof(const Value *V) {
303 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
304 }
305};
306
307/// This represents the llvm.coro.id.async instruction.
309 enum { SizeArg, AlignArg, StorageArg, AsyncFuncPtrArg };
310
311public:
312 void checkWellFormed() const;
313
314 /// The initial async function context size. The fields of which are reserved
315 /// for use by the frontend. The frame will be allocated as a tail of this
316 /// context.
318 return cast<ConstantInt>(getArgOperand(SizeArg))->getZExtValue();
319 }
320
321 /// The alignment of the initial async function context.
323 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
324 }
325
326 /// The async context parameter.
327 Value *getStorage() const {
328 return getParent()->getParent()->getArg(getStorageArgumentIndex());
329 }
330
331 unsigned getStorageArgumentIndex() const {
332 auto *Arg = cast<ConstantInt>(getArgOperand(StorageArg));
333 return Arg->getZExtValue();
334 }
335
336 /// Return the async function pointer address. This should be the address of
337 /// a async function pointer struct for the current async function.
338 /// struct async_function_pointer {
339 /// uint32_t context_size;
340 /// uint32_t relative_async_function_pointer;
341 /// };
343 return cast<GlobalVariable>(
344 getArgOperand(AsyncFuncPtrArg)->stripPointerCasts());
345 }
346
347 // Methods to support type inquiry through isa, cast, and dyn_cast:
348 static bool classof(const IntrinsicInst *I) {
349 auto ID = I->getIntrinsicID();
350 return ID == Intrinsic::coro_id_async;
351 }
352
353 static bool classof(const Value *V) {
354 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
355 }
356};
357
358/// This represents the llvm.coro.context.alloc instruction.
360 enum { AsyncFuncPtrArg };
361
362public:
364 return cast<GlobalVariable>(
365 getArgOperand(AsyncFuncPtrArg)->stripPointerCasts());
366 }
367
368 // Methods to support type inquiry through isa, cast, and dyn_cast:
369 static bool classof(const IntrinsicInst *I) {
370 return I->getIntrinsicID() == Intrinsic::coro_async_context_alloc;
371 }
372 static bool classof(const Value *V) {
373 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
374 }
375};
376
377/// This represents the llvm.coro.context.dealloc instruction.
379 : public IntrinsicInst {
380 enum { AsyncContextArg };
381
382public:
384 return getArgOperand(AsyncContextArg)->stripPointerCasts();
385 }
386
387 // Methods to support type inquiry through isa, cast, and dyn_cast:
388 static bool classof(const IntrinsicInst *I) {
389 return I->getIntrinsicID() == Intrinsic::coro_async_context_dealloc;
390 }
391 static bool classof(const Value *V) {
392 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
393 }
394};
395
396/// This represents the llvm.coro.async.resume instruction.
397/// During lowering this is replaced by the resume function of a suspend point
398/// (the continuation function).
400public:
401 // Methods to support type inquiry through isa, cast, and dyn_cast:
402 static bool classof(const IntrinsicInst *I) {
403 return I->getIntrinsicID() == Intrinsic::coro_async_resume;
404 }
405 static bool classof(const Value *V) {
406 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
407 }
408};
409
410/// This represents the llvm.coro.async.size.replace instruction.
412public:
413 // Methods to support type inquiry through isa, cast, and dyn_cast:
414 static bool classof(const IntrinsicInst *I) {
415 return I->getIntrinsicID() == Intrinsic::coro_async_size_replace;
416 }
417 static bool classof(const Value *V) {
418 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
419 }
420};
421
422/// This represents the llvm.coro.frame instruction.
424public:
425 // Methods to support type inquiry through isa, cast, and dyn_cast:
426 static bool classof(const IntrinsicInst *I) {
427 return I->getIntrinsicID() == Intrinsic::coro_frame;
428 }
429 static bool classof(const Value *V) {
430 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
431 }
432};
433
434/// This represents the llvm.coro.free instruction.
436 enum { IdArg, FrameArg };
437
438public:
439 Value *getFrame() const { return getArgOperand(FrameArg); }
440
441 // Methods to support type inquiry through isa, cast, and dyn_cast:
442 static bool classof(const IntrinsicInst *I) {
443 return I->getIntrinsicID() == Intrinsic::coro_free;
444 }
445 static bool classof(const Value *V) {
446 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
447 }
448};
449
450/// This class represents the llvm.coro.begin instruction.
452 enum { IdArg, MemArg };
453
454public:
456 return cast<AnyCoroIdInst>(getArgOperand(IdArg));
457 }
458
459 Value *getMem() const { return getArgOperand(MemArg); }
460
461 // Methods for support type inquiry through isa, cast, and dyn_cast:
462 static bool classof(const IntrinsicInst *I) {
463 return I->getIntrinsicID() == Intrinsic::coro_begin;
464 }
465 static bool classof(const Value *V) {
466 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
467 }
468};
469
470/// This represents the llvm.coro.save instruction.
472public:
473 // Methods to support type inquiry through isa, cast, and dyn_cast:
474 static bool classof(const IntrinsicInst *I) {
475 return I->getIntrinsicID() == Intrinsic::coro_save;
476 }
477 static bool classof(const Value *V) {
478 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
479 }
480};
481
482/// This represents the llvm.coro.promise instruction.
484 enum { FrameArg, AlignArg, FromArg };
485
486public:
487 /// Are we translating from the frame to the promise (false) or from
488 /// the promise to the frame (true)?
489 bool isFromPromise() const {
490 return cast<Constant>(getArgOperand(FromArg))->isOneValue();
491 }
492
493 /// The required alignment of the promise. This must match the
494 /// alignment of the promise alloca in the coroutine.
496 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
497 }
498
499 // Methods to support type inquiry through isa, cast, and dyn_cast:
500 static bool classof(const IntrinsicInst *I) {
501 return I->getIntrinsicID() == Intrinsic::coro_promise;
502 }
503 static bool classof(const Value *V) {
504 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
505 }
506};
507
509public:
510 CoroSaveInst *getCoroSave() const;
511
512 // Methods to support type inquiry through isa, cast, and dyn_cast:
513 static bool classof(const IntrinsicInst *I) {
514 return I->getIntrinsicID() == Intrinsic::coro_suspend ||
515 I->getIntrinsicID() == Intrinsic::coro_suspend_async ||
516 I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
517 }
518 static bool classof(const Value *V) {
519 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
520 }
521};
522
523/// This represents the llvm.coro.suspend instruction.
525 enum { SaveArg, FinalArg };
526
527public:
529 Value *Arg = getArgOperand(SaveArg);
530 if (auto *SI = dyn_cast<CoroSaveInst>(Arg))
531 return SI;
532 assert(isa<ConstantTokenNone>(Arg));
533 return nullptr;
534 }
535
536 bool isFinal() const {
537 return cast<Constant>(getArgOperand(FinalArg))->isOneValue();
538 }
539
540 // Methods to support type inquiry through isa, cast, and dyn_cast:
541 static bool classof(const IntrinsicInst *I) {
542 return I->getIntrinsicID() == Intrinsic::coro_suspend;
543 }
544 static bool classof(const Value *V) {
545 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
546 }
547};
548
550 if (auto Suspend = dyn_cast<CoroSuspendInst>(this))
551 return Suspend->getCoroSave();
552 return nullptr;
553}
554
555/// This represents the llvm.coro.suspend.async instruction.
557public:
558 enum {
562 MustTailCallFuncArg
563 };
564
565 void checkWellFormed() const;
566
567 unsigned getStorageArgumentIndex() const {
568 auto *Arg = cast<ConstantInt>(getArgOperand(StorageArgNoArg));
569 return Arg->getZExtValue();
570 }
571
573 return cast<Function>(
574 getArgOperand(AsyncContextProjectionArg)->stripPointerCasts());
575 }
576
578 return cast<CoroAsyncResumeInst>(
579 getArgOperand(ResumeFunctionArg)->stripPointerCasts());
580 }
581
583 return cast<Function>(
584 getArgOperand(MustTailCallFuncArg)->stripPointerCasts());
585 }
586
587 // Methods to support type inquiry through isa, cast, and dyn_cast:
588 static bool classof(const IntrinsicInst *I) {
589 return I->getIntrinsicID() == Intrinsic::coro_suspend_async;
590 }
591 static bool classof(const Value *V) {
592 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
593 }
594};
595
596/// This represents the llvm.coro.suspend.retcon instruction.
598public:
599 op_iterator value_begin() { return arg_begin(); }
600 const_op_iterator value_begin() const { return arg_begin(); }
601
602 op_iterator value_end() { return arg_end(); }
603 const_op_iterator value_end() const { return arg_end(); }
604
606 return make_range(value_begin(), value_end());
607 }
609 return make_range(value_begin(), value_end());
610 }
611
612 // Methods to support type inquiry through isa, cast, and dyn_cast:
613 static bool classof(const IntrinsicInst *I) {
614 return I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
615 }
616 static bool classof(const Value *V) {
617 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
618 }
619};
620
621/// This represents the llvm.coro.size instruction.
623public:
624 // Methods to support type inquiry through isa, cast, and dyn_cast:
625 static bool classof(const IntrinsicInst *I) {
626 return I->getIntrinsicID() == Intrinsic::coro_size;
627 }
628 static bool classof(const Value *V) {
629 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
630 }
631};
632
633/// This represents the llvm.coro.align instruction.
635public:
636 // Methods to support type inquiry through isa, cast, and dyn_cast:
637 static bool classof(const IntrinsicInst *I) {
638 return I->getIntrinsicID() == Intrinsic::coro_align;
639 }
640 static bool classof(const Value *V) {
641 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
642 }
643};
644
645/// This represents the llvm.end.results instruction.
647public:
648 op_iterator retval_begin() { return arg_begin(); }
649 const_op_iterator retval_begin() const { return arg_begin(); }
650
651 op_iterator retval_end() { return arg_end(); }
652 const_op_iterator retval_end() const { return arg_end(); }
653
655 return make_range(retval_begin(), retval_end());
656 }
658 return make_range(retval_begin(), retval_end());
659 }
660
661 unsigned numReturns() const {
662 return std::distance(retval_begin(), retval_end());
663 }
664
665 // Methods to support type inquiry through isa, cast, and dyn_cast:
666 static bool classof(const IntrinsicInst *I) {
667 return I->getIntrinsicID() == Intrinsic::coro_end_results;
668 }
669 static bool classof(const Value *V) {
670 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
671 }
672};
673
675 enum { FrameArg, UnwindArg, TokenArg };
676
677public:
678 bool isFallthrough() const { return !isUnwind(); }
679 bool isUnwind() const {
680 return cast<Constant>(getArgOperand(UnwindArg))->isOneValue();
681 }
682
683 bool hasResults() const {
684 return !isa<ConstantTokenNone>(getArgOperand(TokenArg));
685 }
686
688 assert(hasResults());
689 return cast<CoroEndResults>(getArgOperand(TokenArg));
690 }
691
692 // Methods to support type inquiry through isa, cast, and dyn_cast:
693 static bool classof(const IntrinsicInst *I) {
694 auto ID = I->getIntrinsicID();
695 return ID == Intrinsic::coro_end || ID == Intrinsic::coro_end_async;
696 }
697 static bool classof(const Value *V) {
698 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
699 }
700};
701
702/// This represents the llvm.coro.end instruction.
704public:
705 // Methods to support type inquiry through isa, cast, and dyn_cast:
706 static bool classof(const IntrinsicInst *I) {
707 return I->getIntrinsicID() == Intrinsic::coro_end;
708 }
709 static bool classof(const Value *V) {
710 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
711 }
712};
713
714/// This represents the llvm.coro.end instruction.
716 enum { FrameArg, UnwindArg, MustTailCallFuncArg };
717
718public:
719 void checkWellFormed() const;
720
722 if (arg_size() < 3)
723 return nullptr;
724
725 return cast<Function>(
726 getArgOperand(MustTailCallFuncArg)->stripPointerCasts());
727 }
728
729 // Methods to support type inquiry through isa, cast, and dyn_cast:
730 static bool classof(const IntrinsicInst *I) {
731 return I->getIntrinsicID() == Intrinsic::coro_end_async;
732 }
733 static bool classof(const Value *V) {
734 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
735 }
736};
737
738/// This represents the llvm.coro.alloca.alloc instruction.
740 enum { SizeArg, AlignArg };
741public:
742 Value *getSize() const {
743 return getArgOperand(SizeArg);
744 }
746 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
747 }
748
749 // Methods to support type inquiry through isa, cast, and dyn_cast:
750 static bool classof(const IntrinsicInst *I) {
751 return I->getIntrinsicID() == Intrinsic::coro_alloca_alloc;
752 }
753 static bool classof(const Value *V) {
754 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
755 }
756};
757
758/// This represents the llvm.coro.alloca.get instruction.
760 enum { AllocArg };
761public:
763 return cast<CoroAllocaAllocInst>(getArgOperand(AllocArg));
764 }
765
766 // Methods to support type inquiry through isa, cast, and dyn_cast:
767 static bool classof(const IntrinsicInst *I) {
768 return I->getIntrinsicID() == Intrinsic::coro_alloca_get;
769 }
770 static bool classof(const Value *V) {
771 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
772 }
773};
774
775/// This represents the llvm.coro.alloca.free instruction.
777 enum { AllocArg };
778public:
780 return cast<CoroAllocaAllocInst>(getArgOperand(AllocArg));
781 }
782
783 // Methods to support type inquiry through isa, cast, and dyn_cast:
784 static bool classof(const IntrinsicInst *I) {
785 return I->getIntrinsicID() == Intrinsic::coro_alloca_free;
786 }
787 static bool classof(const Value *V) {
788 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
789 }
790};
791
792} // End namespace llvm.
793
794#endif
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
Definition: Compiler.h:131
uint32_t Index
static Function * getFunction(Constant *C)
Definition: Evaluator.cpp:236
iv users
Definition: IVUsers.cpp:48
#define I(x, y, z)
Definition: MD5.cpp:58
StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
an instruction to allocate memory on the stack
Definition: Instructions.h:59
bool isFallthrough() const
Definition: CoroInstr.h:678
static bool classof(const Value *V)
Definition: CoroInstr.h:697
bool hasResults() const
Definition: CoroInstr.h:683
bool isUnwind() const
Definition: CoroInstr.h:679
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:693
CoroEndResults * getResults() const
Definition: CoroInstr.h:687
This represents a common base class for llvm.coro.id instructions.
Definition: CoroInstr.h:115
IntrinsicInst * getCoroBegin()
Definition: CoroInstr.h:124
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:133
static bool classof(const Value *V)
Definition: CoroInstr.h:140
CoroAllocInst * getCoroAlloc()
Definition: CoroInstr.h:117
This represents either the llvm.coro.id.retcon or llvm.coro.id.retcon.once instruction.
Definition: CoroInstr.h:235
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:271
Value * getStorage() const
Definition: CoroInstr.h:249
Align getStorageAlignment() const
Definition: CoroInstr.h:245
Function * getPrototype() const
Return the prototype for the continuation function.
Definition: CoroInstr.h:256
uint64_t getStorageSize() const
Definition: CoroInstr.h:241
Function * getAllocFunction() const
Return the function to use for allocating memory.
Definition: CoroInstr.h:261
static bool classof(const Value *V)
Definition: CoroInstr.h:276
Function * getDeallocFunction() const
Return the function to use for deallocating memory.
Definition: CoroInstr.h:266
static bool classof(const Value *V)
Definition: CoroInstr.h:518
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:513
CoroSaveInst * getCoroSave() const
Definition: CoroInstr.h:549
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1494
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1742
ConstantArray - Constant Array Declarations.
Definition: Constants.h:423
This is the shared class of boolean and integer constants.
Definition: Constants.h:80
This is an important base class in LLVM.
Definition: Constant.h:41
This represents the llvm.coro.align instruction.
Definition: CoroInstr.h:634
static bool classof(const Value *V)
Definition: CoroInstr.h:640
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:637
This represents the llvm.coro.alloc instruction.
Definition: CoroInstr.h:70
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:73
static bool classof(const Value *V)
Definition: CoroInstr.h:76
This represents the llvm.coro.alloca.alloc instruction.
Definition: CoroInstr.h:739
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:750
Align getAlignment() const
Definition: CoroInstr.h:745
static bool classof(const Value *V)
Definition: CoroInstr.h:753
Value * getSize() const
Definition: CoroInstr.h:742
This represents the llvm.coro.alloca.free instruction.
Definition: CoroInstr.h:776
static bool classof(const Value *V)
Definition: CoroInstr.h:787
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:784
CoroAllocaAllocInst * getAlloc() const
Definition: CoroInstr.h:779
This represents the llvm.coro.alloca.get instruction.
Definition: CoroInstr.h:759
static bool classof(const Value *V)
Definition: CoroInstr.h:770
CoroAllocaAllocInst * getAlloc() const
Definition: CoroInstr.h:762
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:767
This represents the llvm.coro.context.alloc instruction.
Definition: CoroInstr.h:359
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:369
static bool classof(const Value *V)
Definition: CoroInstr.h:372
GlobalVariable * getAsyncFunctionPointer() const
Definition: CoroInstr.h:363
This represents the llvm.coro.context.dealloc instruction.
Definition: CoroInstr.h:379
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:388
static bool classof(const Value *V)
Definition: CoroInstr.h:391
This represents the llvm.coro.end instruction.
Definition: CoroInstr.h:715
Function * getMustTailCallFunction() const
Definition: CoroInstr.h:721
static bool classof(const Value *V)
Definition: CoroInstr.h:733
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:730
This represents the llvm.coro.async.resume instruction.
Definition: CoroInstr.h:399
static bool classof(const Value *V)
Definition: CoroInstr.h:405
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:402
This represents the llvm.coro.async.size.replace instruction.
Definition: CoroInstr.h:411
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:414
static bool classof(const Value *V)
Definition: CoroInstr.h:417
This represents the llvm.coro.await.suspend instruction.
Definition: CoroInstr.h:85
static bool classof(const CallBase *CB)
Definition: CoroInstr.h:98
Value * getFrame() const
Definition: CoroInstr.h:91
static bool classof(const Value *V)
Definition: CoroInstr.h:109
Value * getAwaiter() const
Definition: CoroInstr.h:89
Function * getWrapperFunction() const
Definition: CoroInstr.h:93
This class represents the llvm.coro.begin instruction.
Definition: CoroInstr.h:451
AnyCoroIdInst * getId() const
Definition: CoroInstr.h:455
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:462
static bool classof(const Value *V)
Definition: CoroInstr.h:465
Value * getMem() const
Definition: CoroInstr.h:459
This represents the llvm.coro.end instruction.
Definition: CoroInstr.h:703
static bool classof(const Value *V)
Definition: CoroInstr.h:709
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:706
This represents the llvm.end.results instruction.
Definition: CoroInstr.h:646
op_iterator retval_begin()
Definition: CoroInstr.h:648
const_op_iterator retval_begin() const
Definition: CoroInstr.h:649
iterator_range< const_op_iterator > return_values() const
Definition: CoroInstr.h:657
iterator_range< op_iterator > return_values()
Definition: CoroInstr.h:654
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:666
const_op_iterator retval_end() const
Definition: CoroInstr.h:652
static bool classof(const Value *V)
Definition: CoroInstr.h:669
op_iterator retval_end()
Definition: CoroInstr.h:651
unsigned numReturns() const
Definition: CoroInstr.h:661
This represents the llvm.coro.frame instruction.
Definition: CoroInstr.h:423
static bool classof(const Value *V)
Definition: CoroInstr.h:429
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:426
This represents the llvm.coro.free instruction.
Definition: CoroInstr.h:435
Value * getFrame() const
Definition: CoroInstr.h:439
static bool classof(const Value *V)
Definition: CoroInstr.h:445
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:442
This represents the llvm.coro.id.async instruction.
Definition: CoroInstr.h:308
Align getStorageAlignment() const
The alignment of the initial async function context.
Definition: CoroInstr.h:322
uint64_t getStorageSize() const
The initial async function context size.
Definition: CoroInstr.h:317
GlobalVariable * getAsyncFunctionPointer() const
Return the async function pointer address.
Definition: CoroInstr.h:342
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:348
Value * getStorage() const
The async context parameter.
Definition: CoroInstr.h:327
unsigned getStorageArgumentIndex() const
Definition: CoroInstr.h:331
static bool classof(const Value *V)
Definition: CoroInstr.h:353
This represents the llvm.coro.id instruction.
Definition: CoroInstr.h:146
static bool classof(const Value *V)
Definition: CoroInstr.h:228
void setInfo(Constant *C)
Definition: CoroInstr.h:213
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:225
Info getInfo() const
Definition: CoroInstr.h:195
Function * getCoroutine() const
Definition: CoroInstr.h:215
Constant * getRawInfo() const
Definition: CoroInstr.h:209
AllocaInst * getPromise() const
Definition: CoroInstr.h:150
void setCoroutineSelf()
Definition: CoroInstr.h:218
void clearPromise()
Definition: CoroInstr.h:157
This represents the llvm.coro.id.retcon instruction.
Definition: CoroInstr.h:283
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:286
static bool classof(const Value *V)
Definition: CoroInstr.h:289
This represents the llvm.coro.id.retcon.once instruction.
Definition: CoroInstr.h:296
static bool classof(const Value *V)
Definition: CoroInstr.h:302
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:299
This represents the llvm.coro.promise instruction.
Definition: CoroInstr.h:483
static bool classof(const Value *V)
Definition: CoroInstr.h:503
Align getAlignment() const
The required alignment of the promise.
Definition: CoroInstr.h:495
bool isFromPromise() const
Are we translating from the frame to the promise (false) or from the promise to the frame (true)?
Definition: CoroInstr.h:489
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:500
This represents the llvm.coro.save instruction.
Definition: CoroInstr.h:471
static bool classof(const Value *V)
Definition: CoroInstr.h:477
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:474
This represents the llvm.coro.size instruction.
Definition: CoroInstr.h:622
static bool classof(const Value *V)
Definition: CoroInstr.h:628
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:625
This class represents the llvm.coro.subfn.addr instruction.
Definition: CoroInstr.h:35
static bool classof(const Value *V)
Definition: CoroInstr.h:64
Value * getFrame() const
Definition: CoroInstr.h:48
ResumeKind getIndex() const
Definition: CoroInstr.h:49
ConstantInt * getRawIndex() const
Definition: CoroInstr.h:56
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:61
This represents the llvm.coro.suspend.async instruction.
Definition: CoroInstr.h:556
Function * getAsyncContextProjectionFunction() const
Definition: CoroInstr.h:572
static bool classof(const Value *V)
Definition: CoroInstr.h:591
unsigned getStorageArgumentIndex() const
Definition: CoroInstr.h:567
CoroAsyncResumeInst * getResumeFunction() const
Definition: CoroInstr.h:577
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:588
Function * getMustTailCallFunction() const
Definition: CoroInstr.h:582
This represents the llvm.coro.suspend instruction.
Definition: CoroInstr.h:524
bool isFinal() const
Definition: CoroInstr.h:536
CoroSaveInst * getCoroSave() const
Definition: CoroInstr.h:528
static bool classof(const Value *V)
Definition: CoroInstr.h:544
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:541
This represents the llvm.coro.suspend.retcon instruction.
Definition: CoroInstr.h:597
op_iterator value_begin()
Definition: CoroInstr.h:599
static bool classof(const Value *V)
Definition: CoroInstr.h:616
const_op_iterator value_begin() const
Definition: CoroInstr.h:600
const_op_iterator value_end() const
Definition: CoroInstr.h:603
iterator_range< const_op_iterator > value_operands() const
Definition: CoroInstr.h:608
iterator_range< op_iterator > value_operands()
Definition: CoroInstr.h:605
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:613
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:47
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
LLVM Value Representation.
Definition: Value.h:74
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:693
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.
Definition: AddressRanges.h:18
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.
Definition: Alignment.h:39
bool hasOutlinedParts() const
Definition: CoroInstr.h:191
bool isPostSplit() const
Definition: CoroInstr.h:192
bool isPreSplit() const
Definition: CoroInstr.h:193