Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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