File indexing completed on 2026-05-10 08:44:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #ifndef LLVM_TRANSFORMS_COROUTINES_COROINSTR_H
0026 #define LLVM_TRANSFORMS_COROUTINES_COROINSTR_H
0027
0028 #include "llvm/IR/GlobalVariable.h"
0029 #include "llvm/IR/IntrinsicInst.h"
0030 #include "llvm/Support/raw_ostream.h"
0031
0032 namespace llvm {
0033
0034
0035 class CoroSubFnInst : public IntrinsicInst {
0036 enum { FrameArg, IndexArg };
0037
0038 public:
0039 enum ResumeKind {
0040 RestartTrigger = -1,
0041 ResumeIndex,
0042 DestroyIndex,
0043 CleanupIndex,
0044 IndexLast,
0045 IndexFirst = RestartTrigger
0046 };
0047
0048 Value *getFrame() const { return getArgOperand(FrameArg); }
0049 ResumeKind getIndex() const {
0050 int64_t Index = getRawIndex()->getValue().getSExtValue();
0051 assert(Index >= IndexFirst && Index < IndexLast &&
0052 "unexpected CoroSubFnInst index argument");
0053 return static_cast<ResumeKind>(Index);
0054 }
0055
0056 ConstantInt *getRawIndex() const {
0057 return cast<ConstantInt>(getArgOperand(IndexArg));
0058 }
0059
0060
0061 static bool classof(const IntrinsicInst *I) {
0062 return I->getIntrinsicID() == Intrinsic::coro_subfn_addr;
0063 }
0064 static bool classof(const Value *V) {
0065 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0066 }
0067 };
0068
0069
0070 class CoroAllocInst : public IntrinsicInst {
0071 public:
0072
0073 static bool classof(const IntrinsicInst *I) {
0074 return I->getIntrinsicID() == Intrinsic::coro_alloc;
0075 }
0076 static bool classof(const Value *V) {
0077 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0078 }
0079 };
0080
0081
0082
0083
0084
0085 class CoroAwaitSuspendInst : public CallBase {
0086 enum { AwaiterArg, FrameArg, WrapperArg };
0087
0088 public:
0089 Value *getAwaiter() const { return getArgOperand(AwaiterArg); }
0090
0091 Value *getFrame() const { return getArgOperand(FrameArg); }
0092
0093 Function *getWrapperFunction() const {
0094 return cast<Function>(getArgOperand(WrapperArg));
0095 }
0096
0097
0098 static bool classof(const CallBase *CB) {
0099 if (const Function *CF = CB->getCalledFunction()) {
0100 auto IID = CF->getIntrinsicID();
0101 return IID == Intrinsic::coro_await_suspend_void ||
0102 IID == Intrinsic::coro_await_suspend_bool ||
0103 IID == Intrinsic::coro_await_suspend_handle;
0104 }
0105
0106 return false;
0107 }
0108
0109 static bool classof(const Value *V) {
0110 return isa<CallBase>(V) && classof(cast<CallBase>(V));
0111 }
0112 };
0113
0114
0115 class AnyCoroIdInst : public IntrinsicInst {
0116 public:
0117 CoroAllocInst *getCoroAlloc() {
0118 for (User *U : users())
0119 if (auto *CA = dyn_cast<CoroAllocInst>(U))
0120 return CA;
0121 return nullptr;
0122 }
0123
0124 IntrinsicInst *getCoroBegin() {
0125 for (User *U : users())
0126 if (auto *II = dyn_cast<IntrinsicInst>(U))
0127 if (II->getIntrinsicID() == Intrinsic::coro_begin ||
0128 II->getIntrinsicID() == Intrinsic::coro_begin_custom_abi)
0129 return II;
0130 llvm_unreachable("no coro.begin associated with coro.id");
0131 }
0132
0133
0134 static bool classof(const IntrinsicInst *I) {
0135 auto ID = I->getIntrinsicID();
0136 return ID == Intrinsic::coro_id || ID == Intrinsic::coro_id_retcon ||
0137 ID == Intrinsic::coro_id_retcon_once ||
0138 ID == Intrinsic::coro_id_async;
0139 }
0140
0141 static bool classof(const Value *V) {
0142 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0143 }
0144 };
0145
0146
0147 class CoroIdInst : public AnyCoroIdInst {
0148 enum { AlignArg, PromiseArg, CoroutineArg, InfoArg };
0149
0150 public:
0151 AllocaInst *getPromise() const {
0152 Value *Arg = getArgOperand(PromiseArg);
0153 return isa<ConstantPointerNull>(Arg)
0154 ? nullptr
0155 : cast<AllocaInst>(Arg->stripPointerCasts());
0156 }
0157
0158 void clearPromise() {
0159 Value *Arg = getArgOperand(PromiseArg);
0160 setArgOperand(PromiseArg, ConstantPointerNull::get(
0161 PointerType::getUnqual(getContext())));
0162 if (isa<AllocaInst>(Arg))
0163 return;
0164 assert((isa<BitCastInst>(Arg) || isa<GetElementPtrInst>(Arg)) &&
0165 "unexpected instruction designating the promise");
0166
0167
0168 auto *Inst = cast<Instruction>(Arg);
0169 if (Inst->use_empty()) {
0170 Inst->eraseFromParent();
0171 return;
0172 }
0173 Inst->moveBefore(std::next(getCoroBegin()->getIterator()));
0174 }
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 struct Info {
0189 ConstantStruct *OutlinedParts = nullptr;
0190 ConstantArray *Resumers = nullptr;
0191
0192 bool hasOutlinedParts() const { return OutlinedParts != nullptr; }
0193 bool isPostSplit() const { return Resumers != nullptr; }
0194 bool isPreSplit() const { return !isPostSplit(); }
0195 };
0196 Info getInfo() const {
0197 Info Result;
0198 auto *GV = dyn_cast<GlobalVariable>(getRawInfo());
0199 if (!GV)
0200 return Result;
0201
0202 assert(GV->isConstant() && GV->hasDefinitiveInitializer());
0203 Constant *Initializer = GV->getInitializer();
0204 if ((Result.OutlinedParts = dyn_cast<ConstantStruct>(Initializer)))
0205 return Result;
0206
0207 Result.Resumers = cast<ConstantArray>(Initializer);
0208 return Result;
0209 }
0210 Constant *getRawInfo() const {
0211 return cast<Constant>(getArgOperand(InfoArg)->stripPointerCasts());
0212 }
0213
0214 void setInfo(Constant *C) { setArgOperand(InfoArg, C); }
0215
0216 Function *getCoroutine() const {
0217 return cast<Function>(getArgOperand(CoroutineArg)->stripPointerCasts());
0218 }
0219 void setCoroutineSelf() {
0220 assert(isa<ConstantPointerNull>(getArgOperand(CoroutineArg)) &&
0221 "Coroutine argument is already assigned");
0222 setArgOperand(CoroutineArg, getFunction());
0223 }
0224
0225
0226 static bool classof(const IntrinsicInst *I) {
0227 return I->getIntrinsicID() == Intrinsic::coro_id;
0228 }
0229 static bool classof(const Value *V) {
0230 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0231 }
0232 };
0233
0234
0235
0236 class AnyCoroIdRetconInst : public AnyCoroIdInst {
0237 enum { SizeArg, AlignArg, StorageArg, PrototypeArg, AllocArg, DeallocArg };
0238
0239 public:
0240 void checkWellFormed() const;
0241
0242 uint64_t getStorageSize() const {
0243 return cast<ConstantInt>(getArgOperand(SizeArg))->getZExtValue();
0244 }
0245
0246 Align getStorageAlignment() const {
0247 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
0248 }
0249
0250 Value *getStorage() const { return getArgOperand(StorageArg); }
0251
0252
0253
0254
0255 Function *getPrototype() const {
0256 return cast<Function>(getArgOperand(PrototypeArg)->stripPointerCasts());
0257 }
0258
0259
0260 Function *getAllocFunction() const {
0261 return cast<Function>(getArgOperand(AllocArg)->stripPointerCasts());
0262 }
0263
0264
0265 Function *getDeallocFunction() const {
0266 return cast<Function>(getArgOperand(DeallocArg)->stripPointerCasts());
0267 }
0268
0269
0270 static bool classof(const IntrinsicInst *I) {
0271 auto ID = I->getIntrinsicID();
0272 return ID == Intrinsic::coro_id_retcon ||
0273 ID == Intrinsic::coro_id_retcon_once;
0274 }
0275 static bool classof(const Value *V) {
0276 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0277 }
0278 };
0279
0280
0281 class CoroIdRetconInst : public AnyCoroIdRetconInst {
0282 public:
0283
0284 static bool classof(const IntrinsicInst *I) {
0285 return I->getIntrinsicID() == Intrinsic::coro_id_retcon;
0286 }
0287 static bool classof(const Value *V) {
0288 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0289 }
0290 };
0291
0292
0293 class CoroIdRetconOnceInst : public AnyCoroIdRetconInst {
0294 public:
0295
0296 static bool classof(const IntrinsicInst *I) {
0297 return I->getIntrinsicID() == Intrinsic::coro_id_retcon_once;
0298 }
0299 static bool classof(const Value *V) {
0300 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0301 }
0302 };
0303
0304
0305 class CoroIdAsyncInst : public AnyCoroIdInst {
0306 enum { SizeArg, AlignArg, StorageArg, AsyncFuncPtrArg };
0307
0308 public:
0309 void checkWellFormed() const;
0310
0311
0312
0313
0314 uint64_t getStorageSize() const {
0315 return cast<ConstantInt>(getArgOperand(SizeArg))->getZExtValue();
0316 }
0317
0318
0319 Align getStorageAlignment() const {
0320 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
0321 }
0322
0323
0324 Value *getStorage() const {
0325 return getParent()->getParent()->getArg(getStorageArgumentIndex());
0326 }
0327
0328 unsigned getStorageArgumentIndex() const {
0329 auto *Arg = cast<ConstantInt>(getArgOperand(StorageArg));
0330 return Arg->getZExtValue();
0331 }
0332
0333
0334
0335
0336
0337
0338
0339 GlobalVariable *getAsyncFunctionPointer() const {
0340 return cast<GlobalVariable>(
0341 getArgOperand(AsyncFuncPtrArg)->stripPointerCasts());
0342 }
0343
0344
0345 static bool classof(const IntrinsicInst *I) {
0346 auto ID = I->getIntrinsicID();
0347 return ID == Intrinsic::coro_id_async;
0348 }
0349
0350 static bool classof(const Value *V) {
0351 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0352 }
0353 };
0354
0355
0356 class CoroAsyncContextAllocInst : public IntrinsicInst {
0357 enum { AsyncFuncPtrArg };
0358
0359 public:
0360 GlobalVariable *getAsyncFunctionPointer() const {
0361 return cast<GlobalVariable>(
0362 getArgOperand(AsyncFuncPtrArg)->stripPointerCasts());
0363 }
0364
0365
0366 static bool classof(const IntrinsicInst *I) {
0367 return I->getIntrinsicID() == Intrinsic::coro_async_context_alloc;
0368 }
0369 static bool classof(const Value *V) {
0370 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0371 }
0372 };
0373
0374
0375 class CoroAsyncContextDeallocInst : public IntrinsicInst {
0376 enum { AsyncContextArg };
0377
0378 public:
0379 Value *getAsyncContext() const {
0380 return getArgOperand(AsyncContextArg)->stripPointerCasts();
0381 }
0382
0383
0384 static bool classof(const IntrinsicInst *I) {
0385 return I->getIntrinsicID() == Intrinsic::coro_async_context_dealloc;
0386 }
0387 static bool classof(const Value *V) {
0388 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0389 }
0390 };
0391
0392
0393
0394
0395 class CoroAsyncResumeInst : public IntrinsicInst {
0396 public:
0397
0398 static bool classof(const IntrinsicInst *I) {
0399 return I->getIntrinsicID() == Intrinsic::coro_async_resume;
0400 }
0401 static bool classof(const Value *V) {
0402 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0403 }
0404 };
0405
0406
0407 class CoroAsyncSizeReplace : public IntrinsicInst {
0408 public:
0409
0410 static bool classof(const IntrinsicInst *I) {
0411 return I->getIntrinsicID() == Intrinsic::coro_async_size_replace;
0412 }
0413 static bool classof(const Value *V) {
0414 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0415 }
0416 };
0417
0418
0419 class CoroFrameInst : public IntrinsicInst {
0420 public:
0421
0422 static bool classof(const IntrinsicInst *I) {
0423 return I->getIntrinsicID() == Intrinsic::coro_frame;
0424 }
0425 static bool classof(const Value *V) {
0426 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0427 }
0428 };
0429
0430
0431 class CoroFreeInst : public IntrinsicInst {
0432 enum { IdArg, FrameArg };
0433
0434 public:
0435 Value *getFrame() const { return getArgOperand(FrameArg); }
0436
0437
0438 static bool classof(const IntrinsicInst *I) {
0439 return I->getIntrinsicID() == Intrinsic::coro_free;
0440 }
0441 static bool classof(const Value *V) {
0442 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0443 }
0444 };
0445
0446
0447
0448 class CoroBeginInst : public IntrinsicInst {
0449 enum { IdArg, MemArg, CustomABIArg };
0450
0451 public:
0452 AnyCoroIdInst *getId() const {
0453 return cast<AnyCoroIdInst>(getArgOperand(IdArg));
0454 }
0455
0456 bool hasCustomABI() const {
0457 return getIntrinsicID() == Intrinsic::coro_begin_custom_abi;
0458 }
0459
0460 int getCustomABI() const {
0461 return cast<ConstantInt>(getArgOperand(CustomABIArg))->getZExtValue();
0462 }
0463
0464 Value *getMem() const { return getArgOperand(MemArg); }
0465
0466
0467 static bool classof(const IntrinsicInst *I) {
0468 return I->getIntrinsicID() == Intrinsic::coro_begin ||
0469 I->getIntrinsicID() == Intrinsic::coro_begin_custom_abi;
0470 }
0471 static bool classof(const Value *V) {
0472 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0473 }
0474 };
0475
0476
0477 class CoroSaveInst : public IntrinsicInst {
0478 public:
0479
0480 static bool classof(const IntrinsicInst *I) {
0481 return I->getIntrinsicID() == Intrinsic::coro_save;
0482 }
0483 static bool classof(const Value *V) {
0484 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0485 }
0486 };
0487
0488
0489 class CoroPromiseInst : public IntrinsicInst {
0490 enum { FrameArg, AlignArg, FromArg };
0491
0492 public:
0493
0494
0495 bool isFromPromise() const {
0496 return cast<Constant>(getArgOperand(FromArg))->isOneValue();
0497 }
0498
0499
0500
0501 Align getAlignment() const {
0502 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
0503 }
0504
0505
0506 static bool classof(const IntrinsicInst *I) {
0507 return I->getIntrinsicID() == Intrinsic::coro_promise;
0508 }
0509 static bool classof(const Value *V) {
0510 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0511 }
0512 };
0513
0514 class AnyCoroSuspendInst : public IntrinsicInst {
0515 public:
0516 CoroSaveInst *getCoroSave() const;
0517
0518
0519 static bool classof(const IntrinsicInst *I) {
0520 return I->getIntrinsicID() == Intrinsic::coro_suspend ||
0521 I->getIntrinsicID() == Intrinsic::coro_suspend_async ||
0522 I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
0523 }
0524 static bool classof(const Value *V) {
0525 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0526 }
0527 };
0528
0529
0530 class CoroSuspendInst : public AnyCoroSuspendInst {
0531 enum { SaveArg, FinalArg };
0532
0533 public:
0534 CoroSaveInst *getCoroSave() const {
0535 Value *Arg = getArgOperand(SaveArg);
0536 if (auto *SI = dyn_cast<CoroSaveInst>(Arg))
0537 return SI;
0538 assert(isa<ConstantTokenNone>(Arg));
0539 return nullptr;
0540 }
0541
0542 bool isFinal() const {
0543 return cast<Constant>(getArgOperand(FinalArg))->isOneValue();
0544 }
0545
0546
0547 static bool classof(const IntrinsicInst *I) {
0548 return I->getIntrinsicID() == Intrinsic::coro_suspend;
0549 }
0550 static bool classof(const Value *V) {
0551 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0552 }
0553 };
0554
0555 inline CoroSaveInst *AnyCoroSuspendInst::getCoroSave() const {
0556 if (auto Suspend = dyn_cast<CoroSuspendInst>(this))
0557 return Suspend->getCoroSave();
0558 return nullptr;
0559 }
0560
0561
0562 class CoroSuspendAsyncInst : public AnyCoroSuspendInst {
0563 public:
0564 enum {
0565 StorageArgNoArg,
0566 ResumeFunctionArg,
0567 AsyncContextProjectionArg,
0568 MustTailCallFuncArg
0569 };
0570
0571 void checkWellFormed() const;
0572
0573 unsigned getStorageArgumentIndex() const {
0574 auto *Arg = cast<ConstantInt>(getArgOperand(StorageArgNoArg));
0575 return Arg->getZExtValue();
0576 }
0577
0578 Function *getAsyncContextProjectionFunction() const {
0579 return cast<Function>(
0580 getArgOperand(AsyncContextProjectionArg)->stripPointerCasts());
0581 }
0582
0583 CoroAsyncResumeInst *getResumeFunction() const {
0584 return cast<CoroAsyncResumeInst>(
0585 getArgOperand(ResumeFunctionArg)->stripPointerCasts());
0586 }
0587
0588 Function *getMustTailCallFunction() const {
0589 return cast<Function>(
0590 getArgOperand(MustTailCallFuncArg)->stripPointerCasts());
0591 }
0592
0593
0594 static bool classof(const IntrinsicInst *I) {
0595 return I->getIntrinsicID() == Intrinsic::coro_suspend_async;
0596 }
0597 static bool classof(const Value *V) {
0598 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0599 }
0600 };
0601
0602
0603 class CoroSuspendRetconInst : public AnyCoroSuspendInst {
0604 public:
0605 op_iterator value_begin() { return arg_begin(); }
0606 const_op_iterator value_begin() const { return arg_begin(); }
0607
0608 op_iterator value_end() { return arg_end(); }
0609 const_op_iterator value_end() const { return arg_end(); }
0610
0611 iterator_range<op_iterator> value_operands() {
0612 return make_range(value_begin(), value_end());
0613 }
0614 iterator_range<const_op_iterator> value_operands() const {
0615 return make_range(value_begin(), value_end());
0616 }
0617
0618
0619 static bool classof(const IntrinsicInst *I) {
0620 return I->getIntrinsicID() == Intrinsic::coro_suspend_retcon;
0621 }
0622 static bool classof(const Value *V) {
0623 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0624 }
0625 };
0626
0627
0628 class CoroSizeInst : public IntrinsicInst {
0629 public:
0630
0631 static bool classof(const IntrinsicInst *I) {
0632 return I->getIntrinsicID() == Intrinsic::coro_size;
0633 }
0634 static bool classof(const Value *V) {
0635 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0636 }
0637 };
0638
0639
0640 class CoroAlignInst : public IntrinsicInst {
0641 public:
0642
0643 static bool classof(const IntrinsicInst *I) {
0644 return I->getIntrinsicID() == Intrinsic::coro_align;
0645 }
0646 static bool classof(const Value *V) {
0647 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0648 }
0649 };
0650
0651
0652 class CoroEndResults : public IntrinsicInst {
0653 public:
0654 op_iterator retval_begin() { return arg_begin(); }
0655 const_op_iterator retval_begin() const { return arg_begin(); }
0656
0657 op_iterator retval_end() { return arg_end(); }
0658 const_op_iterator retval_end() const { return arg_end(); }
0659
0660 iterator_range<op_iterator> return_values() {
0661 return make_range(retval_begin(), retval_end());
0662 }
0663 iterator_range<const_op_iterator> return_values() const {
0664 return make_range(retval_begin(), retval_end());
0665 }
0666
0667 unsigned numReturns() const {
0668 return std::distance(retval_begin(), retval_end());
0669 }
0670
0671
0672 static bool classof(const IntrinsicInst *I) {
0673 return I->getIntrinsicID() == Intrinsic::coro_end_results;
0674 }
0675 static bool classof(const Value *V) {
0676 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0677 }
0678 };
0679
0680 class AnyCoroEndInst : public IntrinsicInst {
0681 enum { FrameArg, UnwindArg, TokenArg };
0682
0683 public:
0684 bool isFallthrough() const { return !isUnwind(); }
0685 bool isUnwind() const {
0686 return cast<Constant>(getArgOperand(UnwindArg))->isOneValue();
0687 }
0688
0689 bool hasResults() const {
0690 return !isa<ConstantTokenNone>(getArgOperand(TokenArg));
0691 }
0692
0693 CoroEndResults *getResults() const {
0694 assert(hasResults());
0695 return cast<CoroEndResults>(getArgOperand(TokenArg));
0696 }
0697
0698
0699 static bool classof(const IntrinsicInst *I) {
0700 auto ID = I->getIntrinsicID();
0701 return ID == Intrinsic::coro_end || ID == Intrinsic::coro_end_async;
0702 }
0703 static bool classof(const Value *V) {
0704 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0705 }
0706 };
0707
0708
0709 class CoroEndInst : public AnyCoroEndInst {
0710 public:
0711
0712 static bool classof(const IntrinsicInst *I) {
0713 return I->getIntrinsicID() == Intrinsic::coro_end;
0714 }
0715 static bool classof(const Value *V) {
0716 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0717 }
0718 };
0719
0720
0721 class CoroAsyncEndInst : public AnyCoroEndInst {
0722 enum { FrameArg, UnwindArg, MustTailCallFuncArg };
0723
0724 public:
0725 void checkWellFormed() const;
0726
0727 Function *getMustTailCallFunction() const {
0728 if (arg_size() < 3)
0729 return nullptr;
0730
0731 return cast<Function>(
0732 getArgOperand(MustTailCallFuncArg)->stripPointerCasts());
0733 }
0734
0735
0736 static bool classof(const IntrinsicInst *I) {
0737 return I->getIntrinsicID() == Intrinsic::coro_end_async;
0738 }
0739 static bool classof(const Value *V) {
0740 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0741 }
0742 };
0743
0744
0745 class CoroAllocaAllocInst : public IntrinsicInst {
0746 enum { SizeArg, AlignArg };
0747
0748 public:
0749 Value *getSize() const { return getArgOperand(SizeArg); }
0750 Align getAlignment() const {
0751 return cast<ConstantInt>(getArgOperand(AlignArg))->getAlignValue();
0752 }
0753
0754
0755 static bool classof(const IntrinsicInst *I) {
0756 return I->getIntrinsicID() == Intrinsic::coro_alloca_alloc;
0757 }
0758 static bool classof(const Value *V) {
0759 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0760 }
0761 };
0762
0763
0764 class CoroAllocaGetInst : public IntrinsicInst {
0765 enum { AllocArg };
0766
0767 public:
0768 CoroAllocaAllocInst *getAlloc() const {
0769 return cast<CoroAllocaAllocInst>(getArgOperand(AllocArg));
0770 }
0771
0772
0773 static bool classof(const IntrinsicInst *I) {
0774 return I->getIntrinsicID() == Intrinsic::coro_alloca_get;
0775 }
0776 static bool classof(const Value *V) {
0777 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0778 }
0779 };
0780
0781
0782 class CoroAllocaFreeInst : public IntrinsicInst {
0783 enum { AllocArg };
0784
0785 public:
0786 CoroAllocaAllocInst *getAlloc() const {
0787 return cast<CoroAllocaAllocInst>(getArgOperand(AllocArg));
0788 }
0789
0790
0791 static bool classof(const IntrinsicInst *I) {
0792 return I->getIntrinsicID() == Intrinsic::coro_alloca_free;
0793 }
0794 static bool classof(const Value *V) {
0795 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
0796 }
0797 };
0798
0799 }
0800
0801 #endif