MLIR  14.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 U> U dyn_cast() const;
53  template <typename U> U dyn_cast_or_null() const;
54  template <typename U> U cast() const;
55 
56  // Support dyn_cast'ing Attribute to itself.
57  static bool classof(Attribute) { return true; }
58 
59  /// Return a unique identifier for the concrete attribute type. This is used
60  /// to support dynamic type casting.
61  TypeID getTypeID() { return impl->getAbstractAttribute().getTypeID(); }
62 
63  /// Return the type of this attribute.
64  Type getType() const { return impl->getType(); }
65 
66  /// Return the context this attribute belongs to.
67  MLIRContext *getContext() const;
68 
69  /// Get the dialect this attribute is registered to.
70  Dialect &getDialect() const {
71  return impl->getAbstractAttribute().getDialect();
72  }
73 
74  /// Print the attribute.
75  void print(raw_ostream &os) const;
76  void dump() const;
77 
78  /// Get an opaque pointer to the attribute.
79  const void *getAsOpaquePointer() const { return impl; }
80  /// Construct an attribute from the opaque pointer representation.
81  static Attribute getFromOpaquePointer(const void *ptr) {
82  return Attribute(reinterpret_cast<const ImplType *>(ptr));
83  }
84 
85  friend ::llvm::hash_code hash_value(Attribute arg);
86 
87  /// Returns true if the type was registered with a particular trait.
88  template <template <typename T> class Trait>
89  bool hasTrait() {
90  return getAbstractAttribute().hasTrait<Trait>();
91  }
92 
93  /// Return the abstract descriptor for this attribute.
95  return impl->getAbstractAttribute();
96  }
97 
98 protected:
99  ImplType *impl{nullptr};
100 };
101 
102 inline raw_ostream &operator<<(raw_ostream &os, Attribute attr) {
103  attr.print(os);
104  return os;
105 }
106 
107 template <typename U> bool Attribute::isa() const {
108  assert(impl && "isa<> used on a null attribute.");
109  return U::classof(*this);
110 }
111 
112 template <typename First, typename Second, typename... Rest>
113 bool Attribute::isa() const {
114  return isa<First>() || isa<Second, Rest...>();
115 }
116 
117 template <typename U> U Attribute::dyn_cast() const {
118  return isa<U>() ? U(impl) : U(nullptr);
119 }
120 template <typename U> U Attribute::dyn_cast_or_null() const {
121  return (impl && isa<U>()) ? U(impl) : U(nullptr);
122 }
123 template <typename U> U Attribute::cast() const {
124  assert(isa<U>());
125  return U(impl);
126 }
127 
128 inline ::llvm::hash_code hash_value(Attribute arg) {
130 }
131 
132 //===----------------------------------------------------------------------===//
133 // NamedAttribute
134 //===----------------------------------------------------------------------===//
135 
136 /// NamedAttribute represents a combination of a name and an Attribute value.
138 public:
139  NamedAttribute(StringAttr name, Attribute value);
140 
141  /// Return the name of the attribute.
142  StringAttr getName() const;
143 
144  /// Return the dialect of the name of this attribute, if the name is prefixed
145  /// by a dialect namespace. For example, `llvm.fast_math` would return the
146  /// LLVM dialect (if it is loaded). Returns nullptr if the dialect isn't
147  /// loaded, or if the name is not prefixed by a dialect namespace.
148  Dialect *getNameDialect() const;
149 
150  /// Return the value of the attribute.
151  Attribute getValue() const { return value; }
152 
153  /// Set the name of this attribute.
154  void setName(StringAttr newName);
155 
156  /// Set the value of this attribute.
157  void setValue(Attribute newValue) {
158  assert(value && "expected valid attribute value");
159  value = newValue;
160  }
161 
162  /// Compare this attribute to the provided attribute, ordering by name.
163  bool operator<(const NamedAttribute &rhs) const;
164  /// Compare this attribute to the provided string, ordering by name.
165  bool operator<(StringRef rhs) const;
166 
167  bool operator==(const NamedAttribute &rhs) const {
168  return name == rhs.name && value == rhs.value;
169  }
170  bool operator!=(const NamedAttribute &rhs) const { return !(*this == rhs); }
171 
172 private:
173  NamedAttribute(Attribute name, Attribute value) : name(name), value(value) {}
174 
175  /// Allow access to internals to enable hashing.
176  friend ::llvm::hash_code hash_value(const NamedAttribute &arg);
178 
179  /// The name of the attribute. This is represented as a StringAttr, but
180  /// type-erased to Attribute in the field.
181  Attribute name;
182  /// The value of the attribute.
184 };
185 
186 inline ::llvm::hash_code hash_value(const NamedAttribute &arg) {
187  using AttrPairT = std::pair<Attribute, Attribute>;
188  return DenseMapInfo<AttrPairT>::getHashValue(AttrPairT(arg.name, arg.value));
189 }
190 
191 //===----------------------------------------------------------------------===//
192 // AttributeTraitBase
193 //===----------------------------------------------------------------------===//
194 
195 namespace AttributeTrait {
196 /// This class represents the base of an attribute trait.
197 template <typename ConcreteType, template <typename> class TraitType>
199 } // namespace AttributeTrait
200 
201 //===----------------------------------------------------------------------===//
202 // AttributeInterface
203 //===----------------------------------------------------------------------===//
204 
205 /// This class represents the base of an attribute interface. See the definition
206 /// of `detail::Interface` for requirements on the `Traits` type.
207 template <typename ConcreteType, typename Traits>
209  : public detail::Interface<ConcreteType, Attribute, Traits, Attribute,
210  AttributeTrait::TraitBase> {
211 public:
213  using InterfaceBase = detail::Interface<ConcreteType, Attribute, Traits,
216 
217 private:
218  /// Returns the impl interface instance for the given type.
219  static typename InterfaceBase::Concept *getInterfaceFor(Attribute attr) {
220  return attr.getAbstractAttribute().getInterface<ConcreteType>();
221  }
222 
223  /// Allow access to 'getInterfaceFor'.
224  friend InterfaceBase;
225 };
226 
227 } // namespace mlir.
228 
229 namespace llvm {
230 
231 // Attribute hash just like pointers.
232 template <> struct DenseMapInfo<mlir::Attribute> {
234  auto *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
235  return mlir::Attribute(static_cast<mlir::Attribute::ImplType *>(pointer));
236  }
239  return mlir::Attribute(static_cast<mlir::Attribute::ImplType *>(pointer));
240  }
241  static unsigned getHashValue(mlir::Attribute val) {
242  return mlir::hash_value(val);
243  }
244  static bool isEqual(mlir::Attribute LHS, mlir::Attribute RHS) {
245  return LHS == RHS;
246  }
247 };
248 template <typename T>
250  T, std::enable_if_t<std::is_base_of<mlir::Attribute, T>::value>>
251  : public DenseMapInfo<mlir::Attribute> {
252  static T getEmptyKey() {
253  const void *pointer = llvm::DenseMapInfo<const void *>::getEmptyKey();
254  return T::getFromOpaquePointer(pointer);
255  }
256  static T getTombstoneKey() {
258  return T::getFromOpaquePointer(pointer);
259  }
260 };
261 
262 /// Allow LLVM to steal the low bits of Attributes.
263 template <> struct PointerLikeTypeTraits<mlir::Attribute> {
264  static inline void *getAsVoidPointer(mlir::Attribute attr) {
265  return const_cast<void *>(attr.getAsOpaquePointer());
266  }
267  static inline mlir::Attribute getFromVoidPointer(void *ptr) {
269  }
270  static constexpr int NumLowBitsAvailable = llvm::PointerLikeTypeTraits<
271  mlir::AttributeStorage *>::NumLowBitsAvailable;
272 };
273 
274 template <> struct DenseMapInfo<mlir::NamedAttribute> {
277  return mlir::NamedAttribute(emptyAttr, emptyAttr);
278  }
281  return mlir::NamedAttribute(tombAttr, tombAttr);
282  }
283  static unsigned getHashValue(mlir::NamedAttribute val) {
284  return mlir::hash_value(val);
285  }
287  return lhs == rhs;
288  }
289 };
290 
291 } // namespace llvm
292 
293 #endif
Include the generated interface declarations.
static bool isEqual(mlir::NamedAttribute lhs, mlir::NamedAttribute rhs)
Definition: Attributes.h:286
static void * getAsVoidPointer(mlir::Attribute attr)
Definition: Attributes.h:264
This class represents the base of an attribute interface.
Definition: Attributes.h:208
U cast() const
Definition: Attributes.h:123
U dyn_cast_or_null() const
Definition: Attributes.h:120
Attribute getValue() const
Return the value of the attribute.
Definition: Attributes.h:151
const void * getAsOpaquePointer() const
Get an opaque pointer to the attribute.
Definition: Attributes.h:79
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:57
bool isa() const
Definition: Attributes.h:107
This class represents an abstract interface.
bool operator!=(const NamedAttribute &rhs) const
Definition: Attributes.h:170
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:52
NamedAttribute represents a combination of a name and an Attribute value.
Definition: Attributes.h:137
static mlir::Attribute getTombstoneKey()
Definition: Attributes.h:237
constexpr Attribute()
Definition: Attributes.h:36
static mlir::NamedAttribute getEmptyKey()
Definition: Attributes.h:275
Dialect & getDialect() const
Get the dialect this attribute is registered to.
Definition: Attributes.h:70
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:128
Attributes are known-constant values of operations.
Definition: Attributes.h:24
Attribute(const ImplType *impl)
Definition: Attributes.h:37
bool operator==(const NamedAttribute &rhs) const
Definition: Attributes.h:167
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:42
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:157
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:240
static mlir::Attribute getEmptyKey()
Definition: Attributes.h:233
Type getType() const
Return the type of this attribute.
Definition: Attributes.h:64
bool operator!=(Attribute other) const
Definition: Attributes.h:44
bool operator!() const
Definition: Attributes.h:47
U dyn_cast() const
Definition: Attributes.h:117
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:244
Base storage class appearing in an attribute.
ImplType * impl
Definition: Attributes.h:99
const AbstractTy & getAbstractAttribute() const
Return the abstract descriptor for this attribute.
Definition: Attributes.h:94
static unsigned getHashValue(mlir::Attribute val)
Definition: Attributes.h:241
static unsigned getHashValue(mlir::NamedAttribute val)
Definition: Attributes.h:283
Helper class for implementing traits for storage classes.
bool operator<(Fraction x, Fraction y)
Definition: Fraction.h:61
static mlir::NamedAttribute getTombstoneKey()
Definition: Attributes.h:279
TypeID getTypeID()
Return a unique identifier for the concrete attribute type.
Definition: Attributes.h:61
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:267
static Attribute getFromOpaquePointer(const void *ptr)
Construct an attribute from the opaque pointer representation.
Definition: Attributes.h:81
Attribute & operator=(const Attribute &other)=default
bool hasTrait()
Returns true if the type was registered with a particular trait.
Definition: Attributes.h:89