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, 12 // gc.result intrinsics; and some general utilities helpful when dealing with 13 // gc.statepoint. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_IR_STATEPOINT_H 18 #define LLVM_IR_STATEPOINT_H 19 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" 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(ImmutableCallSite CS); 59 bool isStatepoint(const Value *V); 60 bool isStatepoint(const Value &V); 61 62 bool isGCRelocate(ImmutableCallSite CS); 63 bool isGCResult(ImmutableCallSite CS); 64 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, 72 typename CallSiteTy> 73 class StatepointBase { 74 CallSiteTy StatepointCS; 75 76 protected: 77 explicit StatepointBase(InstructionTy *I) { 78 if (isStatepoint(I)) { 79 StatepointCS = CallSiteTy(I); 80 assert(StatepointCS && "isStatepoint implies CallSite"); 81 } 82 } 83 84 explicit StatepointBase(CallSiteTy CS) { 85 if (isStatepoint(CS)) 86 StatepointCS = CS; 87 } 88 89 public: 90 typedef typename CallSiteTy::arg_iterator arg_iterator; 91 92 enum { 93 IDPos = 0, 94 NumPatchBytesPos = 1, 95 CalledFunctionPos = 2, 96 NumCallArgsPos = 3, 97 FlagsPos = 4, 98 CallArgsBeginPos = 5, 99 }; 100 101 void *operator new(size_t, unsigned) = delete; 102 void *operator new(size_t s) = delete; 103 104 explicit operator bool() const { 105 // We do not assign non-statepoint CallSites to StatepointCS. 106 return (bool)StatepointCS; 107 } 108 109 /// Return the underlying CallSite. 110 CallSiteTy getCallSite() const { 111 assert(*this && "check validity first!"); 112 return StatepointCS; 113 } 114 115 uint64_t getFlags() const { 116 return cast<ConstantInt>(getCallSite().getArgument(FlagsPos)) 117 ->getZExtValue(); 118 } 119 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(); 124 } 125 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; 133 } 134 135 /// Return the value actually being called or invoked. 136 ValueTy *getCalledValue() const { 137 return getCallSite().getArgument(CalledFunctionPos); 138 } 139 140 InstructionTy *getInstruction() const { 141 return getCallSite().getInstruction(); 142 } 143 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()); 148 } 149 150 /// Return the caller function for this statepoint. 151 FunTy *getCaller() const { return getCallSite().getCaller(); } 152 153 /// Determine if the statepoint cannot unwind. 154 bool doesNotThrow() const { 155 Function *F = getCalledFunction(); 156 return getCallSite().doesNotThrow() || (F ? F->doesNotThrow() : false); 157 } 158 159 /// Return the type of the value returned by the call underlying the 160 /// statepoint. 161 Type *getActualReturnType() const { 162 auto *FTy = cast<FunctionType>( 163 cast<PointerType>(getCalledValue()->getType())->getElementType()); 164 return FTy->getReturnType(); 165 } 166 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(); 171 } 172 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; 177 } 178 typename CallSiteTy::arg_iterator arg_end() const { 179 auto I = arg_begin() + arg_size(); 180 assert((getCallSite().arg_end() - I) >= 0); 181 return I; 182 } 183 184 ValueTy *getArgument(unsigned Index) { 185 assert(Index < arg_size() && "out of bounds!"); 186 return *(arg_begin() + Index); 187 } 188 189 /// range adapter for call arguments 190 iterator_range<arg_iterator> call_args() const { 191 return make_range(arg_begin(), arg_end()); 192 } 193 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); 199 } 200 201 /// Number of GC transition args. 202 int getNumTotalGCTransitionArgs() const { 203 const Value *NumGCTransitionArgs = *arg_end(); 204 return cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue(); 205 } 206 typename CallSiteTy::arg_iterator gc_transition_args_begin() const { 207 auto I = arg_end() + 1; 208 assert((getCallSite().arg_end() - I) >= 0); 209 return I; 210 } 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); 214 return I; 215 } 216 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()); 220 } 221 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(); 227 } 228 229 typename CallSiteTy::arg_iterator vm_state_begin() const { 230 auto I = gc_transition_args_end() + 1; 231 assert((getCallSite().arg_end() - I) >= 0); 232 return I; 233 } 234 typename CallSiteTy::arg_iterator vm_state_end() const { 235 auto I = vm_state_begin() + getNumTotalVMSArgs(); 236 assert((getCallSite().arg_end() - I) >= 0); 237 return I; 238 } 239 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()); 243 } 244 245 typename CallSiteTy::arg_iterator gc_args_begin() const { 246 return vm_state_end(); 247 } 248 typename CallSiteTy::arg_iterator gc_args_end() const { 249 return getCallSite().arg_end(); 250 } 251 252 unsigned gcArgsStartIdx() const { 253 return gc_args_begin() - getInstruction()->op_begin(); 254 } 255 256 /// range adapter for gc arguments 257 iterator_range<arg_iterator> gc_args() const { 258 return make_range(gc_args_begin(), gc_args_end()); 259 } 260 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 264 /// path of invoke. 265 std::vector<const GCRelocateInst *> getRelocates() const; 266 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)) 273 return GRI; 274 return nullptr; 275 } 276 277 #ifndef NDEBUG 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. 281 void verify() { 282 assert(getNumCallArgs() >= 0 && 283 "number of arguments to actually callee can't be negative"); 284 285 // The internal asserts in the iterator accessors do the rest. 286 (void)arg_begin(); 287 (void)arg_end(); 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(); 293 (void)gc_args_end(); 294 } 295 #endif 296 }; 297 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, 302 ImmutableCallSite> { 303 typedef StatepointBase<const Function, const Instruction, const Value, 304 ImmutableCallSite> Base; 305 306 public: 307 explicit ImmutableStatepoint(const Instruction *I) : Base(I) {} 308 explicit ImmutableStatepoint(ImmutableCallSite CS) : Base(CS) {} 309 }; 310 311 /// A specialization of it's base class for read-write access 312 /// to a gc.statepoint. 313 class Statepoint 314 : public StatepointBase<Function, Instruction, Value, CallSite> { 315 typedef StatepointBase<Function, Instruction, Value, CallSite> Base; 316 317 public: 318 explicit Statepoint(Instruction *I) : Base(I) {} 319 explicit Statepoint(CallSite CS) : Base(CS) {} 320 }; 321 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 { 325 public: 326 static inline bool classof(const IntrinsicInst *I) { 327 return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate || 328 I->getIntrinsicID() == Intrinsic::experimental_gc_result; 329 } 330 static inline bool classof(const Value *V) { 331 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 332 } 333 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); 338 339 return isa<LandingPadInst>(Token) || isa<InvokeInst>(Token); 340 } 341 342 /// The statepoint with which this gc.relocate is associated. 343 const Instruction *getStatepoint() const { 344 const Value *Token = getArgOperand(0); 345 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); 351 } 352 353 // This relocate is on exceptional path of an invoke statepoint 354 const BasicBlock *InvokeBB = 355 cast<Instruction>(Token)->getParent()->getUniquePredecessor(); 356 357 assert(InvokeBB && "safepoints should have unique landingpads"); 358 assert(InvokeBB->getTerminator() && 359 "safepoint block should be well formed"); 360 assert(isStatepoint(InvokeBB->getTerminator())); 361 362 return InvokeBB->getTerminator(); 363 } 364 }; 365 366 /// Represents calls to the gc.relocate intrinsic. 367 class GCRelocateInst : public GCProjectionInst { 368 public: 369 static inline bool classof(const IntrinsicInst *I) { 370 return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate; 371 } 372 static inline bool classof(const Value *V) { 373 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 374 } 375 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(); 381 } 382 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(); 387 } 388 389 Value *getBasePtr() const { 390 ImmutableCallSite CS(getStatepoint()); 391 return *(CS.arg_begin() + getBasePtrIndex()); 392 } 393 394 Value *getDerivedPtr() const { 395 ImmutableCallSite CS(getStatepoint()); 396 return *(CS.arg_begin() + getDerivedPtrIndex()); 397 } 398 }; 399 400 /// Represents calls to the gc.result intrinsic. 401 class GCResultInst : public GCProjectionInst { 402 public: 403 static inline bool classof(const IntrinsicInst *I) { 404 return I->getIntrinsicID() == Intrinsic::experimental_gc_result; 405 } 406 static inline bool classof(const Value *V) { 407 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 408 } 409 }; 410 411 template <typename FunTy, typename InstructionTy, typename ValueTy, 412 typename CallSiteTy> 413 std::vector<const GCRelocateInst *> 414 StatepointBase<FunTy, InstructionTy, ValueTy, CallSiteTy>::getRelocates() 415 const { 416 417 std::vector<const GCRelocateInst *> Result; 418 419 CallSiteTy StatepointCS = getCallSite(); 420 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); 427 428 if (!StatepointCS.isInvoke()) 429 return Result; 430 431 // We need to scan thorough exceptional relocations if it is invoke statepoint 432 LandingPadInst *LandingPad = 433 cast<InvokeInst>(getInstruction())->getLandingPadInst(); 434 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); 439 } 440 return Result; 441 } 442 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; 450 451 static const uint64_t DefaultStatepointID = 0xABCDEF00; 452 static const uint64_t DeoptBundleStatepointID = 0xABCDEF0F; 453 }; 454 455 /// Parse out statepoint directives from the function attributes present in \p 456 /// AS. 457 StatepointDirectives parseStatepointDirectivesFromAttrs(AttributeList AS); 458 459 /// Return \c true if the the \p Attr is an attribute that is a statepoint 460 /// directive. 461 bool isStatepointDirectiveAttr(Attribute Attr); 462 463 } // end namespace llvm 464 465 #endif // LLVM_IR_STATEPOINT_H 466