MLIR  15.0.0git
Attributes.h
Go to the documentation of this file.
1 //===- Attributes.h - MLIR Attribute Classes --------------------*- 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 #ifndef MLIR_IR_ATTRIBUTES_H
10 #define MLIR_IR_ATTRIBUTES_H
11 
13 #include "llvm/Support/PointerLikeTypeTraits.h"
14 
15 namespace mlir {
16 class StringAttr;
17 
18 /// Attributes are known-constant values of operations.
19 ///
20 /// Instances of the Attribute class are references to immortal key-value pairs
21 /// with immutable, uniqued keys owned by MLIRContext. As such, an Attribute is
22 /// a thin wrapper around an underlying storage pointer. Attributes are usually
23 /// passed by value.
24 class Attribute {
25 public:
26  /// Utility class for implementing attributes.
27  template <typename ConcreteType, typename BaseType, typename StorageType,
28  template <typename T> class... Traits>
29  using AttrBase = detail::StorageUserBase<ConcreteType, BaseType, StorageType,
31 
33  using ValueType = void;
35 
36  constexpr Attribute() {}
37  /* implicit */ Attribute(const ImplType *impl)
38  : impl(const_cast<ImplType *>(impl)) {}
39 
40  Attribute(const Attribute &other) = default;
41  Attribute &operator=(const Attribute &other) = default;
42 
43  bool operator==(Attribute other) const { return impl == other.impl; }
44  bool operator!=(Attribute other) const { return !(*this == other); }
45  explicit operator bool() const { return impl; }
46 
47  bool operator!() const { return impl == nullptr; }
48 
49  template <typename U> bool isa() const;
50  template <typename First, typename Second, typename... Rest>
51  bool isa() const;
52  template <typename First, typename... Rest>
53  bool isa_and_nonnull() const;
54  template <typename U> U dyn_cast() const;
55  template <typename U> U dyn_cast_or_null() const;
56  template <typename U> U cast() const;
57 
58  // Support dyn_cast'ing Attribute to itself.
59  static bool classof(Attribute) { return true; }
60 
61  /// Return a unique identifier for the concrete attribute type. This is used
62  /// to support dynamic type casting.
63  TypeID getTypeID() { return impl->getAbstractAttribute().getTypeID(); }
64 
65  /// Return the type of this attribute.
66  Type getType() const { return impl->getType(); }
67 
68  /// Return the context this attribute belongs to.
69  MLIRContext *getContext() const;
70 
71  /// Get the dialect this attribute is registered to.
72  Dialect &getDialect() const {
73  return impl->getAbstractAttribute().getDialect();
74  }
75 
76  /// Print the attribute.
77  void print(raw_ostream &os) const;
78  void dump() const;
79 
80  /// Get an opaque pointer to the attribute.
81  const void *getAsOpaquePointer() const { return impl; }
82  /// Construct an attribute from the opaque pointer representation.
83  static Attribute getFromOpaquePointer(const void *ptr) {
84  return Attribute(reinterpret_cast<const ImplType *>(ptr));
85  }
86 
87  friend ::llvm::hash_code hash_value(Attribute arg);
88 
89  /// Returns true if the type was registered with a particular trait.
90  template <template <typename T> class Trait>
91  bool hasTrait() {
92  return getAbstractAttribute().hasTrait<Trait>();
93  }
94 
95  /// Return the abstract descriptor for this attribute.
97  return impl->getAbstractAttribute();
98  }
99 
100 protected:
101  ImplType *impl{nullptr};
102 };
103 
104 inline raw_ostream &operator<<(raw_ostream &os, Attribute attr) {
105  attr.print(os);
106  return os;
107 }
108 
109 template <typename U> bool Attribute::isa() const {
110  assert(impl && "isa<> used on a null attribute.");
111  return U::classof(*this);
112 }
113 
114 template <typename First, typename Second, typename... Rest>
115 bool Attribute::isa() const {
116  return isa<First>() || isa<Second, Rest...>();
117 }
118 
119 template <typename First, typename... Rest>
121  return impl && isa<First, Rest...>();
122 }
123 
124 template <typename U> U Attribute::dyn_cast() const {
125  return isa<U>() ? U(impl) : U(nullptr);
126 }
127 template <typename U> U Attribute::dyn_cast_or_null() const {
128  return (impl && isa<U>()) ? U(impl) : U(nullptr);
129 }
130 template <typename U> U Attribute::cast() const {
131  assert(isa<U>());
132  return U(impl);
133 }
134 
135 inline ::llvm::hash_code hash_value(Attribute arg) {
137 }
138 
139 //===----------------------------------------------------------------------===//
140 // NamedAttribute
141 //===----------------------------------------------------------------------===//
142 
143 /// NamedAttribute represents a combination of a name and an Attribute value.
145 public:
146  NamedAttribute(StringAttr name, Attribute value);
147 
148  /// Return the name of the attribute.
149  StringAttr getName() const;
150 
151  /// Return the dialect of the name of this attribute, if the name is prefixed
152  /// by a dialect namespace. For example, `llvm.fast_math` would return the
153  /// LLVM dialect (if it is loaded). Returns nullptr if the dialect isn't
154  /// loaded, or if the name is not prefixed by a dialect namespace.
155  Dialect *getNameDialect() const;
156 
157  /// Return the value of the attribute.
158  Attribute getValue() const { return value; }
159 
160  /// Set the name of this attribute.
161  void setName(StringAttr newName);
162 
163  /// Set the value of this attribute.
164  void setValue(Attribute newValue) {
165  assert(value && "expected valid attribute value");
166  value = newValue;
167  }
168 
169  /// Compare this attribute to the provided attribute, ordering by name.
170  bool operator<(const NamedAttribute &rhs) const;
171  /// Compare this attribute to the provided string, ordering by name.
172  bool operator<(StringRef rhs) const;
173 
174  bool operator==(const NamedAttribute &rhs) const {
175  return name == rhs.name && value == rhs.value;
176  }
177  bool operator!=(const NamedAttribute &rhs) const { return !(*this == rhs); }
178 
179 private:
180  NamedAttribute(Attribute name, Attribute value) : name(name), value(value) {}
181 
182  /// Allow access to internals to enable hashing.
183  friend ::llvm::hash_code hash_value(const NamedAttribute &arg);
185 
186  /// The name of the attribute. This is represented as a StringAttr, but
187  /// type-erased to Attribute in the field.
188  Attribute name;
189  /// The value of the attribute.
191 };
192 
193 inline ::llvm::hash_code hash_value(const NamedAttribute &arg) {
194  using AttrPairT = std::pair<Attribute, Attribute>;
195  return DenseMapInfo<AttrPairT>::getHashValue(AttrPairT(arg.name, arg.value));
196 }
197 
198 //===----------------------------------------------------------------------===//
199 // AttributeTraitBase
200 //===----------------------------------------------------------------------===//
201 
202 namespace AttributeTrait {
203 /// This class represents the base of an attribute trait.
204 template <typename ConcreteType, template <typename> class TraitType>
206 } // namespace AttributeTrait
207 
208 //===----------------------------------------------------------------------===//
209 // AttributeInterface
210 //===----------------------------------------------------------------------===//
211 
212 /// This class represents the base of an attribute interface. See the definition
213 /// of `detail::Interface` for requirements on the `Traits` type.
214 template <typename ConcreteType, typename Traits>
216  : public detail::Interface<ConcreteType, Attribute, Traits, Attribute,
217  AttributeTrait::TraitBase> {
218 public:
220  using InterfaceBase = detail::Interface<ConcreteType, Attribute, Traits,
223 
224 private:
225  /// Returns the impl interface instance for the given type.
226  static typename InterfaceBase::Concept *getInterfaceFor(Attribute attr) {
227  return attr.getAbstractAttribute().getInterface<ConcreteType>();
228  }
229 
230  /// Allow access to 'getInterfaceFor'.
231  friend InterfaceBase;
232 };
233 
234 //===----------------------------------------------------------------------===//
235 // Core AttributeTrait
236 //===----------------------------------------------------------------------===//
237 
238 /// This trait is used to determine if an attribute is mutable or not. It is
239 /// attached on an attribute if the corresponding ImplType defines a `mutate`
240 /// function with proper signature.
241 namespace AttributeTrait {
242 template <typename ConcreteType>
244 } // namespace AttributeTrait
245 
246 } // namespace mlir.
247 
248 namespace llvm {
249 
250 // Attribute hash just like pointers.
251 template <> struct DenseMapInfo<mlir::Attribute> {
253  auto *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
254  return mlir::Attribute(static_cast<mlir::Attribute::ImplType *>(pointer));
255  }
258  return mlir::Attribute(static_cast<mlir::Attribute::ImplType *>(pointer));
259  }
260  static unsigned getHashValue(mlir::Attribute val) {
261  return mlir::hash_value(val);
262  }
263  static bool isEqual(mlir::Attribute LHS, mlir::Attribute RHS) {
264  return LHS == RHS;
265  }
266 };
267 template <typename T>
269  T, std::enable_if_t<std::is_base_of<mlir::Attribute, T>::value>>
270  : public DenseMapInfo<mlir::Attribute> {
271  static T getEmptyKey() {
272  const void *pointer = llvm::DenseMapInfo<const void *>::getEmptyKey();
273  return T::getFromOpaquePointer(pointer);
274  }
275  static T getTombstoneKey() {
277  return T::getFromOpaquePointer(pointer);
278  }
279 };
280 
281 /// Allow LLVM to steal the low bits of Attributes.
282 template <> struct PointerLikeTypeTraits<mlir::Attribute> {
283  static inline void *getAsVoidPointer(mlir::Attribute attr) {
284  return const_cast<void *>(attr.getAsOpaquePointer());
285  }
286  static inline mlir::Attribute getFromVoidPointer(void *ptr) {
288  }
289  static constexpr int NumLowBitsAvailable = llvm::PointerLikeTypeTraits<
290  mlir::AttributeStorage *>::NumLowBitsAvailable;
291 };
292 
293 template <> struct DenseMapInfo<mlir::NamedAttribute> {
296  return mlir::NamedAttribute(emptyAttr, emptyAttr);
297  }
300  return mlir::NamedAttribute(tombAttr, tombAttr);
301  }
302  static unsigned getHashValue(mlir::NamedAttribute val) {
303  return mlir::hash_value(val);
304  }
306  return lhs == rhs;
307  }
308 };
309 
310 } // namespace llvm
311 
312 #endif
TODO: Remove this file when SCCP and integer range analysis have been ported to the new framework...
static bool isEqual(mlir::NamedAttribute lhs, mlir::NamedAttribute rhs)
Definition: Attributes.h:305
bool operator<(Fraction x, Fraction y)
Definition: Fraction.h:69
static void * getAsVoidPointer(mlir::Attribute attr)
Definition: Attributes.h:283
This class represents the base of an attribute interface.
Definition: Attributes.h:215
U cast() const
Definition: Attributes.h:130
U dyn_cast_or_null() const
Definition: Attributes.h:127
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:221
Attribute getValue() const
Return the value of the attribute.
Definition: Attributes.h:158
const void * getAsOpaquePointer() const
Get an opaque pointer to the attribute.
Definition: Attributes.h:81
T::Concept * getInterface() const
Returns an instance of the concept object for the given interface if it was registered to this attrib...
static bool classof(Attribute)
Definition: Attributes.h:59
bool isa() const
Definition: Attributes.h:109
bool isa_and_nonnull() const
Definition: Attributes.h:120
This class represents an abstract interface.
bool operator!=(const NamedAttribute &rhs) const
Definition: Attributes.h:177
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
Definition: AliasAnalysis.h:78
static constexpr const bool value
bool hasTrait() const
Returns true if the attribute has a particular trait.
This class provides an efficient unique identifier for a specific C++ type.
Definition: TypeID.h:104
NamedAttribute represents a combination of a name and an Attribute value.
Definition: Attributes.h:144
static mlir::Attribute getTombstoneKey()
Definition: Attributes.h:256
constexpr Attribute()
Definition: Attributes.h:36
static mlir::NamedAttribute getEmptyKey()
Definition: Attributes.h:294
Dialect & getDialect() const
Get the dialect this attribute is registered to.
Definition: Attributes.h:72
void dump() const
MLIRContext * getContext() const
Return the context this attribute belongs to.
Definition: Attributes.cpp:20
friend ::llvm::hash_code hash_value(Attribute arg)
Definition: Attributes.h:135
Attributes are known-constant values of operations.
Definition: Attributes.h:24
Attribute(const ImplType *impl)
Definition: Attributes.h:37
This trait is used to determine if a storage user, like Type, is mutable or not.
bool operator==(const NamedAttribute &rhs) const
Definition: Attributes.h:174
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:41
bool operator==(Attribute other) const
Definition: Attributes.h:43
void print(raw_ostream &os) const
Print the attribute.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
void setValue(Attribute newValue)
Set the value of this attribute.
Definition: Attributes.h:164
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:240
static mlir::Attribute getEmptyKey()
Definition: Attributes.h:252
Type getType() const
Return the type of this attribute.
Definition: Attributes.h:66
bool operator!=(Attribute other) const
Definition: Attributes.h:44
bool operator!() const
Definition: Attributes.h:47
U dyn_cast() const
Definition: Attributes.h:124
Utility class for implementing users of storage classes uniqued by a StorageUniquer.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:55
static bool isEqual(mlir::Attribute LHS, mlir::Attribute RHS)
Definition: Attributes.h:263
Base storage class appearing in an attribute.
ImplType * impl
Definition: Attributes.h:101
const AbstractTy & getAbstractAttribute() const
Return the abstract descriptor for this attribute.
Definition: Attributes.h:96
static unsigned getHashValue(mlir::Attribute val)
Definition: Attributes.h:260
static unsigned getHashValue(mlir::NamedAttribute val)
Definition: Attributes.h:302
Helper class for implementing traits for storage classes.
static mlir::NamedAttribute getTombstoneKey()
Definition: Attributes.h:298
TypeID getTypeID()
Return a unique identifier for the concrete attribute type.
Definition: Attributes.h:63
This class contains all of the static information common to all instances of a registered Attribute...
static mlir::Attribute getFromVoidPointer(void *ptr)
Definition: Attributes.h:286
static Attribute getFromOpaquePointer(const void *ptr)
Construct an attribute from the opaque pointer representation.
Definition: Attributes.h:83
Attribute & operator=(const Attribute &other)=default
bool hasTrait()
Returns true if the type was registered with a particular trait.
Definition: Attributes.h:91