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->getHungOffOperands(); 98 } 99 static Use *op_end(User* U) { 100 return U->getHungOffOperands() + 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