LLVM  6.0.0svn
CoroInstr.h
Go to the documentation of this file.
1 //===-- CoroInstr.h - Coroutine Intrinsics Instruction Wrappers -*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // This file defines classes that make it really easy to deal with intrinsic
10 // functions with the isa/dyncast family of functions. In particular, this
11 // allows you to do things like:
12 //
13 // if (auto *SF = dyn_cast<CoroSubFnInst>(Inst))
14 // ... SF->getFrame() ...
15 //
16 // All intrinsic function calls are instances of the call instruction, so these
17 // are all subclasses of the CallInst class. Note that none of these classes
18 // has state or virtual methods, which is an important part of this gross/neat
19 // hack working.
20 //
21 // The helpful comment above is borrowed from llvm/IntrinsicInst.h, we keep
22 // coroutine intrinsic wrappers here since they are only used by the passes in
23 // the Coroutine library.
24 //===----------------------------------------------------------------------===//
25 
26 #ifndef LLVM_LIB_TRANSFORMS_COROUTINES_COROINSTR_H
27 #define LLVM_LIB_TRANSFORMS_COROUTINES_COROINSTR_H
28 
29 #include "llvm/IR/GlobalVariable.h"
30 #include "llvm/IR/IntrinsicInst.h"
31 
32 namespace llvm {
33 
34 /// This class represents the llvm.coro.subfn.addr instruction.
36  enum { FrameArg, IndexArg };
37 
38 public:
39  enum ResumeKind {
40  RestartTrigger = -1,
45  IndexFirst = RestartTrigger
46  };
47 
48  Value *getFrame() const { return getArgOperand(FrameArg); }
49  ResumeKind getIndex() const {
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.
71 public:
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.alloc instruction.
83  enum { AlignArg, PromiseArg, CoroutineArg, InfoArg };
84 
85 public:
87  for (User *U : users())
88  if (auto *CA = dyn_cast<CoroAllocInst>(U))
89  return CA;
90  return nullptr;
91  }
92 
94  for (User *U : users())
95  if (auto *II = dyn_cast<IntrinsicInst>(U))
96  if (II->getIntrinsicID() == Intrinsic::coro_begin)
97  return II;
98  llvm_unreachable("no coro.begin associated with coro.id");
99  }
100 
102  Value *Arg = getArgOperand(PromiseArg);
103  return isa<ConstantPointerNull>(Arg)
104  ? nullptr
105  : cast<AllocaInst>(Arg->stripPointerCasts());
106  }
107 
108  void clearPromise() {
109  Value *Arg = getArgOperand(PromiseArg);
110  setArgOperand(PromiseArg,
112  if (isa<AllocaInst>(Arg))
113  return;
114  assert((isa<BitCastInst>(Arg) || isa<GetElementPtrInst>(Arg)) &&
115  "unexpected instruction designating the promise");
116  // TODO: Add a check that any remaining users of Inst are after coro.begin
117  // or add code to move the users after coro.begin.
118  auto *Inst = cast<Instruction>(Arg);
119  if (Inst->use_empty()) {
120  Inst->eraseFromParent();
121  return;
122  }
123  Inst->moveBefore(getCoroBegin()->getNextNode());
124  }
125 
126  // Info argument of coro.id is
127  // fresh out of the frontend: null ;
128  // outlined : {Init, Return, Susp1, Susp2, ...} ;
129  // postsplit : [resume, destroy, cleanup] ;
130  //
131  // If parts of the coroutine were outlined to protect against undesirable
132  // code motion, these functions will be stored in a struct literal referred to
133  // by the Info parameter. Note: this is only needed before coroutine is split.
134  //
135  // After coroutine is split, resume functions are stored in an array
136  // referred to by this parameter.
137 
138  struct Info {
139  ConstantStruct *OutlinedParts = nullptr;
140  ConstantArray *Resumers = nullptr;
141 
142  bool hasOutlinedParts() const { return OutlinedParts != nullptr; }
143  bool isPostSplit() const { return Resumers != nullptr; }
144  bool isPreSplit() const { return !isPostSplit(); }
145  };
146  Info getInfo() const {
147  Info Result;
148  auto *GV = dyn_cast<GlobalVariable>(getRawInfo());
149  if (!GV)
150  return Result;
151 
152  assert(GV->isConstant() && GV->hasDefinitiveInitializer());
153  Constant *Initializer = GV->getInitializer();
154  if ((Result.OutlinedParts = dyn_cast<ConstantStruct>(Initializer)))
155  return Result;
156 
157  Result.Resumers = cast<ConstantArray>(Initializer);
158  return Result;
159  }
160  Constant *getRawInfo() const {
161  return cast<Constant>(getArgOperand(InfoArg)->stripPointerCasts());
162  }
163 
164  void setInfo(Constant *C) { setArgOperand(InfoArg, C); }
165 
167  return cast<Function>(getArgOperand(CoroutineArg)->stripPointerCasts());
168  }
170  assert(isa<ConstantPointerNull>(getArgOperand(CoroutineArg)) &&
171  "Coroutine argument is already assigned");
172  auto *const Int8PtrTy = Type::getInt8PtrTy(getContext());
173  setArgOperand(CoroutineArg,
174  ConstantExpr::getBitCast(getFunction(), Int8PtrTy));
175  }
176 
177  // Methods to support type inquiry through isa, cast, and dyn_cast:
178  static bool classof(const IntrinsicInst *I) {
179  return I->getIntrinsicID() == Intrinsic::coro_id;
180  }
181  static bool classof(const Value *V) {
182  return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
183  }
184 };
185 
186 /// This represents the llvm.coro.frame instruction.
188 public:
189  // Methods to support type inquiry through isa, cast, and dyn_cast:
190  static bool classof(const IntrinsicInst *I) {
191  return I->getIntrinsicID() == Intrinsic::coro_frame;
192  }
193  static bool classof(const Value *V) {
194  return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
195  }
196 };
197 
198 /// This represents the llvm.coro.free instruction.
200  enum { IdArg, FrameArg };
201 
202 public:
203  Value *getFrame() const { return getArgOperand(FrameArg); }
204 
205  // Methods to support type inquiry through isa, cast, and dyn_cast:
206  static bool classof(const IntrinsicInst *I) {
207  return I->getIntrinsicID() == Intrinsic::coro_free;
208  }
209  static bool classof(const Value *V) {
210  return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
211  }
212 };
213 
214 /// This class represents the llvm.coro.begin instruction.
216  enum { IdArg, MemArg };
217 
218 public:
219  CoroIdInst *getId() const { return cast<CoroIdInst>(getArgOperand(IdArg)); }
220 
221  Value *getMem() const { return getArgOperand(MemArg); }
222 
223  // Methods for support type inquiry through isa, cast, and dyn_cast:
224  static bool classof(const IntrinsicInst *I) {
225  return I->getIntrinsicID() == Intrinsic::coro_begin;
226  }
227  static bool classof(const Value *V) {
228  return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
229  }
230 };
231 
232 /// This represents the llvm.coro.save instruction.
234 public:
235  // Methods to support type inquiry through isa, cast, and dyn_cast:
236  static bool classof(const IntrinsicInst *I) {
237  return I->getIntrinsicID() == Intrinsic::coro_save;
238  }
239  static bool classof(const Value *V) {
240  return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
241  }
242 };
243 
244 /// This represents the llvm.coro.promise instruction.
246  enum { FrameArg, AlignArg, FromArg };
247 
248 public:
249  bool isFromPromise() const {
250  return cast<Constant>(getArgOperand(FromArg))->isOneValue();
251  }
252  unsigned getAlignment() const {
253  return cast<ConstantInt>(getArgOperand(AlignArg))->getZExtValue();
254  }
255 
256  // Methods to support type inquiry through isa, cast, and dyn_cast:
257  static bool classof(const IntrinsicInst *I) {
258  return I->getIntrinsicID() == Intrinsic::coro_promise;
259  }
260  static bool classof(const Value *V) {
261  return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
262  }
263 };
264 
265 /// This represents the llvm.coro.suspend instruction.
267  enum { SaveArg, FinalArg };
268 
269 public:
271  Value *Arg = getArgOperand(SaveArg);
272  if (auto *SI = dyn_cast<CoroSaveInst>(Arg))
273  return SI;
274  assert(isa<ConstantTokenNone>(Arg));
275  return nullptr;
276  }
277  bool isFinal() const {
278  return cast<Constant>(getArgOperand(FinalArg))->isOneValue();
279  }
280 
281  // Methods to support type inquiry through isa, cast, and dyn_cast:
282  static bool classof(const IntrinsicInst *I) {
283  return I->getIntrinsicID() == Intrinsic::coro_suspend;
284  }
285  static bool classof(const Value *V) {
286  return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
287  }
288 };
289 
290 /// This represents the llvm.coro.size instruction.
292 public:
293  // Methods to support type inquiry through isa, cast, and dyn_cast:
294  static bool classof(const IntrinsicInst *I) {
295  return I->getIntrinsicID() == Intrinsic::coro_size;
296  }
297  static bool classof(const Value *V) {
298  return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
299  }
300 };
301 
302 /// This represents the llvm.coro.end instruction.
304  enum { FrameArg, UnwindArg };
305 
306 public:
307  bool isFallthrough() const { return !isUnwind(); }
308  bool isUnwind() const {
309  return cast<Constant>(getArgOperand(UnwindArg))->isOneValue();
310  }
311 
312  // Methods to support type inquiry through isa, cast, and dyn_cast:
313  static bool classof(const IntrinsicInst *I) {
314  return I->getIntrinsicID() == Intrinsic::coro_end;
315  }
316  static bool classof(const Value *V) {
317  return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
318  }
319 };
320 
321 } // End namespace llvm.
322 
323 #endif
uint64_t CallInst * C
This represents the llvm.coro.promise instruction.
Definition: CoroInstr.h:245
This represents the llvm.coro.alloc instruction.
Definition: CoroInstr.h:82
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:224
IntrinsicInst * getCoroBegin()
Definition: CoroInstr.h:93
Info getInfo() const
Definition: CoroInstr.h:146
unsigned getAlignment() const
Definition: CoroInstr.h:252
ConstantInt * getRawIndex() const
Definition: CoroInstr.h:56
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:178
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:313
static bool classof(const Value *V)
Definition: CoroInstr.h:227
This represents the llvm.coro.suspend instruction.
Definition: CoroInstr.h:266
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:190
AllocaInst * getPromise() const
Definition: CoroInstr.h:101
This class represents the llvm.coro.subfn.addr instruction.
Definition: CoroInstr.h:35
ConstantStruct * OutlinedParts
Definition: CoroInstr.h:139
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:236
bool isPreSplit() const
Definition: CoroInstr.h:144
This represents the llvm.coro.alloc instruction.
Definition: CoroInstr.h:70
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:61
void setCoroutineSelf()
Definition: CoroInstr.h:169
bool isFallthrough() const
Definition: CoroInstr.h:307
static bool classof(const Value *V)
Definition: CoroInstr.h:239
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:1678
This represents the llvm.coro.size instruction.
Definition: CoroInstr.h:291
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
Definition: Constants.cpp:1306
bool isFinal() const
Definition: CoroInstr.h:277
bool isPostSplit() const
Definition: CoroInstr.h:143
This is an important base class in LLVM.
Definition: Constant.h:42
ResumeKind getIndex() const
Definition: CoroInstr.h:49
Value * getMem() const
Definition: CoroInstr.h:221
static bool classof(const Value *V)
Definition: CoroInstr.h:64
This represents the llvm.coro.end instruction.
Definition: CoroInstr.h:303
bool isFromPromise() const
Definition: CoroInstr.h:249
This represents the llvm.coro.save instruction.
Definition: CoroInstr.h:233
#define LLVM_LIBRARY_VISIBILITY
LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked into a shared library...
Definition: Compiler.h:105
static bool classof(const Value *V)
Definition: CoroInstr.h:297
static bool classof(const Value *V)
Definition: CoroInstr.h:193
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs, and aliases.
Definition: Value.cpp:558
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:220
This represents the llvm.coro.free instruction.
Definition: CoroInstr.h:199
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:257
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Definition: IntrinsicInst.h:51
static bool classof(const Value *V)
Definition: CoroInstr.h:285
This is the shared class of boolean and integer constants.
Definition: Constants.h:84
static bool classof(const Value *V)
Definition: CoroInstr.h:76
bool hasOutlinedParts() const
Definition: CoroInstr.h:142
This class represents the llvm.coro.begin instruction.
Definition: CoroInstr.h:215
ConstantArray - Constant Array Declarations.
Definition: Constants.h:405
ConstantArray * Resumers
Definition: CoroInstr.h:140
bool isUnwind() const
Definition: CoroInstr.h:308
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:206
amdgpu Simplify well known AMD library false Value Value * Arg
void clearPromise()
Definition: CoroInstr.h:108
iv users
Definition: IVUsers.cpp:51
Value * getFrame() const
Definition: CoroInstr.h:203
static bool classof(const Value *V)
Definition: CoroInstr.h:316
static bool classof(const Value *V)
Definition: CoroInstr.h:209
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:294
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:282
static bool classof(const Value *V)
Definition: CoroInstr.h:181
#define I(x, y, z)
Definition: MD5.cpp:58
Function * getCoroutine() const
Definition: CoroInstr.h:166
static bool classof(const IntrinsicInst *I)
Definition: CoroInstr.h:73
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
Value * getFrame() const
Definition: CoroInstr.h:48
CoroIdInst * getId() const
Definition: CoroInstr.h:219
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This represents the llvm.coro.frame instruction.
Definition: CoroInstr.h:187
LLVM Value Representation.
Definition: Value.h:73
void setInfo(Constant *C)
Definition: CoroInstr.h:164
CoroAllocInst * getCoroAlloc()
Definition: CoroInstr.h:86
static bool classof(const Value *V)
Definition: CoroInstr.h:260
CoroSaveInst * getCoroSave() const
Definition: CoroInstr.h:270
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:44
an instruction to allocate memory on the stack
Definition: Instructions.h:60
Constant * getRawInfo() const
Definition: CoroInstr.h:160