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