LLVM 20.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_TRANSFORMS_COROUTINES_COROINSTR_H
26#define LLVM_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:
46 };
47
48 Value *getFrame() const { return getArgOperand(FrameArg); }
50 int64_t Index = getRawIndex()->getValue().getSExtValue();
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.{void,bool,handle} instructions.
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 II->getIntrinsicID() == Intrinsic::coro_begin_custom_abi)
129 return II;
130 llvm_unreachable("no coro.begin associated with coro.id");
131 }
132
133 // Methods to support type inquiry through isa, cast, and dyn_cast:
134 static bool classof(const IntrinsicInst *I) {
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;
139 }
140
141 static bool classof(const Value *V) {
142 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
143 }
144};
145
146/// This represents the llvm.coro.id instruction.
147class CoroIdInst : public AnyCoroIdInst {
148 enum { AlignArg, PromiseArg, CoroutineArg, InfoArg };
149
150public:
152 Value *Arg = getArgOperand(PromiseArg);
153 return isa<ConstantPointerNull>(Arg)
154 ? nullptr
155 : cast<AllocaInst>(Arg->stripPointerCasts());
156 }
157
159 Value *Arg = getArgOperand(PromiseArg);
162 if (isa<AllocaInst>(Arg))
163 return;
164 assert((isa<BitCastInst>(Arg) || isa<GetElementPtrInst>(Arg)) &&
165 "unexpected instruction designating the promise");
166 // TODO: Add a check that any remaining users of Inst are after coro.begin
167 // or add code to move the users after coro.begin.
168 auto *Inst = cast<Instruction>(Arg);
169 if (Inst->use_empty()) {
170 Inst->eraseFromParent();
171 return;
172 }
173 Inst->moveBefore(getCoroBegin()->getNextNode());
174 }
175
176 // Info argument of coro.id is
177 // fresh out of the frontend: null ;
178 // outlined : {Init, Return, Susp1, Susp2, ...} ;
179 // postsplit : [resume, destroy, cleanup] ;
180 //
181 // If parts of the coroutine were outlined to protect against undesirable
182 // code motion, these functions will be stored in a struct literal referred to
183 // by the Info parameter. Note: this is only needed before coroutine is split.
184 //
185 // After coroutine is split, resume functions are stored in an array
186 // referred to by this parameter.
187
188 struct Info {
191
192 bool hasOutlinedParts() const { return OutlinedParts != nullptr; }
193 bool isPostSplit() const { return Resumers != nullptr; }
194 bool isPreSplit() const { return !isPostSplit(); }
195 };
196 Info getInfo() const {
197 Info Result;
198 auto *GV = dyn_cast<GlobalVariable>(getRawInfo());
199 if (!GV)
200 return Result;
201
202 assert(GV->isConstant() && GV->hasDefinitiveInitializer());
203 Constant *Initializer = GV->getInitializer();
204 if ((Result.OutlinedParts = dyn_cast<ConstantStruct>(Initializer)))
205 return Result;
206
207 Result.Resumers = cast<ConstantArray>(Initializer);
208 return Result;
209 }
211 return cast<Constant>(getArgOperand(InfoArg)->stripPointerCasts());
212 }
213
214 void setInfo(Constant *C) { setArgOperand(InfoArg, C); }
215
217 return cast<Function>(getArgOperand(CoroutineArg)->stripPointerCasts());
218 }
220 assert(isa<ConstantPointerNull>(getArgOperand(CoroutineArg)) &&
221 "Coroutine argument is already assigned");
222 setArgOperand(CoroutineArg, getFunction());
223 }
224
225 // Methods to support type inquiry through isa, cast, and dyn_cast:
226 static bool classof(const IntrinsicInst *I) {
227 return I->getIntrinsicID() == Intrinsic::coro_id;
228 }
229 static bool classof(const Value *V) {
230 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
231 }
232};
233
234/// This represents either the llvm.coro.id.retcon or
235/// llvm.coro.id.retcon.once instruction.
237 enum { SizeArg, AlignArg, StorageArg, PrototypeArg, AllocArg, DeallocArg };
238
239public:
240 void checkWellFormed() const;
241
243 return cast<ConstantInt>(getArgOperand(SizeArg))->getZExtValue();
244 }
245
247 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
248 }
249
250 Value *getStorage() const { return getArgOperand(StorageArg); }
251
252 /// Return the prototype for the continuation function. The type,
253 /// attributes, and calling convention of the continuation function(s)
254 /// are taken from this declaration.
256 return cast<Function>(getArgOperand(PrototypeArg)->stripPointerCasts());
257 }
258
259 /// Return the function to use for allocating memory.
261 return cast<Function>(getArgOperand(AllocArg)->stripPointerCasts());
262 }
263
264 /// Return the function to use for deallocating memory.
266 return cast<Function>(getArgOperand(DeallocArg)->stripPointerCasts());
267 }
268
269 // Methods to support type inquiry through isa, cast, and dyn_cast:
270 static bool classof(const IntrinsicInst *I) {
271 auto ID = I->getIntrinsicID();
272 return ID == Intrinsic::coro_id_retcon ||
273 ID == Intrinsic::coro_id_retcon_once;
274 }
275 static bool classof(const Value *V) {
276 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
277 }
278};
279
280/// This represents the llvm.coro.id.retcon instruction.
282public:
283 // Methods to support type inquiry through isa, cast, and dyn_cast:
284 static bool classof(const IntrinsicInst *I) {
285 return I->getIntrinsicID() == Intrinsic::coro_id_retcon;
286 }
287 static bool classof(const Value *V) {
288 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
289 }
290};
291
292/// This represents the llvm.coro.id.retcon.once instruction.
294public:
295 // Methods to support type inquiry through isa, cast, and dyn_cast:
296 static bool classof(const IntrinsicInst *I) {
297 return I->getIntrinsicID() == Intrinsic::coro_id_retcon_once;
298 }
299 static bool classof(const Value *V) {
300 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
301 }
302};
303
304/// This represents the llvm.coro.id.async instruction.
306 enum { SizeArg, AlignArg, StorageArg, AsyncFuncPtrArg };
307
308public:
309 void checkWellFormed() const;
310
311 /// The initial async function context size. The fields of which are reserved
312 /// for use by the frontend. The frame will be allocated as a tail of this
313 /// context.
315 return cast<ConstantInt>(getArgOperand(SizeArg))->getZExtValue();
316 }
317
318 /// The alignment of the initial async function context.
320 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
321 }
322
323 /// The async context parameter.
324 Value *getStorage() const {
325 return getParent()->getParent()->getArg(getStorageArgumentIndex());
326 }
327
328 unsigned getStorageArgumentIndex() const {
329 auto *Arg = cast<ConstantInt>(getArgOperand(StorageArg));
330 return Arg->getZExtValue();
331 }
332
333 /// Return the async function pointer address. This should be the address of
334 /// a async function pointer struct for the current async function.
335 /// struct async_function_pointer {
336 /// uint32_t context_size;
337 /// uint32_t relative_async_function_pointer;
338 /// };
340 return cast<GlobalVariable>(
341 getArgOperand(AsyncFuncPtrArg)->stripPointerCasts());
342 }
343
344 // Methods to support type inquiry through isa, cast, and dyn_cast:
345 static bool classof(const IntrinsicInst *I) {
346 auto ID = I->getIntrinsicID();
347 return ID == Intrinsic::coro_id_async;
348 }
349
350 static bool classof(const Value *V) {
351 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
352 }
353};
354
355/// This represents the llvm.coro.context.alloc instruction.
357 enum { AsyncFuncPtrArg };
358
359public:
361 return cast<GlobalVariable>(
362 getArgOperand(AsyncFuncPtrArg)->stripPointerCasts());
363 }
364
365 // Methods to support type inquiry through isa, cast, and dyn_cast:
366 static bool classof(const IntrinsicInst *I) {
367 return I->getIntrinsicID() == Intrinsic::coro_async_context_alloc;
368 }
369 static bool classof(const Value *V) {
370 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
371 }
372};
373
374/// This represents the llvm.coro.context.dealloc instruction.
376 enum { AsyncContextArg };
377
378public:
380 return getArgOperand(AsyncContextArg)->stripPointerCasts();
381 }
382
383 // Methods to support type inquiry through isa, cast, and dyn_cast:
384 static bool classof(const IntrinsicInst *I) {
385 return I->getIntrinsicID() == Intrinsic::coro_async_context_dealloc;
386 }
387 static bool classof(const Value *V) {
388 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
389 }
390};
391
392/// This represents the llvm.coro.async.resume instruction.
393/// During lowering this is replaced by the resume function of a suspend point
394/// (the continuation function).
396public:
397 // Methods to support type inquiry through isa, cast, and dyn_cast:
398 static bool classof(const IntrinsicInst *I) {
399 return I->getIntrinsicID() == Intrinsic::coro_async_resume;
400 }
401 static bool classof(const Value *V) {
402 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
403 }
404};
405
406/// This represents the llvm.coro.async.size.replace instruction.
408public:
409 // Methods to support type inquiry through isa, cast, and dyn_cast:
410 static bool classof(const IntrinsicInst *I) {
411 return I->getIntrinsicID() == Intrinsic::coro_async_size_replace;
412 }
413 static bool classof(const Value *V) {
414 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
415 }
416};
417
418/// This represents the llvm.coro.frame instruction.
420public:
421 // Methods to support type inquiry through isa, cast, and dyn_cast:
422 static bool classof(const IntrinsicInst *I) {
423 return I->getIntrinsicID() == Intrinsic::coro_frame;
424 }
425 static bool classof(const Value *V) {
426 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
427 }
428};
429
430/// This represents the llvm.coro.free instruction.
432 enum { IdArg, FrameArg };
433
434public:
435 Value *getFrame() const { return getArgOperand(FrameArg); }
436
437 // Methods to support type inquiry through isa, cast, and dyn_cast:
438 static bool classof(const IntrinsicInst *I) {
439 return I->getIntrinsicID() == Intrinsic::coro_free;
440 }
441 static bool classof(const Value *V) {
442 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
443 }
444};
445
446/// This class represents the llvm.coro.begin or llvm.coro.begin.custom.abi
447/// instructions.
449 enum { IdArg, MemArg, CustomABIArg };
450
451public:
453 return cast<AnyCoroIdInst>(getArgOperand(IdArg));
454 }
455
456 bool hasCustomABI() const {
457 return getIntrinsicID() == Intrinsic::coro_begin_custom_abi;
458 }
459
460 int getCustomABI() const {
461 return cast<ConstantInt>(getArgOperand(CustomABIArg))->getZExtValue();
462 }
463
464 Value *getMem() const { return getArgOperand(MemArg); }
465
466 // Methods for support type inquiry through isa, cast, and dyn_cast:
467 static bool classof(const IntrinsicInst *I) {
468 return I->getIntrinsicID() == Intrinsic::coro_begin ||
469 I->getIntrinsicID() == Intrinsic::coro_begin_custom_abi;
470 }
471 static bool classof(const Value *V) {
472 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
473 }
474};
475
476/// This represents the llvm.coro.save instruction.
478public:
479 // Methods to support type inquiry through isa, cast, and dyn_cast:
480 static bool classof(const IntrinsicInst *I) {
481 return I->getIntrinsicID() == Intrinsic::coro_save;
482 }
483 static bool classof(const Value *V) {
484 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
485 }
486};
487
488/// This represents the llvm.coro.promise instruction.
490 enum { FrameArg, AlignArg, FromArg };
491
492public:
493 /// Are we translating from the frame to the promise (false) or from
494 /// the promise to the frame (true)?
495 bool isFromPromise() const {
496 return cast<Constant>(getArgOperand(FromArg))->isOneValue();
497 }
498
499 /// The required alignment of the promise. This must match the
500 /// alignment of the promise alloca in the coroutine.
502 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
503 }
504
505 // Methods to support type inquiry through isa, cast, and dyn_cast:
506 static bool classof(const IntrinsicInst *I) {
507 return I->getIntrinsicID() == Intrinsic::coro_promise;
508 }
509 static bool classof(const Value *V) {
510 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
511 }
512};
513
515public:
516 CoroSaveInst *getCoroSave() const;
517
518 // Methods to support type inquiry through isa, cast, and dyn_cast:
519 static bool classof(const IntrinsicInst *I) {
520 return I->getIntrinsicID() == Intrinsic::coro_suspend ||
521 I->getIntrinsicID() == Intrinsic::coro_suspend_async ||
522 I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
523 }
524 static bool classof(const Value *V) {
525 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
526 }
527};
528
529/// This represents the llvm.coro.suspend instruction.
531 enum { SaveArg, FinalArg };
532
533public:
535 Value *Arg = getArgOperand(SaveArg);
536 if (auto *SI = dyn_cast<CoroSaveInst>(Arg))
537 return SI;
538 assert(isa<ConstantTokenNone>(Arg));
539 return nullptr;
540 }
541
542 bool isFinal() const {
543 return cast<Constant>(getArgOperand(FinalArg))->isOneValue();
544 }
545
546 // Methods to support type inquiry through isa, cast, and dyn_cast:
547 static bool classof(const IntrinsicInst *I) {
548 return I->getIntrinsicID() == Intrinsic::coro_suspend;
549 }
550 static bool classof(const Value *V) {
551 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
552 }
553};
554
556 if (auto Suspend = dyn_cast<CoroSuspendInst>(this))
557 return Suspend->getCoroSave();
558 return nullptr;
559}
560
561/// This represents the llvm.coro.suspend.async instruction.
563public:
564 enum {
569 };
570
571 void checkWellFormed() const;
572
573 unsigned getStorageArgumentIndex() const {
574 auto *Arg = cast<ConstantInt>(getArgOperand(StorageArgNoArg));
575 return Arg->getZExtValue();
576 }
577
579 return cast<Function>(
581 }
582
584 return cast<CoroAsyncResumeInst>(
586 }
587
589 return cast<Function>(
591 }
592
593 // Methods to support type inquiry through isa, cast, and dyn_cast:
594 static bool classof(const IntrinsicInst *I) {
595 return I->getIntrinsicID() == Intrinsic::coro_suspend_async;
596 }
597 static bool classof(const Value *V) {
598 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
599 }
600};
601
602/// This represents the llvm.coro.suspend.retcon instruction.
604public:
607
609 const_op_iterator value_end() const { return arg_end(); }
610
612 return make_range(value_begin(), value_end());
613 }
615 return make_range(value_begin(), value_end());
616 }
617
618 // Methods to support type inquiry through isa, cast, and dyn_cast:
619 static bool classof(const IntrinsicInst *I) {
620 return I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
621 }
622 static bool classof(const Value *V) {
623 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
624 }
625};
626
627/// This represents the llvm.coro.size instruction.
629public:
630 // Methods to support type inquiry through isa, cast, and dyn_cast:
631 static bool classof(const IntrinsicInst *I) {
632 return I->getIntrinsicID() == Intrinsic::coro_size;
633 }
634 static bool classof(const Value *V) {
635 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
636 }
637};
638
639/// This represents the llvm.coro.align instruction.
641public:
642 // Methods to support type inquiry through isa, cast, and dyn_cast:
643 static bool classof(const IntrinsicInst *I) {
644 return I->getIntrinsicID() == Intrinsic::coro_align;
645 }
646 static bool classof(const Value *V) {
647 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
648 }
649};
650
651/// This represents the llvm.end.results instruction.
653public:
656
659
662 }
665 }
666
667 unsigned numReturns() const {
668 return std::distance(retval_begin(), retval_end());
669 }
670
671 // Methods to support type inquiry through isa, cast, and dyn_cast:
672 static bool classof(const IntrinsicInst *I) {
673 return I->getIntrinsicID() == Intrinsic::coro_end_results;
674 }
675 static bool classof(const Value *V) {
676 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
677 }
678};
679
681 enum { FrameArg, UnwindArg, TokenArg };
682
683public:
684 bool isFallthrough() const { return !isUnwind(); }
685 bool isUnwind() const {
686 return cast<Constant>(getArgOperand(UnwindArg))->isOneValue();
687 }
688
689 bool hasResults() const {
690 return !isa<ConstantTokenNone>(getArgOperand(TokenArg));
691 }
692
695 return cast<CoroEndResults>(getArgOperand(TokenArg));
696 }
697
698 // Methods to support type inquiry through isa, cast, and dyn_cast:
699 static bool classof(const IntrinsicInst *I) {
700 auto ID = I->getIntrinsicID();
701 return ID == Intrinsic::coro_end || ID == Intrinsic::coro_end_async;
702 }
703 static bool classof(const Value *V) {
704 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
705 }
706};
707
708/// This represents the llvm.coro.end instruction.
710public:
711 // Methods to support type inquiry through isa, cast, and dyn_cast:
712 static bool classof(const IntrinsicInst *I) {
713 return I->getIntrinsicID() == Intrinsic::coro_end;
714 }
715 static bool classof(const Value *V) {
716 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
717 }
718};
719
720/// This represents the llvm.coro.end instruction.
722 enum { FrameArg, UnwindArg, MustTailCallFuncArg };
723
724public:
725 void checkWellFormed() const;
726
728 if (arg_size() < 3)
729 return nullptr;
730
731 return cast<Function>(
732 getArgOperand(MustTailCallFuncArg)->stripPointerCasts());
733 }
734
735 // Methods to support type inquiry through isa, cast, and dyn_cast:
736 static bool classof(const IntrinsicInst *I) {
737 return I->getIntrinsicID() == Intrinsic::coro_end_async;
738 }
739 static bool classof(const Value *V) {
740 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
741 }
742};
743
744/// This represents the llvm.coro.alloca.alloc instruction.
746 enum { SizeArg, AlignArg };
747
748public:
749 Value *getSize() const { return getArgOperand(SizeArg); }
751 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
752 }
753
754 // Methods to support type inquiry through isa, cast, and dyn_cast:
755 static bool classof(const IntrinsicInst *I) {
756 return I->getIntrinsicID() == Intrinsic::coro_alloca_alloc;
757 }
758 static bool classof(const Value *V) {
759 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
760 }
761};
762
763/// This represents the llvm.coro.alloca.get instruction.
765 enum { AllocArg };
766
767public:
769 return cast<CoroAllocaAllocInst>(getArgOperand(AllocArg));
770 }
771
772 // Methods to support type inquiry through isa, cast, and dyn_cast:
773 static bool classof(const IntrinsicInst *I) {
774 return I->getIntrinsicID() == Intrinsic::coro_alloca_get;
775 }
776 static bool classof(const Value *V) {
777 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
778 }
779};
780
781/// This represents the llvm.coro.alloca.free instruction.
783 enum { AllocArg };
784
785public:
787 return cast<CoroAllocaAllocInst>(getArgOperand(AllocArg));
788 }
789
790 // Methods to support type inquiry through isa, cast, and dyn_cast:
791 static bool classof(const IntrinsicInst *I) {
792 return I->getIntrinsicID() == Intrinsic::coro_alloca_free;
793 }
794 static bool classof(const Value *V) {
795 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
796 }
797};
798
799} // End namespace llvm.
800
801#endif // LLVM_TRANSFORMS_COROUTINES_COROINSTR_H
uint32_t Index
iv users
Definition: IVUsers.cpp:48
#define I(x, y, z)
Definition: MD5.cpp:58
uint64_t IntrinsicInst * II
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1542
an instruction to allocate memory on the stack
Definition: Instructions.h:63
bool isFallthrough() const
Definition: CoroInstr.h:684
static bool classof(const Value *V)
Definition: CoroInstr.h:703
bool hasResults() const
Definition: CoroInstr.h:689
bool isUnwind() const
Definition: CoroInstr.h:685
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:699
CoroEndResults * getResults() const
Definition: CoroInstr.h:693
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:134
static bool classof(const Value *V)
Definition: CoroInstr.h:141
CoroAllocInst * getCoroAlloc()
Definition: CoroInstr.h:117
This represents either the llvm.coro.id.retcon or llvm.coro.id.retcon.once instruction.
Definition: CoroInstr.h:236
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:270
Value * getStorage() const
Definition: CoroInstr.h:250
Align getStorageAlignment() const
Definition: CoroInstr.h:246
Function * getPrototype() const
Return the prototype for the continuation function.
Definition: CoroInstr.h:255
uint64_t getStorageSize() const
Definition: CoroInstr.h:242
void checkWellFormed() const
Definition: Coroutines.cpp:637
Function * getAllocFunction() const
Return the function to use for allocating memory.
Definition: CoroInstr.h:260
static bool classof(const Value *V)
Definition: CoroInstr.h:275
Function * getDeallocFunction() const
Return the function to use for deallocating memory.
Definition: CoroInstr.h:265
static bool classof(const Value *V)
Definition: CoroInstr.h:524
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:519
CoroSaveInst * getCoroSave() const
Definition: CoroInstr.h:555
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1120
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1349
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Definition: InstrTypes.h:1269
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1294
void setArgOperand(unsigned i, Value *v)
Definition: InstrTypes.h:1299
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
Definition: InstrTypes.h:1275
unsigned arg_size() const
Definition: InstrTypes.h:1292
ConstantArray - Constant Array Declarations.
Definition: Constants.h:427
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition: Constants.h:148
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
Definition: Constants.cpp:1826
This is an important base class in LLVM.
Definition: Constant.h:42
This represents the llvm.coro.align instruction.
Definition: CoroInstr.h:640
static bool classof(const Value *V)
Definition: CoroInstr.h:646
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:643
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:745
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:755
Align getAlignment() const
Definition: CoroInstr.h:750
static bool classof(const Value *V)
Definition: CoroInstr.h:758
Value * getSize() const
Definition: CoroInstr.h:749
This represents the llvm.coro.alloca.free instruction.
Definition: CoroInstr.h:782
static bool classof(const Value *V)
Definition: CoroInstr.h:794
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:791
CoroAllocaAllocInst * getAlloc() const
Definition: CoroInstr.h:786
This represents the llvm.coro.alloca.get instruction.
Definition: CoroInstr.h:764
static bool classof(const Value *V)
Definition: CoroInstr.h:776
CoroAllocaAllocInst * getAlloc() const
Definition: CoroInstr.h:768
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:773
This represents the llvm.coro.context.alloc instruction.
Definition: CoroInstr.h:356
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:366
static bool classof(const Value *V)
Definition: CoroInstr.h:369
GlobalVariable * getAsyncFunctionPointer() const
Definition: CoroInstr.h:360
This represents the llvm.coro.context.dealloc instruction.
Definition: CoroInstr.h:375
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:384
static bool classof(const Value *V)
Definition: CoroInstr.h:387
This represents the llvm.coro.end instruction.
Definition: CoroInstr.h:721
Function * getMustTailCallFunction() const
Definition: CoroInstr.h:727
void checkWellFormed() const
Definition: Coroutines.cpp:682
static bool classof(const Value *V)
Definition: CoroInstr.h:739
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:736
This represents the llvm.coro.async.resume instruction.
Definition: CoroInstr.h:395
static bool classof(const Value *V)
Definition: CoroInstr.h:401
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:398
This represents the llvm.coro.async.size.replace instruction.
Definition: CoroInstr.h:407
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:410
static bool classof(const Value *V)
Definition: CoroInstr.h:413
This represents the llvm.coro.await.suspend.{void,bool,handle} instructions.
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 or llvm.coro.begin.custom.abi instructions.
Definition: CoroInstr.h:448
AnyCoroIdInst * getId() const
Definition: CoroInstr.h:452
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:467
static bool classof(const Value *V)
Definition: CoroInstr.h:471
bool hasCustomABI() const
Definition: CoroInstr.h:456
int getCustomABI() const
Definition: CoroInstr.h:460
Value * getMem() const
Definition: CoroInstr.h:464
This represents the llvm.coro.end instruction.
Definition: CoroInstr.h:709
static bool classof(const Value *V)
Definition: CoroInstr.h:715
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:712
This represents the llvm.end.results instruction.
Definition: CoroInstr.h:652
op_iterator retval_begin()
Definition: CoroInstr.h:654
const_op_iterator retval_begin() const
Definition: CoroInstr.h:655
iterator_range< const_op_iterator > return_values() const
Definition: CoroInstr.h:663
iterator_range< op_iterator > return_values()
Definition: CoroInstr.h:660
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:672
const_op_iterator retval_end() const
Definition: CoroInstr.h:658
static bool classof(const Value *V)
Definition: CoroInstr.h:675
op_iterator retval_end()
Definition: CoroInstr.h:657
unsigned numReturns() const
Definition: CoroInstr.h:667
This represents the llvm.coro.frame instruction.
Definition: CoroInstr.h:419
static bool classof(const Value *V)
Definition: CoroInstr.h:425
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:422
This represents the llvm.coro.free instruction.
Definition: CoroInstr.h:431
Value * getFrame() const
Definition: CoroInstr.h:435
static bool classof(const Value *V)
Definition: CoroInstr.h:441
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:438
This represents the llvm.coro.id.async instruction.
Definition: CoroInstr.h:305
Align getStorageAlignment() const
The alignment of the initial async function context.
Definition: CoroInstr.h:319
uint64_t getStorageSize() const
The initial async function context size.
Definition: CoroInstr.h:314
void checkWellFormed() const
Definition: Coroutines.cpp:653
GlobalVariable * getAsyncFunctionPointer() const
Return the async function pointer address.
Definition: CoroInstr.h:339
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:345
Value * getStorage() const
The async context parameter.
Definition: CoroInstr.h:324
unsigned getStorageArgumentIndex() const
Definition: CoroInstr.h:328
static bool classof(const Value *V)
Definition: CoroInstr.h:350
This represents the llvm.coro.id instruction.
Definition: CoroInstr.h:147
static bool classof(const Value *V)
Definition: CoroInstr.h:229
void setInfo(Constant *C)
Definition: CoroInstr.h:214
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:226
Info getInfo() const
Definition: CoroInstr.h:196
Function * getCoroutine() const
Definition: CoroInstr.h:216
Constant * getRawInfo() const
Definition: CoroInstr.h:210
AllocaInst * getPromise() const
Definition: CoroInstr.h:151
void setCoroutineSelf()
Definition: CoroInstr.h:219
void clearPromise()
Definition: CoroInstr.h:158
This represents the llvm.coro.id.retcon instruction.
Definition: CoroInstr.h:281
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:284
static bool classof(const Value *V)
Definition: CoroInstr.h:287
This represents the llvm.coro.id.retcon.once instruction.
Definition: CoroInstr.h:293
static bool classof(const Value *V)
Definition: CoroInstr.h:299
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:296
This represents the llvm.coro.promise instruction.
Definition: CoroInstr.h:489
static bool classof(const Value *V)
Definition: CoroInstr.h:509
Align getAlignment() const
The required alignment of the promise.
Definition: CoroInstr.h:501
bool isFromPromise() const
Are we translating from the frame to the promise (false) or from the promise to the frame (true)?
Definition: CoroInstr.h:495
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:506
This represents the llvm.coro.save instruction.
Definition: CoroInstr.h:477
static bool classof(const Value *V)
Definition: CoroInstr.h:483
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:480
This represents the llvm.coro.size instruction.
Definition: CoroInstr.h:628
static bool classof(const Value *V)
Definition: CoroInstr.h:634
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:631
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:562
Function * getAsyncContextProjectionFunction() const
Definition: CoroInstr.h:578
static bool classof(const Value *V)
Definition: CoroInstr.h:597
unsigned getStorageArgumentIndex() const
Definition: CoroInstr.h:573
CoroAsyncResumeInst * getResumeFunction() const
Definition: CoroInstr.h:583
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:594
Function * getMustTailCallFunction() const
Definition: CoroInstr.h:588
This represents the llvm.coro.suspend instruction.
Definition: CoroInstr.h:530
bool isFinal() const
Definition: CoroInstr.h:542
CoroSaveInst * getCoroSave() const
Definition: CoroInstr.h:534
static bool classof(const Value *V)
Definition: CoroInstr.h:550
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:547
This represents the llvm.coro.suspend.retcon instruction.
Definition: CoroInstr.h:603
op_iterator value_begin()
Definition: CoroInstr.h:605
static bool classof(const Value *V)
Definition: CoroInstr.h:622
const_op_iterator value_begin() const
Definition: CoroInstr.h:606
const_op_iterator value_end() const
Definition: CoroInstr.h:609
iterator_range< const_op_iterator > value_operands() const
Definition: CoroInstr.h:614
iterator_range< op_iterator > value_operands()
Definition: CoroInstr.h:611
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:619
const Function * getFunction() const
Return the function this instruction belongs to.
Definition: Instruction.cpp:70
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:48
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Definition: IntrinsicInst.h:55
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Definition: DerivedTypes.h:686
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:694
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:1075
const ParentTy * getParent() const
Definition: ilist_node.h:32
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.
Definition: CallingConv.h:34
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
ConstantArray * Resumers
Definition: CoroInstr.h:190
bool hasOutlinedParts() const
Definition: CoroInstr.h:192
bool isPostSplit() const
Definition: CoroInstr.h:193
bool isPreSplit() const
Definition: CoroInstr.h:194
ConstantStruct * OutlinedParts
Definition: CoroInstr.h:189