Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/IR/Statepoint.h
Line
Count
Source (jump to first uncovered line)
1
//===- llvm/IR/Statepoint.h - gc.statepoint utilities -----------*- 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
//
9
// This file contains utility functions and a wrapper class analogous to
10
// CallBase for accessing the fields of gc.statepoint, gc.relocate,
11
// gc.result intrinsics; and some general utilities helpful when dealing with
12
// gc.statepoint.
13
//
14
//===----------------------------------------------------------------------===//
15
16
#ifndef LLVM_IR_STATEPOINT_H
17
#define LLVM_IR_STATEPOINT_H
18
19
#include "llvm/ADT/Optional.h"
20
#include "llvm/ADT/iterator_range.h"
21
#include "llvm/IR/Attributes.h"
22
#include "llvm/IR/BasicBlock.h"
23
#include "llvm/IR/Constants.h"
24
#include "llvm/IR/Function.h"
25
#include "llvm/IR/Instruction.h"
26
#include "llvm/IR/Instructions.h"
27
#include "llvm/IR/IntrinsicInst.h"
28
#include "llvm/IR/Intrinsics.h"
29
#include "llvm/Support/Casting.h"
30
#include "llvm/Support/MathExtras.h"
31
#include <cassert>
32
#include <cstddef>
33
#include <cstdint>
34
#include <vector>
35
36
namespace llvm {
37
38
/// The statepoint intrinsic accepts a set of flags as its third argument.
39
/// Valid values come out of this set.
40
enum class StatepointFlags {
41
  None = 0,
42
  GCTransition = 1, ///< Indicates that this statepoint is a transition from
43
                    ///< GC-aware code to code that is not GC-aware.
44
  /// Mark the deopt arguments associated with the statepoint as only being
45
  /// "live-in". By default, deopt arguments are "live-through".  "live-through"
46
  /// requires that they the value be live on entry, on exit, and at any point
47
  /// during the call.  "live-in" only requires the value be available at the
48
  /// start of the call.  In particular, "live-in" values can be placed in
49
  /// unused argument registers or other non-callee saved registers.
50
  DeoptLiveIn = 2,
51
52
  MaskAll = 3 ///< A bitmask that includes all valid flags.
53
};
54
55
class GCRelocateInst;
56
class GCResultInst;
57
58
bool isStatepoint(const CallBase *Call);
59
bool isStatepoint(const Value *V);
60
bool isStatepoint(const Value &V);
61
62
bool isGCRelocate(const CallBase *Call);
63
bool isGCRelocate(const Value *V);
64
65
bool isGCResult(const CallBase *Call);
66
bool isGCResult(const Value *V);
67
68
/// A wrapper around a GC intrinsic call, this provides most of the actual
69
/// functionality for Statepoint and ImmutableStatepoint.  It is
70
/// templatized to allow easily specializing of const and non-const
71
/// concrete subtypes.
72
template <typename FunTy, typename InstructionTy, typename ValueTy,
73
          typename CallBaseTy>
74
class StatepointBase {
75
  CallBaseTy *StatepointCall;
76
77
protected:
78
684
  explicit StatepointBase(InstructionTy *I) {
79
684
    StatepointCall = isStatepoint(I) ? cast<CallBaseTy>(I) : 
nullptr0
;
80
684
  }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::StatepointBase(llvm::Instruction*)
Line
Count
Source
78
682
  explicit StatepointBase(InstructionTy *I) {
79
682
    StatepointCall = isStatepoint(I) ? cast<CallBaseTy>(I) : 
nullptr0
;
80
682
  }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::StatepointBase(llvm::Instruction const*)
Line
Count
Source
78
2
  explicit StatepointBase(InstructionTy *I) {
79
2
    StatepointCall = isStatepoint(I) ? cast<CallBaseTy>(I) : 
nullptr0
;
80
2
  }
81
82
83
  explicit StatepointBase(CallBaseTy *Call) {
83
83
    StatepointCall = isStatepoint(Call) ? Call : 
nullptr0
;
84
83
  }
85
86
public:
87
  using arg_iterator = typename CallBaseTy::const_op_iterator;
88
89
  enum {
90
    IDPos = 0,
91
    NumPatchBytesPos = 1,
92
    CalledFunctionPos = 2,
93
    NumCallArgsPos = 3,
94
    FlagsPos = 4,
95
    CallArgsBeginPos = 5,
96
  };
97
98
  void *operator new(size_t, unsigned) = delete;
99
  void *operator new(size_t s) = delete;
100
101
  explicit operator bool() const {
102
    // We do not assign non-statepoint call instructions to StatepointCall.
103
    return (bool)StatepointCall;
104
  }
105
106
  /// Return the underlying call instruction.
107
9.65k
  CallBaseTy *getCall() const {
108
9.65k
    assert(*this && "check validity first!");
109
9.65k
    return StatepointCall;
110
9.65k
  }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::getCall() const
Line
Count
Source
107
6.13k
  CallBaseTy *getCall() const {
108
6.13k
    assert(*this && "check validity first!");
109
6.13k
    return StatepointCall;
110
6.13k
  }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::getCall() const
Line
Count
Source
107
3.51k
  CallBaseTy *getCall() const {
108
3.51k
    assert(*this && "check validity first!");
109
3.51k
    return StatepointCall;
110
3.51k
  }
111
112
83
  uint64_t getFlags() const {
113
83
    return cast<ConstantInt>(getCall()->getArgOperand(FlagsPos))
114
83
        ->getZExtValue();
115
83
  }
116
117
  /// Return the ID associated with this statepoint.
118
83
  uint64_t getID() const {
119
83
    const Value *IDVal = getCall()->getArgOperand(IDPos);
120
83
    return cast<ConstantInt>(IDVal)->getZExtValue();
121
83
  }
122
123
  /// Return the number of patchable bytes associated with this statepoint.
124
166
  uint32_t getNumPatchBytes() const {
125
166
    const Value *NumPatchBytesVal = getCall()->getArgOperand(NumPatchBytesPos);
126
166
    uint64_t NumPatchBytes =
127
166
      cast<ConstantInt>(NumPatchBytesVal)->getZExtValue();
128
166
    assert(isInt<32>(NumPatchBytes) && "should fit in 32 bits!");
129
166
    return NumPatchBytes;
130
166
  }
131
132
  /// Return the value actually being called or invoked.
133
251
  ValueTy *getCalledValue() const {
134
251
    return getCall()->getArgOperand(CalledFunctionPos);
135
251
  }
136
137
  // FIXME: Migrate users of this to `getCall` and remove it.
138
249
  InstructionTy *getInstruction() const { return getCall(); }
139
140
  /// Return the function being called if this is a direct call, otherwise
141
  /// return null (if it's an indirect call).
142
  FunTy *getCalledFunction() const {
143
    return dyn_cast<Function>(getCalledValue());
144
  }
145
146
  /// Return the caller function for this statepoint.
147
  FunTy *getCaller() const { return getCall()->getCaller(); }
148
149
  /// Determine if the statepoint cannot unwind.
150
  bool doesNotThrow() const {
151
    Function *F = getCalledFunction();
152
    return getCall()->doesNotThrow() || (F ? F->doesNotThrow() : false);
153
  }
154
155
  /// Return the type of the value returned by the call underlying the
156
  /// statepoint.
157
166
  Type *getActualReturnType() const {
158
166
    auto *FTy = cast<FunctionType>(
159
166
        cast<PointerType>(getCalledValue()->getType())->getElementType());
160
166
    return FTy->getReturnType();
161
166
  }
162
163
  /// Number of arguments to be passed to the actual callee.
164
3.97k
  int getNumCallArgs() const {
165
3.97k
    const Value *NumCallArgsVal = getCall()->getArgOperand(NumCallArgsPos);
166
3.97k
    return cast<ConstantInt>(NumCallArgsVal)->getZExtValue();
167
3.97k
  }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::getNumCallArgs() const
Line
Count
Source
164
2.72k
  int getNumCallArgs() const {
165
2.72k
    const Value *NumCallArgsVal = getCall()->getArgOperand(NumCallArgsPos);
166
2.72k
    return cast<ConstantInt>(NumCallArgsVal)->getZExtValue();
167
2.72k
  }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::getNumCallArgs() const
Line
Count
Source
164
1.24k
  int getNumCallArgs() const {
165
1.24k
    const Value *NumCallArgsVal = getCall()->getArgOperand(NumCallArgsPos);
166
1.24k
    return cast<ConstantInt>(NumCallArgsVal)->getZExtValue();
167
1.24k
  }
168
169
3.89k
  size_t arg_size() const { return getNumCallArgs(); }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::arg_size() const
Line
Count
Source
169
2.72k
  size_t arg_size() const { return getNumCallArgs(); }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::arg_size() const
Line
Count
Source
169
1.16k
  size_t arg_size() const { return getNumCallArgs(); }
170
3.89k
  arg_iterator arg_begin() const {
171
3.89k
    assert(CallArgsBeginPos <= (int)getCall()->arg_size());
172
3.89k
    return getCall()->arg_begin() + CallArgsBeginPos;
173
3.89k
  }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::arg_begin() const
Line
Count
Source
170
2.72k
  arg_iterator arg_begin() const {
171
2.72k
    assert(CallArgsBeginPos <= (int)getCall()->arg_size());
172
2.72k
    return getCall()->arg_begin() + CallArgsBeginPos;
173
2.72k
  }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::arg_begin() const
Line
Count
Source
170
1.16k
  arg_iterator arg_begin() const {
171
1.16k
    assert(CallArgsBeginPos <= (int)getCall()->arg_size());
172
1.16k
    return getCall()->arg_begin() + CallArgsBeginPos;
173
1.16k
  }
174
3.89k
  arg_iterator arg_end() const {
175
3.89k
    auto I = arg_begin() + arg_size();
176
3.89k
    assert((getCall()->arg_end() - I) >= 0);
177
3.89k
    return I;
178
3.89k
  }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::arg_end() const
Line
Count
Source
174
2.72k
  arg_iterator arg_end() const {
175
2.72k
    auto I = arg_begin() + arg_size();
176
2.72k
    assert((getCall()->arg_end() - I) >= 0);
177
2.72k
    return I;
178
2.72k
  }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::arg_end() const
Line
Count
Source
174
1.16k
  arg_iterator arg_end() const {
175
1.16k
    auto I = arg_begin() + arg_size();
176
1.16k
    assert((getCall()->arg_end() - I) >= 0);
177
1.16k
    return I;
178
1.16k
  }
179
180
  ValueTy *getArgument(unsigned Index) {
181
    assert(Index < arg_size() && "out of bounds!");
182
    return *(arg_begin() + Index);
183
  }
184
185
  /// range adapter for call arguments
186
  iterator_range<arg_iterator> call_args() const {
187
    return make_range(arg_begin(), arg_end());
188
  }
189
190
  /// Return true if the call or the callee has the given attribute.
191
  bool paramHasAttr(unsigned i, Attribute::AttrKind A) const {
192
    Function *F = getCalledFunction();
193
    return getCall()->paramHasAttr(i + CallArgsBeginPos, A) ||
194
           (F ? F->getAttributes().hasAttribute(i, A) : false);
195
  }
196
197
  /// Number of GC transition args.
198
1.94k
  int getNumTotalGCTransitionArgs() const {
199
1.94k
    const Value *NumGCTransitionArgs = *arg_end();
200
1.94k
    return cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue();
201
1.94k
  }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::getNumTotalGCTransitionArgs() const
Line
Count
Source
198
1.36k
  int getNumTotalGCTransitionArgs() const {
199
1.36k
    const Value *NumGCTransitionArgs = *arg_end();
200
1.36k
    return cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue();
201
1.36k
  }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::getNumTotalGCTransitionArgs() const
Line
Count
Source
198
581
  int getNumTotalGCTransitionArgs() const {
199
581
    const Value *NumGCTransitionArgs = *arg_end();
200
581
    return cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue();
201
581
  }
202
1.94k
  arg_iterator gc_transition_args_begin() const {
203
1.94k
    auto I = arg_end() + 1;
204
1.94k
    assert((getCall()->arg_end() - I) >= 0);
205
1.94k
    return I;
206
1.94k
  }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::gc_transition_args_begin() const
Line
Count
Source
202
1.36k
  arg_iterator gc_transition_args_begin() const {
203
1.36k
    auto I = arg_end() + 1;
204
1.36k
    assert((getCall()->arg_end() - I) >= 0);
205
1.36k
    return I;
206
1.36k
  }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::gc_transition_args_begin() const
Line
Count
Source
202
581
  arg_iterator gc_transition_args_begin() const {
203
581
    auto I = arg_end() + 1;
204
581
    assert((getCall()->arg_end() - I) >= 0);
205
581
    return I;
206
581
  }
207
1.94k
  arg_iterator gc_transition_args_end() const {
208
1.94k
    auto I = gc_transition_args_begin() + getNumTotalGCTransitionArgs();
209
1.94k
    assert((getCall()->arg_end() - I) >= 0);
210
1.94k
    return I;
211
1.94k
  }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::gc_transition_args_end() const
Line
Count
Source
207
1.36k
  arg_iterator gc_transition_args_end() const {
208
1.36k
    auto I = gc_transition_args_begin() + getNumTotalGCTransitionArgs();
209
1.36k
    assert((getCall()->arg_end() - I) >= 0);
210
1.36k
    return I;
211
1.36k
  }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::gc_transition_args_end() const
Line
Count
Source
207
581
  arg_iterator gc_transition_args_end() const {
208
581
    auto I = gc_transition_args_begin() + getNumTotalGCTransitionArgs();
209
581
    assert((getCall()->arg_end() - I) >= 0);
210
581
    return I;
211
581
  }
212
213
  /// range adapter for GC transition arguments
214
  iterator_range<arg_iterator> gc_transition_args() const {
215
    return make_range(gc_transition_args_begin(), gc_transition_args_end());
216
  }
217
218
  /// Number of additional arguments excluding those intended
219
  /// for garbage collection.
220
931
  int getNumTotalVMSArgs() const {
221
931
    const Value *NumVMSArgs = *gc_transition_args_end();
222
931
    return cast<ConstantInt>(NumVMSArgs)->getZExtValue();
223
931
  }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::getNumTotalVMSArgs() const
Line
Count
Source
220
682
  int getNumTotalVMSArgs() const {
221
682
    const Value *NumVMSArgs = *gc_transition_args_end();
222
682
    return cast<ConstantInt>(NumVMSArgs)->getZExtValue();
223
682
  }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::getNumTotalVMSArgs() const
Line
Count
Source
220
249
  int getNumTotalVMSArgs() const {
221
249
    const Value *NumVMSArgs = *gc_transition_args_end();
222
249
    return cast<ConstantInt>(NumVMSArgs)->getZExtValue();
223
249
  }
224
225
1.01k
  arg_iterator deopt_begin() const {
226
1.01k
    auto I = gc_transition_args_end() + 1;
227
1.01k
    assert((getCall()->arg_end() - I) >= 0);
228
1.01k
    return I;
229
1.01k
  }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::deopt_begin() const
Line
Count
Source
225
682
  arg_iterator deopt_begin() const {
226
682
    auto I = gc_transition_args_end() + 1;
227
682
    assert((getCall()->arg_end() - I) >= 0);
228
682
    return I;
229
682
  }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::deopt_begin() const
Line
Count
Source
225
332
  arg_iterator deopt_begin() const {
226
332
    auto I = gc_transition_args_end() + 1;
227
332
    assert((getCall()->arg_end() - I) >= 0);
228
332
    return I;
229
332
  }
230
931
  arg_iterator deopt_end() const {
231
931
    auto I = deopt_begin() + getNumTotalVMSArgs();
232
931
    assert((getCall()->arg_end() - I) >= 0);
233
931
    return I;
234
931
  }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::deopt_end() const
Line
Count
Source
230
682
  arg_iterator deopt_end() const {
231
682
    auto I = deopt_begin() + getNumTotalVMSArgs();
232
682
    assert((getCall()->arg_end() - I) >= 0);
233
682
    return I;
234
682
  }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::deopt_end() const
Line
Count
Source
230
249
  arg_iterator deopt_end() const {
231
249
    auto I = deopt_begin() + getNumTotalVMSArgs();
232
249
    assert((getCall()->arg_end() - I) >= 0);
233
249
    return I;
234
249
  }
235
236
  /// range adapter for vm state arguments
237
  iterator_range<arg_iterator> deopt_operands() const {
238
    return make_range(deopt_begin(), deopt_end());
239
  }
240
241
848
  arg_iterator gc_args_begin() const { return deopt_end(); }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::gc_args_begin() const
Line
Count
Source
241
682
  arg_iterator gc_args_begin() const { return deopt_end(); }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::gc_args_begin() const
Line
Count
Source
241
166
  arg_iterator gc_args_begin() const { return deopt_end(); }
242
490
  arg_iterator gc_args_end() const { return getCall()->arg_end(); }
llvm::StatepointBase<llvm::Function, llvm::Instruction, llvm::Value, llvm::CallBase>::gc_args_end() const
Line
Count
Source
242
324
  arg_iterator gc_args_end() const { return getCall()->arg_end(); }
llvm::StatepointBase<llvm::Function const, llvm::Instruction const, llvm::Value const, llvm::CallBase const>::gc_args_end() const
Line
Count
Source
242
166
  arg_iterator gc_args_end() const { return getCall()->arg_end(); }
243
244
358
  unsigned gcArgsStartIdx() const {
245
358
    return gc_args_begin() - getCall()->op_begin();
246
358
  }
247
248
  /// range adapter for gc arguments
249
  iterator_range<arg_iterator> gc_args() const {
250
    return make_range(gc_args_begin(), gc_args_end());
251
  }
252
253
  /// Get list of all gc reloactes linked to this statepoint
254
  /// May contain several relocations for the same base/derived pair.
255
  /// For example this could happen due to relocations on unwinding
256
  /// path of invoke.
257
  std::vector<const GCRelocateInst *> getRelocates() const;
258
259
  /// Get the experimental_gc_result call tied to this statepoint.  Can be
260
  /// nullptr if there isn't a gc_result tied to this statepoint.  Guaranteed to
261
  /// be a CallInst if non-null.
262
83
  const GCResultInst *getGCResult() const {
263
83
    for (auto *U : getInstruction()->users())
264
83
      if (auto *GRI = dyn_cast<GCResultInst>(U))
265
24
        return GRI;
266
83
    
return nullptr59
;
267
83
  }
268
269
#ifndef NDEBUG
270
  /// Asserts if this statepoint is malformed.  Common cases for failure
271
  /// include incorrect length prefixes for variable length sections or
272
  /// illegal values for parameters.
273
  void verify() {
274
    assert(getNumCallArgs() >= 0 &&
275
           "number of arguments to actually callee can't be negative");
276
277
    // The internal asserts in the iterator accessors do the rest.
278
    (void)arg_begin();
279
    (void)arg_end();
280
    (void)gc_transition_args_begin();
281
    (void)gc_transition_args_end();
282
    (void)deopt_begin();
283
    (void)deopt_end();
284
    (void)gc_args_begin();
285
    (void)gc_args_end();
286
  }
287
#endif
288
};
289
290
/// A specialization of it's base class for read only access
291
/// to a gc.statepoint.
292
class ImmutableStatepoint
293
    : public StatepointBase<const Function, const Instruction, const Value,
294
                            const CallBase> {
295
  using Base = StatepointBase<const Function, const Instruction, const Value,
296
                              const CallBase>;
297
298
public:
299
2
  explicit ImmutableStatepoint(const Instruction *I) : Base(I) {}
300
83
  explicit ImmutableStatepoint(const CallBase *Call) : Base(Call) {}
301
};
302
303
/// A specialization of it's base class for read-write access
304
/// to a gc.statepoint.
305
class Statepoint
306
    : public StatepointBase<Function, Instruction, Value, CallBase> {
307
  using Base = StatepointBase<Function, Instruction, Value, CallBase>;
308
309
public:
310
682
  explicit Statepoint(Instruction *I) : Base(I) {}
311
0
  explicit Statepoint(CallBase *Call) : Base(Call) {}
312
};
313
314
/// Common base class for representing values projected from a statepoint.
315
/// Currently, the only projections available are gc.result and gc.relocate.
316
class GCProjectionInst : public IntrinsicInst {
317
public:
318
0
  static bool classof(const IntrinsicInst *I) {
319
0
    return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate ||
320
0
      I->getIntrinsicID() == Intrinsic::experimental_gc_result;
321
0
  }
322
323
0
  static bool classof(const Value *V) {
324
0
    return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
325
0
  }
326
327
  /// Return true if this relocate is tied to the invoke statepoint.
328
  /// This includes relocates which are on the unwinding path.
329
0
  bool isTiedToInvoke() const {
330
0
    const Value *Token = getArgOperand(0);
331
0
332
0
    return isa<LandingPadInst>(Token) || isa<InvokeInst>(Token);
333
0
  }
334
335
  /// The statepoint with which this gc.relocate is associated.
336
4.36k
  const CallBase *getStatepoint() const {
337
4.36k
    const Value *Token = getArgOperand(0);
338
4.36k
339
4.36k
    // This takes care both of relocates for call statepoints and relocates
340
4.36k
    // on normal path of invoke statepoint.
341
4.36k
    if (!isa<LandingPadInst>(Token)) {
342
3.97k
      assert(isStatepoint(Token));
343
3.97k
      return cast<CallBase>(Token);
344
3.97k
    }
345
395
346
395
    // This relocate is on exceptional path of an invoke statepoint
347
395
    const BasicBlock *InvokeBB =
348
395
        cast<Instruction>(Token)->getParent()->getUniquePredecessor();
349
395
350
395
    assert(InvokeBB && "safepoints should have unique landingpads");
351
395
    assert(InvokeBB->getTerminator() &&
352
395
           "safepoint block should be well formed");
353
395
    assert(isStatepoint(InvokeBB->getTerminator()));
354
395
355
395
    return cast<CallBase>(InvokeBB->getTerminator());
356
395
  }
357
};
358
359
/// Represents calls to the gc.relocate intrinsic.
360
class GCRelocateInst : public GCProjectionInst {
361
public:
362
97.2k
  static bool classof(const IntrinsicInst *I) {
363
97.2k
    return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate;
364
97.2k
  }
365
366
4.78M
  static bool classof(const Value *V) {
367
4.78M
    return isa<IntrinsicInst>(V) && 
classof(cast<IntrinsicInst>(V))97.2k
;
368
4.78M
  }
369
370
  /// The index into the associate statepoint's argument list
371
  /// which contains the base pointer of the pointer whose
372
  /// relocation this gc.relocate describes.
373
700
  unsigned getBasePtrIndex() const {
374
700
    return cast<ConstantInt>(getArgOperand(1))->getZExtValue();
375
700
  }
376
377
  /// The index into the associate statepoint's argument list which
378
  /// contains the pointer whose relocation this gc.relocate describes.
379
2.92k
  unsigned getDerivedPtrIndex() const {
380
2.92k
    return cast<ConstantInt>(getArgOperand(2))->getZExtValue();
381
2.92k
  }
382
383
598
  Value *getBasePtr() const {
384
598
    return *(getStatepoint()->arg_begin() + getBasePtrIndex());
385
598
  }
386
387
2.83k
  Value *getDerivedPtr() const {
388
2.83k
    return *(getStatepoint()->arg_begin() + getDerivedPtrIndex());
389
2.83k
  }
390
};
391
392
/// Represents calls to the gc.result intrinsic.
393
class GCResultInst : public GCProjectionInst {
394
public:
395
3.40k
  static bool classof(const IntrinsicInst *I) {
396
3.40k
    return I->getIntrinsicID() == Intrinsic::experimental_gc_result;
397
3.40k
  }
398
399
4.27k
  static bool classof(const Value *V) {
400
4.27k
    return isa<IntrinsicInst>(V) && 
classof(cast<IntrinsicInst>(V))3.40k
;
401
4.27k
  }
402
};
403
404
template <typename FunTy, typename InstructionTy, typename ValueTy,
405
          typename CallBaseTy>
406
std::vector<const GCRelocateInst *>
407
StatepointBase<FunTy, InstructionTy, ValueTy, CallBaseTy>::getRelocates()
408
83
    const {
409
83
  std::vector<const GCRelocateInst *> Result;
410
83
411
83
  // Search for relocated pointers.  Note that working backwards from the
412
83
  // gc_relocates ensures that we only get pairs which are actually relocated
413
83
  // and used after the statepoint.
414
83
  for (const User *U : StatepointCall->users())
415
86
    if (auto *Relocate = dyn_cast<GCRelocateInst>(U))
416
62
      Result.push_back(Relocate);
417
83
418
83
  auto *StatepointInvoke = dyn_cast<InvokeInst>(StatepointCall);
419
83
  if (!StatepointInvoke)
420
75
    return Result;
421
8
422
8
  // We need to scan thorough exceptional relocations if it is invoke statepoint
423
8
  LandingPadInst *LandingPad = StatepointInvoke->getLandingPadInst();
424
8
425
8
  // Search for gc relocates that are attached to this landingpad.
426
8
  for (const User *LandingPadUser : LandingPad->users()) {
427
8
    if (auto *Relocate = dyn_cast<GCRelocateInst>(LandingPadUser))
428
8
      Result.push_back(Relocate);
429
8
  }
430
8
  return Result;
431
8
}
432
433
/// Call sites that get wrapped by a gc.statepoint (currently only in
434
/// RewriteStatepointsForGC and potentially in other passes in the future) can
435
/// have attributes that describe properties of gc.statepoint call they will be
436
/// eventually be wrapped in.  This struct is used represent such directives.
437
struct StatepointDirectives {
438
  Optional<uint32_t> NumPatchBytes;
439
  Optional<uint64_t> StatepointID;
440
441
  static const uint64_t DefaultStatepointID = 0xABCDEF00;
442
  static const uint64_t DeoptBundleStatepointID = 0xABCDEF0F;
443
};
444
445
/// Parse out statepoint directives from the function attributes present in \p
446
/// AS.
447
StatepointDirectives parseStatepointDirectivesFromAttrs(AttributeList AS);
448
449
/// Return \c true if the \p Attr is an attribute that is a statepoint
450
/// directive.
451
bool isStatepointDirectiveAttr(Attribute Attr);
452
453
} // end namespace llvm
454
455
#endif // LLVM_IR_STATEPOINT_H