Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===-- llvm/OperandTraits.h - OperandTraits class definition ---*- 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 defines the traits classes that are handy for enforcing the correct
  10. // layout of various User subclasses. It also provides the means for accessing
  11. // the operands in the most efficient manner.
  12. //
  13.  
  14. #ifndef LLVM_IR_OPERANDTRAITS_H
  15. #define LLVM_IR_OPERANDTRAITS_H
  16.  
  17. #include "llvm/IR/User.h"
  18.  
  19. namespace llvm {
  20.  
  21. //===----------------------------------------------------------------------===//
  22. //                          FixedNumOperand Trait Class
  23. //===----------------------------------------------------------------------===//
  24.  
  25. /// FixedNumOperandTraits - determine the allocation regime of the Use array
  26. /// when it is a prefix to the User object, and the number of Use objects is
  27. /// known at compile time.
  28.  
  29. template <typename SubClass, unsigned ARITY>
  30. struct FixedNumOperandTraits {
  31.   static Use *op_begin(SubClass* U) {
  32.     static_assert(
  33.         !std::is_polymorphic<SubClass>::value,
  34.         "adding virtual methods to subclasses of User breaks use lists");
  35.     return reinterpret_cast<Use*>(U) - ARITY;
  36.   }
  37.   static Use *op_end(SubClass* U) {
  38.     return reinterpret_cast<Use*>(U);
  39.   }
  40.   static unsigned operands(const User*) {
  41.     return ARITY;
  42.   }
  43. };
  44.  
  45. //===----------------------------------------------------------------------===//
  46. //                          OptionalOperand Trait Class
  47. //===----------------------------------------------------------------------===//
  48.  
  49. /// OptionalOperandTraits - when the number of operands may change at runtime.
  50. /// Naturally it may only decrease, because the allocations may not change.
  51.  
  52. template <typename SubClass, unsigned ARITY = 1>
  53. struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> {
  54.   static unsigned operands(const User *U) {
  55.     return U->getNumOperands();
  56.   }
  57. };
  58.  
  59. //===----------------------------------------------------------------------===//
  60. //                          VariadicOperand Trait Class
  61. //===----------------------------------------------------------------------===//
  62.  
  63. /// VariadicOperandTraits - determine the allocation regime of the Use array
  64. /// when it is a prefix to the User object, and the number of Use objects is
  65. /// only known at allocation time.
  66.  
  67. template <typename SubClass, unsigned MINARITY = 0>
  68. struct VariadicOperandTraits {
  69.   static Use *op_begin(SubClass* U) {
  70.     static_assert(
  71.         !std::is_polymorphic<SubClass>::value,
  72.         "adding virtual methods to subclasses of User breaks use lists");
  73.     return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands();
  74.   }
  75.   static Use *op_end(SubClass* U) {
  76.     return reinterpret_cast<Use*>(U);
  77.   }
  78.   static unsigned operands(const User *U) {
  79.     return U->getNumOperands();
  80.   }
  81. };
  82.  
  83. //===----------------------------------------------------------------------===//
  84. //                          HungoffOperand Trait Class
  85. //===----------------------------------------------------------------------===//
  86.  
  87. /// HungoffOperandTraits - determine the allocation regime of the Use array
  88. /// when it is not a prefix to the User object, but allocated at an unrelated
  89. /// heap address.
  90. ///
  91. /// This is the traits class that is needed when the Use array must be
  92. /// resizable.
  93.  
  94. template <unsigned MINARITY = 1>
  95. struct HungoffOperandTraits {
  96.   static Use *op_begin(User* U) {
  97.     return U->getOperandList();
  98.   }
  99.   static Use *op_end(User* U) {
  100.     return U->getOperandList() + U->getNumOperands();
  101.   }
  102.   static unsigned operands(const User *U) {
  103.     return U->getNumOperands();
  104.   }
  105. };
  106.  
  107. /// Macro for generating in-class operand accessor declarations.
  108. /// It should only be called in the public section of the interface.
  109. ///
  110. #define DECLARE_TRANSPARENT_OPERAND_ACCESSORS(VALUECLASS) \
  111.   public: \
  112.   inline VALUECLASS *getOperand(unsigned) const; \
  113.   inline void setOperand(unsigned, VALUECLASS*); \
  114.   inline op_iterator op_begin(); \
  115.   inline const_op_iterator op_begin() const; \
  116.   inline op_iterator op_end(); \
  117.   inline const_op_iterator op_end() const; \
  118.   protected: \
  119.   template <int> inline Use &Op(); \
  120.   template <int> inline const Use &Op() const; \
  121.   public: \
  122.   inline unsigned getNumOperands() const
  123.  
  124. /// Macro for generating out-of-class operand accessor definitions
  125. #define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS) \
  126. CLASS::op_iterator CLASS::op_begin() { \
  127.   return OperandTraits<CLASS>::op_begin(this); \
  128. } \
  129. CLASS::const_op_iterator CLASS::op_begin() const { \
  130.   return OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this)); \
  131. } \
  132. CLASS::op_iterator CLASS::op_end() { \
  133.   return OperandTraits<CLASS>::op_end(this); \
  134. } \
  135. CLASS::const_op_iterator CLASS::op_end() const { \
  136.   return OperandTraits<CLASS>::op_end(const_cast<CLASS*>(this)); \
  137. } \
  138. VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \
  139.   assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
  140.          && "getOperand() out of range!"); \
  141.   return cast_or_null<VALUECLASS>( \
  142.     OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this))[i_nocapture].get()); \
  143. } \
  144. void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \
  145.   assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
  146.          && "setOperand() out of range!"); \
  147.   OperandTraits<CLASS>::op_begin(this)[i_nocapture] = Val_nocapture; \
  148. } \
  149. unsigned CLASS::getNumOperands() const { \
  150.   return OperandTraits<CLASS>::operands(this); \
  151. } \
  152. template <int Idx_nocapture> Use &CLASS::Op() { \
  153.   return this->OpFrom<Idx_nocapture>(this); \
  154. } \
  155. template <int Idx_nocapture> const Use &CLASS::Op() const { \
  156.   return this->OpFrom<Idx_nocapture>(this); \
  157. }
  158.  
  159.  
  160. } // End llvm namespace
  161.  
  162. #endif
  163.