1 //===-- llvm/IR/Statepoint.h - gc.statepoint utilities ----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains utility functions and a wrapper class analogous to
11 // CallSite for accessing the fields of gc.statepoint, gc.relocate,
12 // gc.result intrinsics; and some general utilities helpful when dealing with
15 //===----------------------------------------------------------------------===//
17 #ifndef LLVM_IR_STATEPOINT_H
18 #define LLVM_IR_STATEPOINT_H
20 #include "llvm/ADT/iterator_range.h"
21 #include "llvm/ADT/Optional.h"
22 #include "llvm/IR/Attributes.h"
23 #include "llvm/IR/BasicBlock.h"
24 #include "llvm/IR/CallSite.h"
25 #include "llvm/IR/Constants.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/IR/Instructions.h"
28 #include "llvm/IR/IntrinsicInst.h"
29 #include "llvm/IR/Intrinsics.h"
30 #include "llvm/Support/Casting.h"
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 {
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.
52 MaskAll = 3 ///< A bitmask that includes all valid flags.
58 bool isStatepoint(ImmutableCallSite CS);
59 bool isStatepoint(const Value *V);
60 bool isStatepoint(const Value &V);
62 bool isGCRelocate(ImmutableCallSite CS);
63 bool isGCResult(ImmutableCallSite CS);
65 /// Analogous to CallSiteBase, this provides most of the actual
66 /// functionality for Statepoint and ImmutableStatepoint. It is
67 /// templatized to allow easily specializing of const and non-const
68 /// concrete subtypes. This is structured analogous to CallSite
69 /// rather than the IntrinsicInst.h helpers since we need to support
70 /// invokable statepoints.
71 template <typename FunTy, typename InstructionTy, typename ValueTy,
73 class StatepointBase {
74 CallSiteTy StatepointCS;
77 explicit StatepointBase(InstructionTy *I) {
78 if (isStatepoint(I)) {
79 StatepointCS = CallSiteTy(I);
80 assert(StatepointCS && "isStatepoint implies CallSite");
84 explicit StatepointBase(CallSiteTy CS) {
90 typedef typename CallSiteTy::arg_iterator arg_iterator;
95 CalledFunctionPos = 2,
101 void *operator new(size_t, unsigned) = delete;
102 void *operator new(size_t s) = delete;
104 explicit operator bool() const {
105 // We do not assign non-statepoint CallSites to StatepointCS.
106 return (bool)StatepointCS;
109 /// Return the underlying CallSite.
110 CallSiteTy getCallSite() const {
111 assert(*this && "check validity first!");
115 uint64_t getFlags() const {
116 return cast<ConstantInt>(getCallSite().getArgument(FlagsPos))
120 /// Return the ID associated with this statepoint.
121 uint64_t getID() const {
122 const Value *IDVal = getCallSite().getArgument(IDPos);
123 return cast<ConstantInt>(IDVal)->getZExtValue();
126 /// Return the number of patchable bytes associated with this statepoint.
127 uint32_t getNumPatchBytes() const {
128 const Value *NumPatchBytesVal = getCallSite().getArgument(NumPatchBytesPos);
129 uint64_t NumPatchBytes =
130 cast<ConstantInt>(NumPatchBytesVal)->getZExtValue();
131 assert(isInt<32>(NumPatchBytes) && "should fit in 32 bits!");
132 return NumPatchBytes;
135 /// Return the value actually being called or invoked.
136 ValueTy *getCalledValue() const {
137 return getCallSite().getArgument(CalledFunctionPos);
140 InstructionTy *getInstruction() const {
141 return getCallSite().getInstruction();
144 /// Return the function being called if this is a direct call, otherwise
145 /// return null (if it's an indirect call).
146 FunTy *getCalledFunction() const {
147 return dyn_cast<Function>(getCalledValue());
150 /// Return the caller function for this statepoint.
151 FunTy *getCaller() const { return getCallSite().getCaller(); }
153 /// Determine if the statepoint cannot unwind.
154 bool doesNotThrow() const {
155 Function *F = getCalledFunction();
156 return getCallSite().doesNotThrow() || (F ? F->doesNotThrow() : false);
159 /// Return the type of the value returned by the call underlying the
161 Type *getActualReturnType() const {
162 auto *FTy = cast<FunctionType>(
163 cast<PointerType>(getCalledValue()->getType())->getElementType());
164 return FTy->getReturnType();
167 /// Number of arguments to be passed to the actual callee.
168 int getNumCallArgs() const {
169 const Value *NumCallArgsVal = getCallSite().getArgument(NumCallArgsPos);
170 return cast<ConstantInt>(NumCallArgsVal)->getZExtValue();
173 size_t arg_size() const { return getNumCallArgs(); }
174 typename CallSiteTy::arg_iterator arg_begin() const {
175 assert(CallArgsBeginPos <= (int)getCallSite().arg_size());
176 return getCallSite().arg_begin() + CallArgsBeginPos;
178 typename CallSiteTy::arg_iterator arg_end() const {
179 auto I = arg_begin() + arg_size();
180 assert((getCallSite().arg_end() - I) >= 0);
184 ValueTy *getArgument(unsigned Index) {
185 assert(Index < arg_size() && "out of bounds!");
186 return *(arg_begin() + Index);
189 /// range adapter for call arguments
190 iterator_range<arg_iterator> call_args() const {
191 return make_range(arg_begin(), arg_end());
194 /// \brief Return true if the call or the callee has the given attribute.
195 bool paramHasAttr(unsigned i, Attribute::AttrKind A) const {
196 Function *F = getCalledFunction();
197 return getCallSite().paramHasAttr(i + CallArgsBeginPos, A) ||
198 (F ? F->getAttributes().hasAttribute(i, A) : false);
201 /// Number of GC transition args.
202 int getNumTotalGCTransitionArgs() const {
203 const Value *NumGCTransitionArgs = *arg_end();
204 return cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue();
206 typename CallSiteTy::arg_iterator gc_transition_args_begin() const {
207 auto I = arg_end() + 1;
208 assert((getCallSite().arg_end() - I) >= 0);
211 typename CallSiteTy::arg_iterator gc_transition_args_end() const {
212 auto I = gc_transition_args_begin() + getNumTotalGCTransitionArgs();
213 assert((getCallSite().arg_end() - I) >= 0);
217 /// range adapter for GC transition arguments
218 iterator_range<arg_iterator> gc_transition_args() const {
219 return make_range(gc_transition_args_begin(), gc_transition_args_end());
222 /// Number of additional arguments excluding those intended
223 /// for garbage collection.
224 int getNumTotalVMSArgs() const {
225 const Value *NumVMSArgs = *gc_transition_args_end();
226 return cast<ConstantInt>(NumVMSArgs)->getZExtValue();
229 typename CallSiteTy::arg_iterator vm_state_begin() const {
230 auto I = gc_transition_args_end() + 1;
231 assert((getCallSite().arg_end() - I) >= 0);
234 typename CallSiteTy::arg_iterator vm_state_end() const {
235 auto I = vm_state_begin() + getNumTotalVMSArgs();
236 assert((getCallSite().arg_end() - I) >= 0);
240 /// range adapter for vm state arguments
241 iterator_range<arg_iterator> vm_state_args() const {
242 return make_range(vm_state_begin(), vm_state_end());
245 typename CallSiteTy::arg_iterator gc_args_begin() const {
246 return vm_state_end();
248 typename CallSiteTy::arg_iterator gc_args_end() const {
249 return getCallSite().arg_end();
252 unsigned gcArgsStartIdx() const {
253 return gc_args_begin() - getInstruction()->op_begin();
256 /// range adapter for gc arguments
257 iterator_range<arg_iterator> gc_args() const {
258 return make_range(gc_args_begin(), gc_args_end());
261 /// Get list of all gc reloactes linked to this statepoint
262 /// May contain several relocations for the same base/derived pair.
263 /// For example this could happen due to relocations on unwinding
265 std::vector<const GCRelocateInst *> getRelocates() const;
267 /// Get the experimental_gc_result call tied to this statepoint. Can be
268 /// nullptr if there isn't a gc_result tied to this statepoint. Guaranteed to
269 /// be a CallInst if non-null.
270 const GCResultInst *getGCResult() const {
271 for (auto *U : getInstruction()->users())
272 if (auto *GRI = dyn_cast<GCResultInst>(U))
278 /// Asserts if this statepoint is malformed. Common cases for failure
279 /// include incorrect length prefixes for variable length sections or
280 /// illegal values for parameters.
282 assert(getNumCallArgs() >= 0 &&
283 "number of arguments to actually callee can't be negative");
285 // The internal asserts in the iterator accessors do the rest.
288 (void)gc_transition_args_begin();
289 (void)gc_transition_args_end();
290 (void)vm_state_begin();
291 (void)vm_state_end();
292 (void)gc_args_begin();
298 /// A specialization of it's base class for read only access
299 /// to a gc.statepoint.
300 class ImmutableStatepoint
301 : public StatepointBase<const Function, const Instruction, const Value,
303 typedef StatepointBase<const Function, const Instruction, const Value,
304 ImmutableCallSite> Base;
307 explicit ImmutableStatepoint(const Instruction *I) : Base(I) {}
308 explicit ImmutableStatepoint(ImmutableCallSite CS) : Base(CS) {}
311 /// A specialization of it's base class for read-write access
312 /// to a gc.statepoint.
314 : public StatepointBase<Function, Instruction, Value, CallSite> {
315 typedef StatepointBase<Function, Instruction, Value, CallSite> Base;
318 explicit Statepoint(Instruction *I) : Base(I) {}
319 explicit Statepoint(CallSite CS) : Base(CS) {}
322 /// Common base class for representing values projected from a statepoint.
323 /// Currently, the only projections available are gc.result and gc.relocate.
324 class GCProjectionInst : public IntrinsicInst {
326 static inline bool classof(const IntrinsicInst *I) {
327 return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate ||
328 I->getIntrinsicID() == Intrinsic::experimental_gc_result;
330 static inline bool classof(const Value *V) {
331 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
334 /// Return true if this relocate is tied to the invoke statepoint.
335 /// This includes relocates which are on the unwinding path.
336 bool isTiedToInvoke() const {
337 const Value *Token = getArgOperand(0);
339 return isa<LandingPadInst>(Token) || isa<InvokeInst>(Token);
342 /// The statepoint with which this gc.relocate is associated.
343 const Instruction *getStatepoint() const {
344 const Value *Token = getArgOperand(0);
346 // This takes care both of relocates for call statepoints and relocates
347 // on normal path of invoke statepoint.
348 if (!isa<LandingPadInst>(Token)) {
349 assert(isStatepoint(Token));
350 return cast<Instruction>(Token);
353 // This relocate is on exceptional path of an invoke statepoint
354 const BasicBlock *InvokeBB =
355 cast<Instruction>(Token)->getParent()->getUniquePredecessor();
357 assert(InvokeBB && "safepoints should have unique landingpads");
358 assert(InvokeBB->getTerminator() &&
359 "safepoint block should be well formed");
360 assert(isStatepoint(InvokeBB->getTerminator()));
362 return InvokeBB->getTerminator();
366 /// Represents calls to the gc.relocate intrinsic.
367 class GCRelocateInst : public GCProjectionInst {
369 static inline bool classof(const IntrinsicInst *I) {
370 return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate;
372 static inline bool classof(const Value *V) {
373 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
376 /// The index into the associate statepoint's argument list
377 /// which contains the base pointer of the pointer whose
378 /// relocation this gc.relocate describes.
379 unsigned getBasePtrIndex() const {
380 return cast<ConstantInt>(getArgOperand(1))->getZExtValue();
383 /// The index into the associate statepoint's argument list which
384 /// contains the pointer whose relocation this gc.relocate describes.
385 unsigned getDerivedPtrIndex() const {
386 return cast<ConstantInt>(getArgOperand(2))->getZExtValue();
389 Value *getBasePtr() const {
390 ImmutableCallSite CS(getStatepoint());
391 return *(CS.arg_begin() + getBasePtrIndex());
394 Value *getDerivedPtr() const {
395 ImmutableCallSite CS(getStatepoint());
396 return *(CS.arg_begin() + getDerivedPtrIndex());
400 /// Represents calls to the gc.result intrinsic.
401 class GCResultInst : public GCProjectionInst {
403 static inline bool classof(const IntrinsicInst *I) {
404 return I->getIntrinsicID() == Intrinsic::experimental_gc_result;
406 static inline bool classof(const Value *V) {
407 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
411 template <typename FunTy, typename InstructionTy, typename ValueTy,
413 std::vector<const GCRelocateInst *>
414 StatepointBase<FunTy, InstructionTy, ValueTy, CallSiteTy>::getRelocates()
417 std::vector<const GCRelocateInst *> Result;
419 CallSiteTy StatepointCS = getCallSite();
421 // Search for relocated pointers. Note that working backwards from the
422 // gc_relocates ensures that we only get pairs which are actually relocated
423 // and used after the statepoint.
424 for (const User *U : getInstruction()->users())
425 if (auto *Relocate = dyn_cast<GCRelocateInst>(U))
426 Result.push_back(Relocate);
428 if (!StatepointCS.isInvoke())
431 // We need to scan thorough exceptional relocations if it is invoke statepoint
432 LandingPadInst *LandingPad =
433 cast<InvokeInst>(getInstruction())->getLandingPadInst();
435 // Search for gc relocates that are attached to this landingpad.
436 for (const User *LandingPadUser : LandingPad->users()) {
437 if (auto *Relocate = dyn_cast<GCRelocateInst>(LandingPadUser))
438 Result.push_back(Relocate);
443 /// Call sites that get wrapped by a gc.statepoint (currently only in
444 /// RewriteStatepointsForGC and potentially in other passes in the future) can
445 /// have attributes that describe properties of gc.statepoint call they will be
446 /// eventually be wrapped in. This struct is used represent such directives.
447 struct StatepointDirectives {
448 Optional<uint32_t> NumPatchBytes;
449 Optional<uint64_t> StatepointID;
451 static const uint64_t DefaultStatepointID = 0xABCDEF00;
452 static const uint64_t DeoptBundleStatepointID = 0xABCDEF0F;
455 /// Parse out statepoint directives from the function attributes present in \p
457 StatepointDirectives parseStatepointDirectivesFromAttrs(AttributeSet AS);
459 /// Return \c true if the the \p Attr is an attribute that is a statepoint
461 bool isStatepointDirectiveAttr(Attribute Attr);
463 } // end namespace llvm
465 #endif // LLVM_IR_STATEPOINT_H