1311116Sdim//===-- CoroInstr.h - Coroutine Intrinsics Instruction Wrappers -*- C++ -*-===// 2311116Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6311116Sdim// 7311116Sdim//===----------------------------------------------------------------------===// 8311116Sdim// This file defines classes that make it really easy to deal with intrinsic 9311116Sdim// functions with the isa/dyncast family of functions. In particular, this 10311116Sdim// allows you to do things like: 11311116Sdim// 12311116Sdim// if (auto *SF = dyn_cast<CoroSubFnInst>(Inst)) 13311116Sdim// ... SF->getFrame() ... 14311116Sdim// 15311116Sdim// All intrinsic function calls are instances of the call instruction, so these 16311116Sdim// are all subclasses of the CallInst class. Note that none of these classes 17311116Sdim// has state or virtual methods, which is an important part of this gross/neat 18311116Sdim// hack working. 19311116Sdim// 20311116Sdim// The helpful comment above is borrowed from llvm/IntrinsicInst.h, we keep 21311116Sdim// coroutine intrinsic wrappers here since they are only used by the passes in 22311116Sdim// the Coroutine library. 23311116Sdim//===----------------------------------------------------------------------===// 24311116Sdim 25321369Sdim#ifndef LLVM_LIB_TRANSFORMS_COROUTINES_COROINSTR_H 26321369Sdim#define LLVM_LIB_TRANSFORMS_COROUTINES_COROINSTR_H 27321369Sdim 28311116Sdim#include "llvm/IR/GlobalVariable.h" 29311116Sdim#include "llvm/IR/IntrinsicInst.h" 30360784Sdim#include "llvm/Support/raw_ostream.h" 31311116Sdim 32311116Sdimnamespace llvm { 33311116Sdim 34311116Sdim/// This class represents the llvm.coro.subfn.addr instruction. 35311116Sdimclass LLVM_LIBRARY_VISIBILITY CoroSubFnInst : public IntrinsicInst { 36311116Sdim enum { FrameArg, IndexArg }; 37311116Sdim 38311116Sdimpublic: 39311116Sdim enum ResumeKind { 40311116Sdim RestartTrigger = -1, 41311116Sdim ResumeIndex, 42311116Sdim DestroyIndex, 43311116Sdim CleanupIndex, 44311116Sdim IndexLast, 45311116Sdim IndexFirst = RestartTrigger 46311116Sdim }; 47311116Sdim 48311116Sdim Value *getFrame() const { return getArgOperand(FrameArg); } 49311116Sdim ResumeKind getIndex() const { 50311116Sdim int64_t Index = getRawIndex()->getValue().getSExtValue(); 51311116Sdim assert(Index >= IndexFirst && Index < IndexLast && 52311116Sdim "unexpected CoroSubFnInst index argument"); 53311116Sdim return static_cast<ResumeKind>(Index); 54311116Sdim } 55311116Sdim 56311116Sdim ConstantInt *getRawIndex() const { 57311116Sdim return cast<ConstantInt>(getArgOperand(IndexArg)); 58311116Sdim } 59311116Sdim 60311116Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 61321369Sdim static bool classof(const IntrinsicInst *I) { 62311116Sdim return I->getIntrinsicID() == Intrinsic::coro_subfn_addr; 63311116Sdim } 64321369Sdim static bool classof(const Value *V) { 65311116Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 66311116Sdim } 67311116Sdim}; 68311116Sdim 69311116Sdim/// This represents the llvm.coro.alloc instruction. 70311116Sdimclass LLVM_LIBRARY_VISIBILITY CoroAllocInst : public IntrinsicInst { 71311116Sdimpublic: 72311116Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 73321369Sdim static bool classof(const IntrinsicInst *I) { 74311116Sdim return I->getIntrinsicID() == Intrinsic::coro_alloc; 75311116Sdim } 76321369Sdim static bool classof(const Value *V) { 77311116Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 78311116Sdim } 79311116Sdim}; 80311116Sdim 81360784Sdim/// This represents a common base class for llvm.coro.id instructions. 82360784Sdimclass LLVM_LIBRARY_VISIBILITY AnyCoroIdInst : public IntrinsicInst { 83311116Sdimpublic: 84311116Sdim CoroAllocInst *getCoroAlloc() { 85311116Sdim for (User *U : users()) 86311116Sdim if (auto *CA = dyn_cast<CoroAllocInst>(U)) 87311116Sdim return CA; 88311116Sdim return nullptr; 89311116Sdim } 90311116Sdim 91311116Sdim IntrinsicInst *getCoroBegin() { 92311116Sdim for (User *U : users()) 93311116Sdim if (auto *II = dyn_cast<IntrinsicInst>(U)) 94311116Sdim if (II->getIntrinsicID() == Intrinsic::coro_begin) 95311116Sdim return II; 96311116Sdim llvm_unreachable("no coro.begin associated with coro.id"); 97311116Sdim } 98311116Sdim 99360784Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 100360784Sdim static bool classof(const IntrinsicInst *I) { 101360784Sdim auto ID = I->getIntrinsicID(); 102360784Sdim return ID == Intrinsic::coro_id || 103360784Sdim ID == Intrinsic::coro_id_retcon || 104360784Sdim ID == Intrinsic::coro_id_retcon_once; 105360784Sdim } 106360784Sdim 107360784Sdim static bool classof(const Value *V) { 108360784Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 109360784Sdim } 110360784Sdim}; 111360784Sdim 112360784Sdim/// This represents the llvm.coro.id instruction. 113360784Sdimclass LLVM_LIBRARY_VISIBILITY CoroIdInst : public AnyCoroIdInst { 114360784Sdim enum { AlignArg, PromiseArg, CoroutineArg, InfoArg }; 115360784Sdim 116360784Sdimpublic: 117311116Sdim AllocaInst *getPromise() const { 118311116Sdim Value *Arg = getArgOperand(PromiseArg); 119311116Sdim return isa<ConstantPointerNull>(Arg) 120311116Sdim ? nullptr 121311116Sdim : cast<AllocaInst>(Arg->stripPointerCasts()); 122311116Sdim } 123311116Sdim 124311116Sdim void clearPromise() { 125311116Sdim Value *Arg = getArgOperand(PromiseArg); 126311116Sdim setArgOperand(PromiseArg, 127311116Sdim ConstantPointerNull::get(Type::getInt8PtrTy(getContext()))); 128311116Sdim if (isa<AllocaInst>(Arg)) 129311116Sdim return; 130311116Sdim assert((isa<BitCastInst>(Arg) || isa<GetElementPtrInst>(Arg)) && 131311116Sdim "unexpected instruction designating the promise"); 132311116Sdim // TODO: Add a check that any remaining users of Inst are after coro.begin 133311116Sdim // or add code to move the users after coro.begin. 134311116Sdim auto *Inst = cast<Instruction>(Arg); 135311116Sdim if (Inst->use_empty()) { 136311116Sdim Inst->eraseFromParent(); 137311116Sdim return; 138311116Sdim } 139311116Sdim Inst->moveBefore(getCoroBegin()->getNextNode()); 140311116Sdim } 141311116Sdim 142311116Sdim // Info argument of coro.id is 143311116Sdim // fresh out of the frontend: null ; 144311116Sdim // outlined : {Init, Return, Susp1, Susp2, ...} ; 145311116Sdim // postsplit : [resume, destroy, cleanup] ; 146311116Sdim // 147311116Sdim // If parts of the coroutine were outlined to protect against undesirable 148311116Sdim // code motion, these functions will be stored in a struct literal referred to 149311116Sdim // by the Info parameter. Note: this is only needed before coroutine is split. 150311116Sdim // 151311116Sdim // After coroutine is split, resume functions are stored in an array 152311116Sdim // referred to by this parameter. 153311116Sdim 154311116Sdim struct Info { 155311116Sdim ConstantStruct *OutlinedParts = nullptr; 156311116Sdim ConstantArray *Resumers = nullptr; 157311116Sdim 158311116Sdim bool hasOutlinedParts() const { return OutlinedParts != nullptr; } 159311116Sdim bool isPostSplit() const { return Resumers != nullptr; } 160311116Sdim bool isPreSplit() const { return !isPostSplit(); } 161311116Sdim }; 162311116Sdim Info getInfo() const { 163311116Sdim Info Result; 164311116Sdim auto *GV = dyn_cast<GlobalVariable>(getRawInfo()); 165311116Sdim if (!GV) 166311116Sdim return Result; 167311116Sdim 168311116Sdim assert(GV->isConstant() && GV->hasDefinitiveInitializer()); 169311116Sdim Constant *Initializer = GV->getInitializer(); 170311116Sdim if ((Result.OutlinedParts = dyn_cast<ConstantStruct>(Initializer))) 171311116Sdim return Result; 172311116Sdim 173311116Sdim Result.Resumers = cast<ConstantArray>(Initializer); 174311116Sdim return Result; 175311116Sdim } 176311116Sdim Constant *getRawInfo() const { 177311116Sdim return cast<Constant>(getArgOperand(InfoArg)->stripPointerCasts()); 178311116Sdim } 179311116Sdim 180311116Sdim void setInfo(Constant *C) { setArgOperand(InfoArg, C); } 181311116Sdim 182311116Sdim Function *getCoroutine() const { 183311116Sdim return cast<Function>(getArgOperand(CoroutineArg)->stripPointerCasts()); 184311116Sdim } 185311116Sdim void setCoroutineSelf() { 186311116Sdim assert(isa<ConstantPointerNull>(getArgOperand(CoroutineArg)) && 187311116Sdim "Coroutine argument is already assigned"); 188311116Sdim auto *const Int8PtrTy = Type::getInt8PtrTy(getContext()); 189311116Sdim setArgOperand(CoroutineArg, 190311116Sdim ConstantExpr::getBitCast(getFunction(), Int8PtrTy)); 191311116Sdim } 192311116Sdim 193311116Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 194321369Sdim static bool classof(const IntrinsicInst *I) { 195311116Sdim return I->getIntrinsicID() == Intrinsic::coro_id; 196311116Sdim } 197321369Sdim static bool classof(const Value *V) { 198311116Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 199311116Sdim } 200311116Sdim}; 201311116Sdim 202360784Sdim/// This represents either the llvm.coro.id.retcon or 203360784Sdim/// llvm.coro.id.retcon.once instruction. 204360784Sdimclass LLVM_LIBRARY_VISIBILITY AnyCoroIdRetconInst : public AnyCoroIdInst { 205360784Sdim enum { SizeArg, AlignArg, StorageArg, PrototypeArg, AllocArg, DeallocArg }; 206360784Sdim 207360784Sdimpublic: 208360784Sdim void checkWellFormed() const; 209360784Sdim 210360784Sdim uint64_t getStorageSize() const { 211360784Sdim return cast<ConstantInt>(getArgOperand(SizeArg))->getZExtValue(); 212360784Sdim } 213360784Sdim 214360784Sdim uint64_t getStorageAlignment() const { 215360784Sdim return cast<ConstantInt>(getArgOperand(AlignArg))->getZExtValue(); 216360784Sdim } 217360784Sdim 218360784Sdim Value *getStorage() const { 219360784Sdim return getArgOperand(StorageArg); 220360784Sdim } 221360784Sdim 222360784Sdim /// Return the prototype for the continuation function. The type, 223360784Sdim /// attributes, and calling convention of the continuation function(s) 224360784Sdim /// are taken from this declaration. 225360784Sdim Function *getPrototype() const { 226360784Sdim return cast<Function>(getArgOperand(PrototypeArg)->stripPointerCasts()); 227360784Sdim } 228360784Sdim 229360784Sdim /// Return the function to use for allocating memory. 230360784Sdim Function *getAllocFunction() const { 231360784Sdim return cast<Function>(getArgOperand(AllocArg)->stripPointerCasts()); 232360784Sdim } 233360784Sdim 234360784Sdim /// Return the function to use for deallocating memory. 235360784Sdim Function *getDeallocFunction() const { 236360784Sdim return cast<Function>(getArgOperand(DeallocArg)->stripPointerCasts()); 237360784Sdim } 238360784Sdim 239360784Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 240360784Sdim static bool classof(const IntrinsicInst *I) { 241360784Sdim auto ID = I->getIntrinsicID(); 242360784Sdim return ID == Intrinsic::coro_id_retcon 243360784Sdim || ID == Intrinsic::coro_id_retcon_once; 244360784Sdim } 245360784Sdim static bool classof(const Value *V) { 246360784Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 247360784Sdim } 248360784Sdim}; 249360784Sdim 250360784Sdim/// This represents the llvm.coro.id.retcon instruction. 251360784Sdimclass LLVM_LIBRARY_VISIBILITY CoroIdRetconInst 252360784Sdim : public AnyCoroIdRetconInst { 253360784Sdimpublic: 254360784Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 255360784Sdim static bool classof(const IntrinsicInst *I) { 256360784Sdim return I->getIntrinsicID() == Intrinsic::coro_id_retcon; 257360784Sdim } 258360784Sdim static bool classof(const Value *V) { 259360784Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 260360784Sdim } 261360784Sdim}; 262360784Sdim 263360784Sdim/// This represents the llvm.coro.id.retcon.once instruction. 264360784Sdimclass LLVM_LIBRARY_VISIBILITY CoroIdRetconOnceInst 265360784Sdim : public AnyCoroIdRetconInst { 266360784Sdimpublic: 267360784Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 268360784Sdim static bool classof(const IntrinsicInst *I) { 269360784Sdim return I->getIntrinsicID() == Intrinsic::coro_id_retcon_once; 270360784Sdim } 271360784Sdim static bool classof(const Value *V) { 272360784Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 273360784Sdim } 274360784Sdim}; 275360784Sdim 276311116Sdim/// This represents the llvm.coro.frame instruction. 277311116Sdimclass LLVM_LIBRARY_VISIBILITY CoroFrameInst : public IntrinsicInst { 278311116Sdimpublic: 279311116Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 280321369Sdim static bool classof(const IntrinsicInst *I) { 281311116Sdim return I->getIntrinsicID() == Intrinsic::coro_frame; 282311116Sdim } 283321369Sdim static bool classof(const Value *V) { 284311116Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 285311116Sdim } 286311116Sdim}; 287311116Sdim 288311116Sdim/// This represents the llvm.coro.free instruction. 289311116Sdimclass LLVM_LIBRARY_VISIBILITY CoroFreeInst : public IntrinsicInst { 290311116Sdim enum { IdArg, FrameArg }; 291311116Sdim 292311116Sdimpublic: 293311116Sdim Value *getFrame() const { return getArgOperand(FrameArg); } 294311116Sdim 295311116Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 296321369Sdim static bool classof(const IntrinsicInst *I) { 297311116Sdim return I->getIntrinsicID() == Intrinsic::coro_free; 298311116Sdim } 299321369Sdim static bool classof(const Value *V) { 300311116Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 301311116Sdim } 302311116Sdim}; 303311116Sdim 304311116Sdim/// This class represents the llvm.coro.begin instruction. 305311116Sdimclass LLVM_LIBRARY_VISIBILITY CoroBeginInst : public IntrinsicInst { 306311116Sdim enum { IdArg, MemArg }; 307311116Sdim 308311116Sdimpublic: 309360784Sdim AnyCoroIdInst *getId() const { 310360784Sdim return cast<AnyCoroIdInst>(getArgOperand(IdArg)); 311360784Sdim } 312311116Sdim 313311116Sdim Value *getMem() const { return getArgOperand(MemArg); } 314311116Sdim 315311116Sdim // Methods for support type inquiry through isa, cast, and dyn_cast: 316321369Sdim static bool classof(const IntrinsicInst *I) { 317311116Sdim return I->getIntrinsicID() == Intrinsic::coro_begin; 318311116Sdim } 319321369Sdim static bool classof(const Value *V) { 320311116Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 321311116Sdim } 322311116Sdim}; 323311116Sdim 324311116Sdim/// This represents the llvm.coro.save instruction. 325311116Sdimclass LLVM_LIBRARY_VISIBILITY CoroSaveInst : public IntrinsicInst { 326311116Sdimpublic: 327311116Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 328321369Sdim static bool classof(const IntrinsicInst *I) { 329311116Sdim return I->getIntrinsicID() == Intrinsic::coro_save; 330311116Sdim } 331321369Sdim static bool classof(const Value *V) { 332311116Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 333311116Sdim } 334311116Sdim}; 335311116Sdim 336311116Sdim/// This represents the llvm.coro.promise instruction. 337311116Sdimclass LLVM_LIBRARY_VISIBILITY CoroPromiseInst : public IntrinsicInst { 338311116Sdim enum { FrameArg, AlignArg, FromArg }; 339311116Sdim 340311116Sdimpublic: 341311116Sdim bool isFromPromise() const { 342311116Sdim return cast<Constant>(getArgOperand(FromArg))->isOneValue(); 343311116Sdim } 344311116Sdim unsigned getAlignment() const { 345311116Sdim return cast<ConstantInt>(getArgOperand(AlignArg))->getZExtValue(); 346311116Sdim } 347311116Sdim 348311116Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 349321369Sdim static bool classof(const IntrinsicInst *I) { 350311116Sdim return I->getIntrinsicID() == Intrinsic::coro_promise; 351311116Sdim } 352321369Sdim static bool classof(const Value *V) { 353311116Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 354311116Sdim } 355311116Sdim}; 356311116Sdim 357360784Sdimclass LLVM_LIBRARY_VISIBILITY AnyCoroSuspendInst : public IntrinsicInst { 358360784Sdimpublic: 359360784Sdim CoroSaveInst *getCoroSave() const; 360360784Sdim 361360784Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 362360784Sdim static bool classof(const IntrinsicInst *I) { 363360784Sdim return I->getIntrinsicID() == Intrinsic::coro_suspend || 364360784Sdim I->getIntrinsicID() == Intrinsic::coro_suspend_retcon; 365360784Sdim } 366360784Sdim static bool classof(const Value *V) { 367360784Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 368360784Sdim } 369360784Sdim}; 370360784Sdim 371311116Sdim/// This represents the llvm.coro.suspend instruction. 372360784Sdimclass LLVM_LIBRARY_VISIBILITY CoroSuspendInst : public AnyCoroSuspendInst { 373311116Sdim enum { SaveArg, FinalArg }; 374311116Sdim 375311116Sdimpublic: 376311116Sdim CoroSaveInst *getCoroSave() const { 377311116Sdim Value *Arg = getArgOperand(SaveArg); 378311116Sdim if (auto *SI = dyn_cast<CoroSaveInst>(Arg)) 379311116Sdim return SI; 380311116Sdim assert(isa<ConstantTokenNone>(Arg)); 381311116Sdim return nullptr; 382311116Sdim } 383360784Sdim 384311116Sdim bool isFinal() const { 385311116Sdim return cast<Constant>(getArgOperand(FinalArg))->isOneValue(); 386311116Sdim } 387311116Sdim 388311116Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 389321369Sdim static bool classof(const IntrinsicInst *I) { 390311116Sdim return I->getIntrinsicID() == Intrinsic::coro_suspend; 391311116Sdim } 392321369Sdim static bool classof(const Value *V) { 393311116Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 394311116Sdim } 395311116Sdim}; 396311116Sdim 397360784Sdiminline CoroSaveInst *AnyCoroSuspendInst::getCoroSave() const { 398360784Sdim if (auto Suspend = dyn_cast<CoroSuspendInst>(this)) 399360784Sdim return Suspend->getCoroSave(); 400360784Sdim return nullptr; 401360784Sdim} 402360784Sdim 403360784Sdim/// This represents the llvm.coro.suspend.retcon instruction. 404360784Sdimclass LLVM_LIBRARY_VISIBILITY CoroSuspendRetconInst : public AnyCoroSuspendInst { 405360784Sdimpublic: 406360784Sdim op_iterator value_begin() { return arg_begin(); } 407360784Sdim const_op_iterator value_begin() const { return arg_begin(); } 408360784Sdim 409360784Sdim op_iterator value_end() { return arg_end(); } 410360784Sdim const_op_iterator value_end() const { return arg_end(); } 411360784Sdim 412360784Sdim iterator_range<op_iterator> value_operands() { 413360784Sdim return make_range(value_begin(), value_end()); 414360784Sdim } 415360784Sdim iterator_range<const_op_iterator> value_operands() const { 416360784Sdim return make_range(value_begin(), value_end()); 417360784Sdim } 418360784Sdim 419360784Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 420360784Sdim static bool classof(const IntrinsicInst *I) { 421360784Sdim return I->getIntrinsicID() == Intrinsic::coro_suspend_retcon; 422360784Sdim } 423360784Sdim static bool classof(const Value *V) { 424360784Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 425360784Sdim } 426360784Sdim}; 427360784Sdim 428311116Sdim/// This represents the llvm.coro.size instruction. 429311116Sdimclass LLVM_LIBRARY_VISIBILITY CoroSizeInst : public IntrinsicInst { 430311116Sdimpublic: 431311116Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 432321369Sdim static bool classof(const IntrinsicInst *I) { 433311116Sdim return I->getIntrinsicID() == Intrinsic::coro_size; 434311116Sdim } 435321369Sdim static bool classof(const Value *V) { 436311116Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 437311116Sdim } 438311116Sdim}; 439311116Sdim 440311116Sdim/// This represents the llvm.coro.end instruction. 441311116Sdimclass LLVM_LIBRARY_VISIBILITY CoroEndInst : public IntrinsicInst { 442311116Sdim enum { FrameArg, UnwindArg }; 443311116Sdim 444311116Sdimpublic: 445311116Sdim bool isFallthrough() const { return !isUnwind(); } 446311116Sdim bool isUnwind() const { 447311116Sdim return cast<Constant>(getArgOperand(UnwindArg))->isOneValue(); 448311116Sdim } 449311116Sdim 450311116Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 451321369Sdim static bool classof(const IntrinsicInst *I) { 452311116Sdim return I->getIntrinsicID() == Intrinsic::coro_end; 453311116Sdim } 454321369Sdim static bool classof(const Value *V) { 455311116Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 456311116Sdim } 457311116Sdim}; 458311116Sdim 459360784Sdim/// This represents the llvm.coro.alloca.alloc instruction. 460360784Sdimclass LLVM_LIBRARY_VISIBILITY CoroAllocaAllocInst : public IntrinsicInst { 461360784Sdim enum { SizeArg, AlignArg }; 462360784Sdimpublic: 463360784Sdim Value *getSize() const { 464360784Sdim return getArgOperand(SizeArg); 465360784Sdim } 466360784Sdim unsigned getAlignment() const { 467360784Sdim return cast<ConstantInt>(getArgOperand(AlignArg))->getZExtValue(); 468360784Sdim } 469360784Sdim 470360784Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 471360784Sdim static bool classof(const IntrinsicInst *I) { 472360784Sdim return I->getIntrinsicID() == Intrinsic::coro_alloca_alloc; 473360784Sdim } 474360784Sdim static bool classof(const Value *V) { 475360784Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 476360784Sdim } 477360784Sdim}; 478360784Sdim 479360784Sdim/// This represents the llvm.coro.alloca.get instruction. 480360784Sdimclass LLVM_LIBRARY_VISIBILITY CoroAllocaGetInst : public IntrinsicInst { 481360784Sdim enum { AllocArg }; 482360784Sdimpublic: 483360784Sdim CoroAllocaAllocInst *getAlloc() const { 484360784Sdim return cast<CoroAllocaAllocInst>(getArgOperand(AllocArg)); 485360784Sdim } 486360784Sdim 487360784Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 488360784Sdim static bool classof(const IntrinsicInst *I) { 489360784Sdim return I->getIntrinsicID() == Intrinsic::coro_alloca_get; 490360784Sdim } 491360784Sdim static bool classof(const Value *V) { 492360784Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 493360784Sdim } 494360784Sdim}; 495360784Sdim 496360784Sdim/// This represents the llvm.coro.alloca.free instruction. 497360784Sdimclass LLVM_LIBRARY_VISIBILITY CoroAllocaFreeInst : public IntrinsicInst { 498360784Sdim enum { AllocArg }; 499360784Sdimpublic: 500360784Sdim CoroAllocaAllocInst *getAlloc() const { 501360784Sdim return cast<CoroAllocaAllocInst>(getArgOperand(AllocArg)); 502360784Sdim } 503360784Sdim 504360784Sdim // Methods to support type inquiry through isa, cast, and dyn_cast: 505360784Sdim static bool classof(const IntrinsicInst *I) { 506360784Sdim return I->getIntrinsicID() == Intrinsic::coro_alloca_free; 507360784Sdim } 508360784Sdim static bool classof(const Value *V) { 509360784Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 510360784Sdim } 511360784Sdim}; 512360784Sdim 513311116Sdim} // End namespace llvm. 514321369Sdim 515321369Sdim#endif 516