LLVM  3.7.0
Statepoint.h
Go to the documentation of this file.
1 //===-- llvm/IR/Statepoint.h - gc.statepoint utilities ------ --*- 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 //
10 // This file contains utility functions and a wrapper class analogous to
11 // CallSite for accessing the fields of gc.statepoint, gc.relocate, and
12 // gc.result intrinsics
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_IR_STATEPOINT_H
17 #define LLVM_IR_STATEPOINT_H
18 
20 #include "llvm/IR/BasicBlock.h"
21 #include "llvm/IR/CallSite.h"
22 #include "llvm/IR/Constants.h"
23 #include "llvm/IR/Function.h"
24 #include "llvm/IR/Instructions.h"
25 #include "llvm/IR/Intrinsics.h"
26 #include "llvm/Support/Compiler.h"
27 
28 namespace llvm {
29 /// The statepoint intrinsic accepts a set of flags as its third argument.
30 /// Valid values come out of this set.
31 enum class StatepointFlags {
32  None = 0,
33  GCTransition = 1, ///< Indicates that this statepoint is a transition from
34  ///< GC-aware code to code that is not GC-aware.
35 
36  MaskAll = GCTransition ///< A bitmask that includes all valid flags.
37 };
38 
39 class GCRelocateOperands;
40 class ImmutableStatepoint;
41 
42 bool isStatepoint(const ImmutableCallSite &CS);
43 bool isStatepoint(const Value *V);
44 bool isStatepoint(const Value &V);
45 
46 bool isGCRelocate(const Value *V);
47 bool isGCRelocate(const ImmutableCallSite &CS);
48 
49 bool isGCResult(const Value *V);
50 bool isGCResult(const ImmutableCallSite &CS);
51 
52 /// Analogous to CallSiteBase, this provides most of the actual
53 /// functionality for Statepoint and ImmutableStatepoint. It is
54 /// templatized to allow easily specializing of const and non-const
55 /// concrete subtypes. This is structured analogous to CallSite
56 /// rather than the IntrinsicInst.h helpers since we want to support
57 /// invokable statepoints in the near future.
58 template <typename FunTy, typename InstructionTy, typename ValueTy,
59  typename CallSiteTy>
61  CallSiteTy StatepointCS;
62  void *operator new(size_t, unsigned) = delete;
63  void *operator new(size_t s) = delete;
64 
65 protected:
66  explicit StatepointBase(InstructionTy *I) {
67  if (isStatepoint(I)) {
68  StatepointCS = CallSiteTy(I);
69  assert(StatepointCS && "isStatepoint implies CallSite");
70  }
71  }
72  explicit StatepointBase(CallSiteTy CS) {
73  if (isStatepoint(CS))
74  StatepointCS = CS;
75  }
76 
77 public:
78  typedef typename CallSiteTy::arg_iterator arg_iterator;
79 
80  enum {
81  IDPos = 0,
85  FlagsPos = 4,
87  };
88 
89  explicit operator bool() const {
90  // We do not assign non-statepoint CallSites to StatepointCS.
91  return (bool)StatepointCS;
92  }
93 
94  /// Return the underlying CallSite.
95  CallSiteTy getCallSite() const {
96  assert(*this && "check validity first!");
97  return StatepointCS;
98  }
99 
100  uint64_t getFlags() const {
101  return cast<ConstantInt>(getCallSite().getArgument(FlagsPos))
102  ->getZExtValue();
103  }
104 
105  /// Return the ID associated with this statepoint.
106  uint64_t getID() const {
107  const Value *IDVal = getCallSite().getArgument(IDPos);
108  return cast<ConstantInt>(IDVal)->getZExtValue();
109  }
110 
111  /// Return the number of patchable bytes associated with this statepoint.
112  uint32_t getNumPatchBytes() const {
113  const Value *NumPatchBytesVal = getCallSite().getArgument(NumPatchBytesPos);
114  uint64_t NumPatchBytes =
115  cast<ConstantInt>(NumPatchBytesVal)->getZExtValue();
116  assert(isInt<32>(NumPatchBytes) && "should fit in 32 bits!");
117  return NumPatchBytes;
118  }
119 
120  /// Return the value actually being called or invoked.
121  ValueTy *getCalledValue() const {
122  return getCallSite().getArgument(CalledFunctionPos);
123  }
124 
125  InstructionTy *getInstruction() const {
126  return getCallSite().getInstruction();
127  }
128 
129  /// Return the function being called if this is a direct call, otherwise
130  /// return null (if it's an indirect call).
131  FunTy *getCalledFunction() const {
132  return dyn_cast<Function>(getCalledValue());
133  }
134 
135  /// Return the caller function for this statepoint.
136  FunTy *getCaller() const { return getCallSite().getCaller(); }
137 
138  /// Determine if the statepoint cannot unwind.
139  bool doesNotThrow() const {
141  return getCallSite().doesNotThrow() || (F ? F->doesNotThrow() : false);
142  }
143 
144  /// Return the type of the value returned by the call underlying the
145  /// statepoint.
147  auto *FTy = cast<FunctionType>(
148  cast<PointerType>(getCalledValue()->getType())->getElementType());
149  return FTy->getReturnType();
150  }
151 
152  /// Number of arguments to be passed to the actual callee.
153  int getNumCallArgs() const {
154  const Value *NumCallArgsVal = getCallSite().getArgument(NumCallArgsPos);
155  return cast<ConstantInt>(NumCallArgsVal)->getZExtValue();
156  }
157 
158  size_t arg_size() const { return getNumCallArgs(); }
159  typename CallSiteTy::arg_iterator arg_begin() const {
160  assert(CallArgsBeginPos <= (int)getCallSite().arg_size());
161  return getCallSite().arg_begin() + CallArgsBeginPos;
162  }
163  typename CallSiteTy::arg_iterator arg_end() const {
164  auto I = arg_begin() + arg_size();
165  assert((getCallSite().arg_end() - I) >= 0);
166  return I;
167  }
168 
169  ValueTy *getArgument(unsigned Index) {
170  assert(Index < arg_size() && "out of bounds!");
171  return *(arg_begin() + Index);
172  }
173 
174  /// range adapter for call arguments
177  }
178 
179  /// \brief Return true if the call or the callee has the given attribute.
180  bool paramHasAttr(unsigned i, Attribute::AttrKind A) const {
182  return getCallSite().paramHasAttr(i + CallArgsBeginPos, A) ||
183  (F ? F->getAttributes().hasAttribute(i, A) : false);
184  }
185 
186  /// Number of GC transition args.
188  const Value *NumGCTransitionArgs = *arg_end();
189  return cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue();
190  }
191  typename CallSiteTy::arg_iterator gc_transition_args_begin() const {
192  auto I = arg_end() + 1;
193  assert((getCallSite().arg_end() - I) >= 0);
194  return I;
195  }
196  typename CallSiteTy::arg_iterator gc_transition_args_end() const {
198  assert((getCallSite().arg_end() - I) >= 0);
199  return I;
200  }
201 
202  /// range adapter for GC transition arguments
206  }
207 
208  /// Number of additional arguments excluding those intended
209  /// for garbage collection.
210  int getNumTotalVMSArgs() const {
211  const Value *NumVMSArgs = *gc_transition_args_end();
212  return cast<ConstantInt>(NumVMSArgs)->getZExtValue();
213  }
214 
215  typename CallSiteTy::arg_iterator vm_state_begin() const {
216  auto I = gc_transition_args_end() + 1;
217  assert((getCallSite().arg_end() - I) >= 0);
218  return I;
219  }
220  typename CallSiteTy::arg_iterator vm_state_end() const {
221  auto I = vm_state_begin() + getNumTotalVMSArgs();
222  assert((getCallSite().arg_end() - I) >= 0);
223  return I;
224  }
225 
226  /// range adapter for vm state arguments
229  }
230 
231  typename CallSiteTy::arg_iterator gc_args_begin() const {
232  return vm_state_end();
233  }
234  typename CallSiteTy::arg_iterator gc_args_end() const {
235  return getCallSite().arg_end();
236  }
237 
238  /// range adapter for gc arguments
241  }
242 
243  /// Get list of all gc reloactes linked to this statepoint
244  /// May contain several relocations for the same base/derived pair.
245  /// For example this could happen due to relocations on unwinding
246  /// path of invoke.
247  std::vector<GCRelocateOperands> getRelocates() const;
248 
249  /// Get the experimental_gc_result call tied to this statepoint. Can be
250  /// nullptr if there isn't a gc_result tied to this statepoint. Guaranteed to
251  /// be a CallInst if non-null.
252  InstructionTy *getGCResult() const {
253  for (auto *U : getInstruction()->users())
254  if (isGCResult(U))
255  return cast<CallInst>(U);
256 
257  return nullptr;
258  }
259 
260 #ifndef NDEBUG
261  /// Asserts if this statepoint is malformed. Common cases for failure
262  /// include incorrect length prefixes for variable length sections or
263  /// illegal values for parameters.
264  void verify() {
265  assert(getNumCallArgs() >= 0 &&
266  "number of arguments to actually callee can't be negative");
267 
268  // The internal asserts in the iterator accessors do the rest.
269  (void)arg_begin();
270  (void)arg_end();
271  (void)gc_transition_args_begin();
272  (void)gc_transition_args_end();
273  (void)vm_state_begin();
274  (void)vm_state_end();
275  (void)gc_args_begin();
276  (void)gc_args_end();
277  }
278 #endif
279 };
280 
281 /// A specialization of it's base class for read only access
282 /// to a gc.statepoint.
284  : public StatepointBase<const Function, const Instruction, const Value,
285  ImmutableCallSite> {
286  typedef StatepointBase<const Function, const Instruction, const Value,
288 
289 public:
290  explicit ImmutableStatepoint(const Instruction *I) : Base(I) {}
292 };
293 
294 /// A specialization of it's base class for read-write access
295 /// to a gc.statepoint.
297  : public StatepointBase<Function, Instruction, Value, CallSite> {
299 
300 public:
301  explicit Statepoint(Instruction *I) : Base(I) {}
302  explicit Statepoint(CallSite CS) : Base(CS) {}
303 };
304 
305 /// Wraps a call to a gc.relocate and provides access to it's operands.
306 /// TODO: This should likely be refactored to resememble the wrappers in
307 /// InstrinsicInst.h.
309  ImmutableCallSite RelocateCS;
310 
311 public:
312  GCRelocateOperands(const User *U) : RelocateCS(U) { assert(isGCRelocate(U)); }
313  GCRelocateOperands(const Instruction *inst) : RelocateCS(inst) {
314  assert(isGCRelocate(inst));
315  }
316  GCRelocateOperands(CallSite CS) : RelocateCS(CS) { assert(isGCRelocate(CS)); }
317 
318  /// Return true if this relocate is tied to the invoke statepoint.
319  /// This includes relocates which are on the unwinding path.
320  bool isTiedToInvoke() const {
321  const Value *Token = RelocateCS.getArgument(0);
322 
323  return isa<ExtractValueInst>(Token) || isa<InvokeInst>(Token);
324  }
325 
326  /// Get enclosed relocate intrinsic
327  ImmutableCallSite getUnderlyingCallSite() { return RelocateCS; }
328 
329  /// The statepoint with which this gc.relocate is associated.
331  const Value *Token = RelocateCS.getArgument(0);
332 
333  // This takes care both of relocates for call statepoints and relocates
334  // on normal path of invoke statepoint.
335  if (!isa<ExtractValueInst>(Token)) {
336  return cast<Instruction>(Token);
337  }
338 
339  // This relocate is on exceptional path of an invoke statepoint
340  const BasicBlock *InvokeBB =
341  cast<Instruction>(Token)->getParent()->getUniquePredecessor();
342 
343  assert(InvokeBB && "safepoints should have unique landingpads");
344  assert(InvokeBB->getTerminator() &&
345  "safepoint block should be well formed");
346  assert(isStatepoint(InvokeBB->getTerminator()));
347 
348  return InvokeBB->getTerminator();
349  }
350 
351  /// The index into the associate statepoint's argument list
352  /// which contains the base pointer of the pointer whose
353  /// relocation this gc.relocate describes.
354  unsigned getBasePtrIndex() {
355  return cast<ConstantInt>(RelocateCS.getArgument(1))->getZExtValue();
356  }
357 
358  /// The index into the associate statepoint's argument list which
359  /// contains the pointer whose relocation this gc.relocate describes.
360  unsigned getDerivedPtrIndex() {
361  return cast<ConstantInt>(RelocateCS.getArgument(2))->getZExtValue();
362  }
363 
366  return *(CS.arg_begin() + getBasePtrIndex());
367  }
368 
371  return *(CS.arg_begin() + getDerivedPtrIndex());
372  }
373 };
374 
375 template <typename FunTy, typename InstructionTy, typename ValueTy,
376  typename CallSiteTy>
377 std::vector<GCRelocateOperands>
379  const {
380 
381  std::vector<GCRelocateOperands> Result;
382 
383  CallSiteTy StatepointCS = getCallSite();
384 
385  // Search for relocated pointers. Note that working backwards from the
386  // gc_relocates ensures that we only get pairs which are actually relocated
387  // and used after the statepoint.
388  for (const User *U : getInstruction()->users())
389  if (isGCRelocate(U))
390  Result.push_back(GCRelocateOperands(U));
391 
392  if (!StatepointCS.isInvoke())
393  return Result;
394 
395  // We need to scan thorough exceptional relocations if it is invoke statepoint
396  LandingPadInst *LandingPad =
397  cast<InvokeInst>(getInstruction())->getLandingPadInst();
398 
399  // Search for extract value from landingpad instruction to which
400  // gc relocates will be attached
401  for (const User *LandingPadUser : LandingPad->users()) {
402  if (!isa<ExtractValueInst>(LandingPadUser))
403  continue;
404 
405  // gc relocates should be attached to this extract value
406  for (const User *U : LandingPadUser->users())
407  if (isGCRelocate(U))
408  Result.push_back(GCRelocateOperands(U));
409  }
410  return Result;
411 }
412 }
413 
414 #endif
bool isInt< 32 >(int64_t x)
Definition: MathExtras.h:276
ImmutableStatepoint(const Instruction *I)
Definition: Statepoint.h:290
GCRelocateOperands(CallSite CS)
Definition: Statepoint.h:316
ValueTy * getCalledValue() const
Return the value actually being called or invoked.
Definition: Statepoint.h:121
unsigned getBasePtrIndex()
The index into the associate statepoint's argument list which contains the base pointer of the pointe...
Definition: Statepoint.h:354
Statepoint(Instruction *I)
Definition: Statepoint.h:301
StatepointFlags
The statepoint intrinsic accepts a set of flags as its third argument.
Definition: Statepoint.h:31
ValTy * getArgument(unsigned ArgNo) const
Definition: CallSite.h:119
A specialization of it's base class for read only access to a gc.statepoint.
Definition: Statepoint.h:283
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
CallSiteTy::arg_iterator gc_transition_args_end() const
Definition: Statepoint.h:196
CallSiteTy::arg_iterator vm_state_begin() const
Definition: Statepoint.h:215
F(f)
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
Definition: Attributes.cpp:956
iterator_range< arg_iterator > gc_transition_args() const
range adapter for GC transition arguments
Definition: Statepoint.h:203
bool doesNotThrow() const
Determine if the function cannot unwind.
Definition: Function.h:316
GCRelocateOperands(const Instruction *inst)
Definition: Statepoint.h:313
size_t arg_size() const
Definition: Statepoint.h:158
CallSiteTy getCallSite() const
Return the underlying CallSite.
Definition: Statepoint.h:95
bool isStatepoint(const ImmutableCallSite &CS)
Definition: Statepoint.cpp:22
ValueTy * getArgument(unsigned Index)
Definition: Statepoint.h:169
FunTy * getCalledFunction() const
Return the function being called if this is a direct call, otherwise return null (if it's an indirect...
Definition: Statepoint.h:131
unsigned getDerivedPtrIndex()
The index into the associate statepoint's argument list which contains the pointer whose relocation t...
Definition: Statepoint.h:360
InstructionTy * getInstruction() const
Definition: Statepoint.h:125
CallSiteTy::arg_iterator gc_args_begin() const
Definition: Statepoint.h:231
iterator_range< arg_iterator > vm_state_args() const
range adapter for vm state arguments
Definition: Statepoint.h:227
LandingPadInst - The landingpad instruction holds all of the information necessary to generate correc...
LLVM Basic Block Representation.
Definition: BasicBlock.h:65
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
CallSiteTy::arg_iterator gc_args_end() const
Definition: Statepoint.h:234
bool isGCRelocate(const Value *V)
Definition: Statepoint.cpp:50
This file contains the declarations for the subclasses of Constant, which represent the different fla...
iterator_range< arg_iterator > gc_args() const
range adapter for gc arguments
Definition: Statepoint.h:239
bool paramHasAttr(unsigned i, Attribute::AttrKind A) const
Return true if the call or the callee has the given attribute.
Definition: Statepoint.h:180
StatepointBase(CallSiteTy CS)
Definition: Statepoint.h:72
void verify()
Asserts if this statepoint is malformed.
Definition: Statepoint.h:264
A specialization of it's base class for read-write access to a gc.statepoint.
Definition: Statepoint.h:296
Wraps a call to a gc.relocate and provides access to it's operands.
Definition: Statepoint.h:308
GCRelocateOperands(const User *U)
Definition: Statepoint.h:312
int getNumTotalGCTransitionArgs() const
Number of GC transition args.
Definition: Statepoint.h:187
bool isTiedToInvoke() const
Return true if this relocate is tied to the invoke statepoint.
Definition: Statepoint.h:320
CallSiteTy::arg_iterator vm_state_end() const
Definition: Statepoint.h:220
uint64_t getID() const
Return the ID associated with this statepoint.
Definition: Statepoint.h:106
Indicates that this statepoint is a transition from GC-aware code to code that is not GC-aware...
ImmutableCallSite getUnderlyingCallSite()
Get enclosed relocate intrinsic.
Definition: Statepoint.h:327
CallSiteTy::arg_iterator arg_end() const
Definition: Statepoint.h:163
Type * getActualReturnType() const
Return the type of the value returned by the call underlying the statepoint.
Definition: Statepoint.h:146
int getNumCallArgs() const
Number of arguments to be passed to the actual callee.
Definition: Statepoint.h:153
AttributeSet getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:181
A range adaptor for a pair of iterators.
CallSiteTy::arg_iterator arg_iterator
Definition: Statepoint.h:78
Statepoint(CallSite CS)
Definition: Statepoint.h:302
iterator_range< user_iterator > users()
Definition: Value.h:300
CallSiteTy::arg_iterator arg_begin() const
Definition: Statepoint.h:159
LLVM_ATTRIBUTE_UNUSED_RESULT 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:285
const Instruction * getStatepoint()
The statepoint with which this gc.relocate is associated.
Definition: Statepoint.h:330
InstructionTy * getGCResult() const
Get the experimental_gc_result call tied to this statepoint.
Definition: Statepoint.h:252
iv users
Definition: IVUsers.cpp:43
FunTy * getCaller() const
Return the caller function for this statepoint.
Definition: Statepoint.h:136
std::vector< GCRelocateOperands > getRelocates() const
Get list of all gc reloactes linked to this statepoint May contain several relocations for the same b...
Definition: Statepoint.h:378
ImmutableCallSite - establish a view to a call site for examination.
Definition: CallSite.h:418
#define I(x, y, z)
Definition: MD5.cpp:54
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:124
int getNumTotalVMSArgs() const
Number of additional arguments excluding those intended for garbage collection.
Definition: Statepoint.h:210
StatepointBase(InstructionTy *I)
Definition: Statepoint.h:66
CallSiteTy::arg_iterator gc_transition_args_begin() const
Definition: Statepoint.h:191
ImmutableStatepoint(ImmutableCallSite CS)
Definition: Statepoint.h:291
iterator_range< arg_iterator > call_args() const
range adapter for call arguments
Definition: Statepoint.h:175
bool doesNotThrow() const
Determine if the statepoint cannot unwind.
Definition: Statepoint.h:139
LLVM Value Representation.
Definition: Value.h:69
Analogous to CallSiteBase, this provides most of the actual functionality for Statepoint and Immutabl...
Definition: Statepoint.h:60
static const Function * getParent(const Value *V)
IterTy arg_begin() const
arg_begin/arg_end - Return iterators corresponding to the actual argument list for a call site...
Definition: CallSite.h:151
uint32_t getNumPatchBytes() const
Return the number of patchable bytes associated with this statepoint.
Definition: Statepoint.h:112
uint64_t getFlags() const
Definition: Statepoint.h:100
bool isGCResult(const Value *V)
Definition: Statepoint.cpp:67
A bitmask that includes all valid flags.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results...
Definition: Attributes.h:64