Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:08

0001 //===-- llvm/OperandTraits.h - OperandTraits class definition ---*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the traits classes that are handy for enforcing the correct
0010 // layout of various User subclasses. It also provides the means for accessing
0011 // the operands in the most efficient manner.
0012 //
0013 
0014 #ifndef LLVM_IR_OPERANDTRAITS_H
0015 #define LLVM_IR_OPERANDTRAITS_H
0016 
0017 #include "llvm/IR/User.h"
0018 
0019 namespace llvm {
0020 
0021 //===----------------------------------------------------------------------===//
0022 //                          FixedNumOperand Trait Class
0023 //===----------------------------------------------------------------------===//
0024 
0025 /// FixedNumOperandTraits - determine the allocation regime of the Use array
0026 /// when it is a prefix to the User object, and the number of Use objects is
0027 /// known at compile time.
0028 
0029 template <typename SubClass, unsigned ARITY>
0030 struct FixedNumOperandTraits {
0031   static Use *op_begin(SubClass* U) {
0032     static_assert(
0033         !std::is_polymorphic<SubClass>::value,
0034         "adding virtual methods to subclasses of User breaks use lists");
0035     return reinterpret_cast<Use*>(U) - ARITY;
0036   }
0037   static Use *op_end(SubClass* U) {
0038     return reinterpret_cast<Use*>(U);
0039   }
0040   static unsigned operands(const User*) {
0041     return ARITY;
0042   }
0043 };
0044 
0045 //===----------------------------------------------------------------------===//
0046 //                          OptionalOperand Trait Class
0047 //===----------------------------------------------------------------------===//
0048 
0049 /// OptionalOperandTraits - when the number of operands may change at runtime.
0050 /// Naturally it may only decrease, because the allocations may not change.
0051 
0052 template <typename SubClass, unsigned ARITY = 1>
0053 struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> {
0054   static unsigned operands(const User *U) {
0055     return U->getNumOperands();
0056   }
0057 };
0058 
0059 //===----------------------------------------------------------------------===//
0060 //                          VariadicOperand Trait Class
0061 //===----------------------------------------------------------------------===//
0062 
0063 /// VariadicOperandTraits - determine the allocation regime of the Use array
0064 /// when it is a prefix to the User object, and the number of Use objects is
0065 /// only known at allocation time.
0066 
0067 template <typename SubClass> struct VariadicOperandTraits {
0068   static Use *op_begin(SubClass* U) {
0069     static_assert(
0070         !std::is_polymorphic<SubClass>::value,
0071         "adding virtual methods to subclasses of User breaks use lists");
0072     return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands();
0073   }
0074   static Use *op_end(SubClass* U) {
0075     return reinterpret_cast<Use*>(U);
0076   }
0077   static unsigned operands(const User *U) {
0078     return U->getNumOperands();
0079   }
0080 };
0081 
0082 //===----------------------------------------------------------------------===//
0083 //                          HungoffOperand Trait Class
0084 //===----------------------------------------------------------------------===//
0085 
0086 /// HungoffOperandTraits - determine the allocation regime of the Use array
0087 /// when it is not a prefix to the User object, but allocated at an unrelated
0088 /// heap address.
0089 ///
0090 /// This is the traits class that is needed when the Use array must be
0091 /// resizable.
0092 
0093 struct HungoffOperandTraits {
0094   static Use *op_begin(User* U) {
0095     return U->getHungOffOperands();
0096   }
0097   static Use *op_end(User* U) {
0098     return U->getHungOffOperands() + U->getNumOperands();
0099   }
0100   static unsigned operands(const User *U) {
0101     return U->getNumOperands();
0102   }
0103 };
0104 
0105 /// Macro for generating in-class operand accessor declarations.
0106 /// It should only be called in the public section of the interface.
0107 ///
0108 #define DECLARE_TRANSPARENT_OPERAND_ACCESSORS(VALUECLASS) \
0109   public: \
0110   inline VALUECLASS *getOperand(unsigned) const; \
0111   inline void setOperand(unsigned, VALUECLASS*); \
0112   inline op_iterator op_begin(); \
0113   inline const_op_iterator op_begin() const; \
0114   inline op_iterator op_end(); \
0115   inline const_op_iterator op_end() const; \
0116   protected: \
0117   template <int> inline Use &Op(); \
0118   template <int> inline const Use &Op() const; \
0119   public: \
0120   inline unsigned getNumOperands() const
0121 
0122 /// Macro for generating out-of-class operand accessor definitions
0123 #define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS) \
0124 CLASS::op_iterator CLASS::op_begin() { \
0125   return OperandTraits<CLASS>::op_begin(this); \
0126 } \
0127 CLASS::const_op_iterator CLASS::op_begin() const { \
0128   return OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this)); \
0129 } \
0130 CLASS::op_iterator CLASS::op_end() { \
0131   return OperandTraits<CLASS>::op_end(this); \
0132 } \
0133 CLASS::const_op_iterator CLASS::op_end() const { \
0134   return OperandTraits<CLASS>::op_end(const_cast<CLASS*>(this)); \
0135 } \
0136 VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \
0137   assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
0138          && "getOperand() out of range!"); \
0139   return cast_or_null<VALUECLASS>( \
0140     OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this))[i_nocapture].get()); \
0141 } \
0142 void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \
0143   assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
0144          && "setOperand() out of range!"); \
0145   OperandTraits<CLASS>::op_begin(this)[i_nocapture] = Val_nocapture; \
0146 } \
0147 unsigned CLASS::getNumOperands() const { \
0148   return OperandTraits<CLASS>::operands(this); \
0149 } \
0150 template <int Idx_nocapture> Use &CLASS::Op() { \
0151   return this->OpFrom<Idx_nocapture>(this); \
0152 } \
0153 template <int Idx_nocapture> const Use &CLASS::Op() const { \
0154   return this->OpFrom<Idx_nocapture>(this); \
0155 }
0156 
0157 
0158 } // End llvm namespace
0159 
0160 #endif