Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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/iterator_range.h"
  20. #include "llvm/IR/Attributes.h"
  21. #include "llvm/IR/Constants.h"
  22. #include "llvm/IR/Function.h"
  23. #include "llvm/IR/InstrTypes.h"
  24. #include "llvm/IR/Instructions.h"
  25. #include "llvm/IR/IntrinsicInst.h"
  26. #include "llvm/IR/Intrinsics.h"
  27. #include "llvm/Support/Casting.h"
  28. #include "llvm/Support/MathExtras.h"
  29. #include <cassert>
  30. #include <cstddef>
  31. #include <cstdint>
  32. #include <optional>
  33. #include <vector>
  34.  
  35. namespace llvm {
  36.  
  37. /// The statepoint intrinsic accepts a set of flags as its third argument.
  38. /// Valid values come out of this set.
  39. enum class StatepointFlags {
  40.   None = 0,
  41.   GCTransition = 1, ///< Indicates that this statepoint is a transition from
  42.                     ///< GC-aware code to code that is not GC-aware.
  43.   /// Mark the deopt arguments associated with the statepoint as only being
  44.   /// "live-in". By default, deopt arguments are "live-through".  "live-through"
  45.   /// requires that they the value be live on entry, on exit, and at any point
  46.   /// during the call.  "live-in" only requires the value be available at the
  47.   /// start of the call.  In particular, "live-in" values can be placed in
  48.   /// unused argument registers or other non-callee saved registers.
  49.   DeoptLiveIn = 2,
  50.  
  51.   MaskAll = 3 ///< A bitmask that includes all valid flags.
  52. };
  53.  
  54. // These two are defined in IntrinsicInst since they're part of the
  55. // IntrinsicInst class hierarchy.
  56. class GCRelocateInst;
  57.  
  58. /// Represents a gc.statepoint intrinsic call.  This extends directly from
  59. /// CallBase as the IntrinsicInst only supports calls and gc.statepoint is
  60. /// invokable.
  61. class GCStatepointInst : public CallBase {
  62. public:
  63.   GCStatepointInst() = delete;
  64.   GCStatepointInst(const GCStatepointInst &) = delete;
  65.   GCStatepointInst &operator=(const GCStatepointInst &) = delete;
  66.  
  67.   static bool classof(const CallBase *I) {
  68.     if (const Function *CF = I->getCalledFunction())
  69.       return CF->getIntrinsicID() == Intrinsic::experimental_gc_statepoint;
  70.     return false;
  71.   }
  72.  
  73.   static bool classof(const Value *V) {
  74.     return isa<CallBase>(V) && classof(cast<CallBase>(V));
  75.   }
  76.  
  77.   enum {
  78.     IDPos = 0,
  79.     NumPatchBytesPos = 1,
  80.     CalledFunctionPos = 2,
  81.     NumCallArgsPos = 3,
  82.     FlagsPos = 4,
  83.     CallArgsBeginPos = 5,
  84.   };
  85.  
  86.   /// Return the ID associated with this statepoint.
  87.   uint64_t getID() const {
  88.     return cast<ConstantInt>(getArgOperand(IDPos))->getZExtValue();
  89.   }
  90.  
  91.   /// Return the number of patchable bytes associated with this statepoint.
  92.   uint32_t getNumPatchBytes() const {
  93.     const Value *NumPatchBytesVal = getArgOperand(NumPatchBytesPos);
  94.     uint64_t NumPatchBytes =
  95.       cast<ConstantInt>(NumPatchBytesVal)->getZExtValue();
  96.     assert(isInt<32>(NumPatchBytes) && "should fit in 32 bits!");
  97.     return NumPatchBytes;
  98.   }
  99.  
  100.   /// Number of arguments to be passed to the actual callee.
  101.   int getNumCallArgs() const {
  102.     return cast<ConstantInt>(getArgOperand(NumCallArgsPos))->getZExtValue();
  103.   }
  104.  
  105.   uint64_t getFlags() const {
  106.     return cast<ConstantInt>(getArgOperand(FlagsPos))->getZExtValue();
  107.   }
  108.  
  109.   /// Return the value actually being called or invoked.
  110.   Value *getActualCalledOperand() const {
  111.     return getArgOperand(CalledFunctionPos);
  112.   }
  113.  
  114.   /// Returns the function called if this is a wrapping a direct call, and null
  115.   /// otherwise.
  116.   Function *getActualCalledFunction() const {
  117.     return dyn_cast_or_null<Function>(getActualCalledOperand());
  118.   }
  119.  
  120.   /// Return the type of the value returned by the call underlying the
  121.   /// statepoint.
  122.   Type *getActualReturnType() const {
  123.     auto *FT = cast<FunctionType>(getParamElementType(CalledFunctionPos));
  124.     return FT->getReturnType();
  125.   }
  126.  
  127.  
  128.   /// Return the number of arguments to the underlying call.
  129.   size_t actual_arg_size() const { return getNumCallArgs(); }
  130.   /// Return an iterator to the begining of the arguments to the underlying call
  131.   const_op_iterator actual_arg_begin() const {
  132.     assert(CallArgsBeginPos <= (int)arg_size());
  133.     return arg_begin() + CallArgsBeginPos;
  134.   }
  135.   /// Return an end iterator of the arguments to the underlying call
  136.   const_op_iterator actual_arg_end() const {
  137.     auto I = actual_arg_begin() + actual_arg_size();
  138.     assert((arg_end() - I) == 2);
  139.     return I;
  140.   }
  141.   /// range adapter for actual call arguments
  142.   iterator_range<const_op_iterator> actual_args() const {
  143.     return make_range(actual_arg_begin(), actual_arg_end());
  144.   }
  145.  
  146.   const_op_iterator gc_transition_args_begin() const {
  147.     if (auto Opt = getOperandBundle(LLVMContext::OB_gc_transition))
  148.       return Opt->Inputs.begin();
  149.     return arg_end();
  150.   }
  151.   const_op_iterator gc_transition_args_end() const {
  152.     if (auto Opt = getOperandBundle(LLVMContext::OB_gc_transition))
  153.       return Opt->Inputs.end();
  154.     return arg_end();
  155.   }
  156.  
  157.   /// range adapter for GC transition arguments
  158.   iterator_range<const_op_iterator> gc_transition_args() const {
  159.     return make_range(gc_transition_args_begin(), gc_transition_args_end());
  160.   }
  161.  
  162.   const_op_iterator deopt_begin() const {
  163.     if (auto Opt = getOperandBundle(LLVMContext::OB_deopt))
  164.       return Opt->Inputs.begin();
  165.     return arg_end();
  166.   }
  167.   const_op_iterator deopt_end() const {
  168.     if (auto Opt = getOperandBundle(LLVMContext::OB_deopt))
  169.       return Opt->Inputs.end();
  170.     return arg_end();
  171.   }
  172.  
  173.   /// range adapter for vm state arguments
  174.   iterator_range<const_op_iterator> deopt_operands() const {
  175.     return make_range(deopt_begin(), deopt_end());
  176.   }
  177.  
  178.   /// Returns an iterator to the begining of the argument range describing gc
  179.   /// values for the statepoint.
  180.   const_op_iterator gc_args_begin() const {
  181.     if (auto Opt = getOperandBundle(LLVMContext::OB_gc_live))
  182.       return Opt->Inputs.begin();
  183.     return arg_end();
  184.   }
  185.  
  186.   /// Return an end iterator for the gc argument range
  187.   const_op_iterator gc_args_end() const {
  188.     if (auto Opt = getOperandBundle(LLVMContext::OB_gc_live))
  189.       return Opt->Inputs.end();
  190.     return arg_end();
  191.   }
  192.  
  193.   /// range adapter for gc arguments
  194.   iterator_range<const_op_iterator> gc_args() const {
  195.     return make_range(gc_args_begin(), gc_args_end());
  196.   }
  197.  
  198.  
  199.   /// Get list of all gc reloactes linked to this statepoint
  200.   /// May contain several relocations for the same base/derived pair.
  201.   /// For example this could happen due to relocations on unwinding
  202.   /// path of invoke.
  203.   inline std::vector<const GCRelocateInst *> getGCRelocates() const;
  204. };
  205.  
  206. std::vector<const GCRelocateInst *> GCStatepointInst::getGCRelocates() const {
  207.   std::vector<const GCRelocateInst *> Result;
  208.  
  209.   // Search for relocated pointers.  Note that working backwards from the
  210.   // gc_relocates ensures that we only get pairs which are actually relocated
  211.   // and used after the statepoint.
  212.   for (const User *U : users())
  213.     if (auto *Relocate = dyn_cast<GCRelocateInst>(U))
  214.       Result.push_back(Relocate);
  215.  
  216.   auto *StatepointInvoke = dyn_cast<InvokeInst>(this);
  217.   if (!StatepointInvoke)
  218.     return Result;
  219.  
  220.   // We need to scan thorough exceptional relocations if it is invoke statepoint
  221.   LandingPadInst *LandingPad = StatepointInvoke->getLandingPadInst();
  222.  
  223.   // Search for gc relocates that are attached to this landingpad.
  224.   for (const User *LandingPadUser : LandingPad->users()) {
  225.     if (auto *Relocate = dyn_cast<GCRelocateInst>(LandingPadUser))
  226.       Result.push_back(Relocate);
  227.   }
  228.   return Result;
  229. }
  230.  
  231. /// Call sites that get wrapped by a gc.statepoint (currently only in
  232. /// RewriteStatepointsForGC and potentially in other passes in the future) can
  233. /// have attributes that describe properties of gc.statepoint call they will be
  234. /// eventually be wrapped in.  This struct is used represent such directives.
  235. struct StatepointDirectives {
  236.   std::optional<uint32_t> NumPatchBytes;
  237.   std::optional<uint64_t> StatepointID;
  238.  
  239.   static const uint64_t DefaultStatepointID = 0xABCDEF00;
  240.   static const uint64_t DeoptBundleStatepointID = 0xABCDEF0F;
  241. };
  242.  
  243. /// Parse out statepoint directives from the function attributes present in \p
  244. /// AS.
  245. StatepointDirectives parseStatepointDirectivesFromAttrs(AttributeList AS);
  246.  
  247. /// Return \c true if the \p Attr is an attribute that is a statepoint
  248. /// directive.
  249. bool isStatepointDirectiveAttr(Attribute Attr);
  250.  
  251. } // end namespace llvm
  252.  
  253. #endif // LLVM_IR_STATEPOINT_H
  254.