MLIR  21.0.0git
BuiltinAttributes.h
Go to the documentation of this file.
1 //===- BuiltinAttributes.h - MLIR Builtin 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_BUILTINATTRIBUTES_H
10 #define MLIR_IR_BUILTINATTRIBUTES_H
11 
13 #include "llvm/ADT/APFloat.h"
14 #include "llvm/ADT/Sequence.h"
15 #include <complex>
16 #include <optional>
17 
18 namespace mlir {
19 class AffineMap;
20 class AsmResourceBlob;
21 class BoolAttr;
22 class BuiltinDialect;
23 class DenseIntElementsAttr;
24 template <typename T>
25 struct DialectResourceBlobHandle;
26 class FlatSymbolRefAttr;
27 class FunctionType;
28 class IntegerSet;
29 class IntegerType;
30 class Location;
31 class Operation;
32 class RankedTensorType;
33 
34 namespace detail {
35 struct DenseIntOrFPElementsAttrStorage;
36 struct DenseStringElementsAttrStorage;
37 struct StringAttrStorage;
38 } // namespace detail
39 
40 //===----------------------------------------------------------------------===//
41 // Elements Attributes
42 //===----------------------------------------------------------------------===//
43 
44 namespace detail {
45 /// Pair of raw pointer and a boolean flag of whether the pointer holds a splat,
46 using DenseIterPtrAndSplat = std::pair<const char *, bool>;
47 
48 /// Impl iterator for indexed DenseElementsAttr iterators that records a data
49 /// pointer and data index that is adjusted for the case of a splat attribute.
50 template <typename ConcreteT, typename T, typename PointerT = T *,
51  typename ReferenceT = T &>
53  : public llvm::indexed_accessor_iterator<ConcreteT, DenseIterPtrAndSplat, T,
54  PointerT, ReferenceT> {
55 protected:
56  DenseElementIndexedIteratorImpl(const char *data, bool isSplat,
57  size_t dataIndex)
58  : llvm::indexed_accessor_iterator<ConcreteT, DenseIterPtrAndSplat, T,
59  PointerT, ReferenceT>({data, isSplat},
60  dataIndex) {}
61 
62  /// Return the current index for this iterator, adjusted for the case of a
63  /// splat.
64  ptrdiff_t getDataIndex() const {
65  bool isSplat = this->base.second;
66  return isSplat ? 0 : this->index;
67  }
68 
69  /// Return the data base pointer.
70  const char *getData() const { return this->base.first; }
71 };
72 
73 /// Type trait detector that checks if a given type T is a complex type.
74 template <typename T>
75 struct is_complex_t : public std::false_type {};
76 template <typename T>
77 struct is_complex_t<std::complex<T>> : public std::true_type {};
78 } // namespace detail
79 
80 /// An attribute that represents a reference to a dense vector or tensor
81 /// object.
82 class DenseElementsAttr : public Attribute {
83 public:
85 
86  /// Allow implicit conversion to ElementsAttr.
87  operator ElementsAttr() const { return cast_if_present<ElementsAttr>(*this); }
88  /// Allow implicit conversion to TypedAttr.
89  operator TypedAttr() const { return ElementsAttr(*this); }
90 
91  /// Type trait used to check if the given type T is a potentially valid C++
92  /// floating point type that can be used to access the underlying element
93  /// types of a DenseElementsAttr.
94  template <typename T>
96  /// The type is a valid floating point type if it is a builtin floating
97  /// point type, or is a potentially user defined floating point type. The
98  /// latter allows for supporting users that have custom types defined for
99  /// bfloat16/half/etc.
100  static constexpr bool value = llvm::is_one_of<T, float, double>::value ||
101  (std::numeric_limits<T>::is_specialized &&
102  !std::numeric_limits<T>::is_integer);
103  };
104 
105  /// Method for support type inquiry through isa, cast and dyn_cast.
106  static bool classof(Attribute attr);
107 
108  /// Constructs a dense elements attribute from an array of element values.
109  /// Each element attribute value is expected to be an element of 'type'.
110  /// 'type' must be a vector or tensor with static shape. If the element of
111  /// `type` is non-integer/index/float it is assumed to be a string type.
112  static DenseElementsAttr get(ShapedType type, ArrayRef<Attribute> values);
113 
114  /// Constructs a dense integer elements attribute from an array of integer
115  /// or floating-point values. Each value is expected to be the same bitwidth
116  /// of the element type of 'type'. 'type' must be a vector or tensor with
117  /// static shape.
118  template <typename T,
119  typename = std::enable_if_t<std::numeric_limits<T>::is_integer ||
121  static DenseElementsAttr get(const ShapedType &type, ArrayRef<T> values) {
122  const char *data = reinterpret_cast<const char *>(values.data());
123  return getRawIntOrFloat(
124  type, ArrayRef<char>(data, values.size() * sizeof(T)), sizeof(T),
125  std::numeric_limits<T>::is_integer, std::numeric_limits<T>::is_signed);
126  }
127 
128  /// Constructs a dense integer elements attribute from a single element.
129  template <typename T,
130  typename = std::enable_if_t<std::numeric_limits<T>::is_integer ||
133  static DenseElementsAttr get(const ShapedType &type, T value) {
134  return get(type, llvm::ArrayRef(value));
135  }
136 
137  /// Constructs a dense complex elements attribute from an array of complex
138  /// values. Each value is expected to be the same bitwidth of the element type
139  /// of 'type'. 'type' must be a vector or tensor with static shape.
140  template <
141  typename T, typename ElementT = typename T::value_type,
142  typename = std::enable_if_t<detail::is_complex_t<T>::value &&
143  (std::numeric_limits<ElementT>::is_integer ||
145  static DenseElementsAttr get(const ShapedType &type, ArrayRef<T> values) {
146  const char *data = reinterpret_cast<const char *>(values.data());
147  return getRawComplex(type, ArrayRef<char>(data, values.size() * sizeof(T)),
148  sizeof(T), std::numeric_limits<ElementT>::is_integer,
149  std::numeric_limits<ElementT>::is_signed);
150  }
151 
152  /// Overload of the above 'get' method that is specialized for boolean values.
153  static DenseElementsAttr get(ShapedType type, ArrayRef<bool> values);
154 
155  /// Overload of the above 'get' method that is specialized for StringRef
156  /// values.
157  static DenseElementsAttr get(ShapedType type, ArrayRef<StringRef> values);
158 
159  /// Constructs a dense integer elements attribute from an array of APInt
160  /// values. Each APInt value is expected to have the same bitwidth as the
161  /// element type of 'type'. 'type' must be a vector or tensor with static
162  /// shape.
163  static DenseElementsAttr get(ShapedType type, ArrayRef<APInt> values);
164 
165  /// Constructs a dense complex elements attribute from an array of APInt
166  /// values. Each APInt value is expected to have the same bitwidth as the
167  /// element type of 'type'. 'type' must be a vector or tensor with static
168  /// shape.
169  static DenseElementsAttr get(ShapedType type,
170  ArrayRef<std::complex<APInt>> values);
171 
172  /// Constructs a dense float elements attribute from an array of APFloat
173  /// values. Each APFloat value is expected to have the same bitwidth as the
174  /// element type of 'type'. 'type' must be a vector or tensor with static
175  /// shape.
176  static DenseElementsAttr get(ShapedType type, ArrayRef<APFloat> values);
177 
178  /// Constructs a dense complex elements attribute from an array of APFloat
179  /// values. Each APFloat value is expected to have the same bitwidth as the
180  /// element type of 'type'. 'type' must be a vector or tensor with static
181  /// shape.
182  static DenseElementsAttr get(ShapedType type,
183  ArrayRef<std::complex<APFloat>> values);
184 
185  /// Construct a dense elements attribute for an initializer_list of values.
186  /// Each value is expected to be the same bitwidth of the element type of
187  /// 'type'. 'type' must be a vector or tensor with static shape.
188  template <typename T>
189  static DenseElementsAttr get(const ShapedType &type,
190  const std::initializer_list<T> &list) {
191  return get(type, ArrayRef<T>(list));
192  }
193 
194  /// Construct a dense elements attribute from a raw buffer representing the
195  /// data for this attribute. Users are encouraged to use one of the
196  /// constructors above, which provide more safeties. However, this
197  /// constructor is useful for tools which may want to interop and can
198  /// follow the precise definition.
199  ///
200  /// The format of the raw buffer is a densely packed array of values that
201  /// can be bitcast to the storage format of the element type specified.
202  /// Types that are not byte aligned will be:
203  /// - For bitwidth > 1: Rounded up to the next byte.
204  /// - For bitwidth = 1: Packed into 8bit bytes with bits corresponding to
205  /// the linear order of the shape type from MSB to LSB, padded to on the
206  /// right.
207  static DenseElementsAttr getFromRawBuffer(ShapedType type,
208  ArrayRef<char> rawBuffer);
209 
210  /// Returns true if the given buffer is a valid raw buffer for the given type.
211  /// `detectedSplat` is set if the buffer is valid and represents a splat
212  /// buffer. The definition may be expanded over time, but currently, a
213  /// splat buffer is detected if:
214  /// - For >1bit: The buffer consists of a single element.
215  /// - For 1bit: The buffer consists of a single byte with value 0 or 255.
216  ///
217  /// User code should be prepared for additional, conformant patterns to be
218  /// identified as splats in the future.
219  static bool isValidRawBuffer(ShapedType type, ArrayRef<char> rawBuffer,
220  bool &detectedSplat);
221 
222  //===--------------------------------------------------------------------===//
223  // Iterators
224  //===--------------------------------------------------------------------===//
225 
226  /// The iterator range over the given iterator type T.
227  template <typename IteratorT>
229 
230  /// The iterator for the given element type T.
231  template <typename T, typename AttrT = DenseElementsAttr>
232  using iterator = decltype(std::declval<AttrT>().template value_begin<T>());
233  /// The iterator range over the given element T.
234  template <typename T, typename AttrT = DenseElementsAttr>
236  decltype(std::declval<AttrT>().template getValues<T>());
237 
238  /// A utility iterator that allows walking over the internal Attribute values
239  /// of a DenseElementsAttr.
241  : public llvm::indexed_accessor_iterator<AttributeElementIterator,
242  const void *, Attribute,
243  Attribute, Attribute> {
244  public:
245  /// Accesses the Attribute value at this iterator position.
246  Attribute operator*() const;
247 
248  private:
249  friend DenseElementsAttr;
250 
251  /// Constructs a new iterator.
252  AttributeElementIterator(DenseElementsAttr attr, size_t index);
253  };
254 
255  /// Iterator for walking raw element values of the specified type 'T', which
256  /// may be any c++ data type matching the stored representation: int32_t,
257  /// float, etc.
258  template <typename T>
260  : public detail::DenseElementIndexedIteratorImpl<ElementIterator<T>,
261  const T> {
262  public:
263  /// Accesses the raw value at this iterator position.
264  const T &operator*() const {
265  return reinterpret_cast<const T *>(this->getData())[this->getDataIndex()];
266  }
267 
268  private:
269  friend DenseElementsAttr;
270 
271  /// Constructs a new iterator.
272  ElementIterator(const char *data, bool isSplat, size_t dataIndex)
273  : detail::DenseElementIndexedIteratorImpl<ElementIterator<T>, const T>(
274  data, isSplat, dataIndex) {}
275  };
276 
277  /// A utility iterator that allows walking over the internal bool values.
279  : public detail::DenseElementIndexedIteratorImpl<BoolElementIterator,
280  bool, bool, bool> {
281  public:
282  /// Accesses the bool value at this iterator position.
283  bool operator*() const;
284 
285  private:
286  friend DenseElementsAttr;
287 
288  /// Constructs a new iterator.
289  BoolElementIterator(DenseElementsAttr attr, size_t dataIndex);
290  };
291 
292  /// A utility iterator that allows walking over the internal raw APInt values.
294  : public detail::DenseElementIndexedIteratorImpl<IntElementIterator,
295  APInt, APInt, APInt> {
296  public:
297  /// Accesses the raw APInt value at this iterator position.
298  APInt operator*() const;
299 
300  private:
301  friend DenseElementsAttr;
302 
303  /// Constructs a new iterator.
304  IntElementIterator(DenseElementsAttr attr, size_t dataIndex);
305 
306  /// The bitwidth of the element type.
307  size_t bitWidth;
308  };
309 
310  /// A utility iterator that allows walking over the internal raw complex APInt
311  /// values.
314  ComplexIntElementIterator, std::complex<APInt>, std::complex<APInt>,
315  std::complex<APInt>> {
316  public:
317  /// Accesses the raw std::complex<APInt> value at this iterator position.
318  std::complex<APInt> operator*() const;
319 
320  private:
321  friend DenseElementsAttr;
322 
323  /// Constructs a new iterator.
324  ComplexIntElementIterator(DenseElementsAttr attr, size_t dataIndex);
325 
326  /// The bitwidth of the element type.
327  size_t bitWidth;
328  };
329 
330  /// Iterator for walking over APFloat values.
332  : public llvm::mapped_iterator_base<FloatElementIterator,
333  IntElementIterator, APFloat> {
334  public:
335  /// Map the element to the iterator result type.
336  APFloat mapElement(const APInt &value) const {
337  return APFloat(*smt, value);
338  }
339 
340  private:
341  friend DenseElementsAttr;
342 
343  /// Initializes the float element iterator to the specified iterator.
344  FloatElementIterator(const llvm::fltSemantics &smt, IntElementIterator it)
345  : BaseT(it), smt(&smt) {}
346 
347  /// The float semantics to use when constructing the APFloat.
348  const llvm::fltSemantics *smt;
349  };
350 
351  /// Iterator for walking over complex APFloat values.
353  : public llvm::mapped_iterator_base<ComplexFloatElementIterator,
354  ComplexIntElementIterator,
355  std::complex<APFloat>> {
356  public:
357  /// Map the element to the iterator result type.
358  std::complex<APFloat> mapElement(const std::complex<APInt> &value) const {
359  return {APFloat(*smt, value.real()), APFloat(*smt, value.imag())};
360  }
361 
362  private:
363  friend DenseElementsAttr;
364 
365  /// Initializes the float element iterator to the specified iterator.
366  ComplexFloatElementIterator(const llvm::fltSemantics &smt,
368  : BaseT(it), smt(&smt) {}
369 
370  /// The float semantics to use when constructing the APFloat.
371  const llvm::fltSemantics *smt;
372  };
373 
374  //===--------------------------------------------------------------------===//
375  // Value Querying
376  //===--------------------------------------------------------------------===//
377 
378  /// Returns true if this attribute corresponds to a splat, i.e. if all element
379  /// values are the same.
380  bool isSplat() const;
381 
382  /// Return the splat value for this attribute. This asserts that the attribute
383  /// corresponds to a splat.
384  template <typename T>
385  std::enable_if_t<!std::is_base_of<Attribute, T>::value ||
386  std::is_same<Attribute, T>::value,
387  T>
388  getSplatValue() const {
389  assert(isSplat() && "expected the attribute to be a splat");
390  return *value_begin<T>();
391  }
392  /// Return the splat value for derived attribute element types.
393  template <typename T>
394  std::enable_if_t<std::is_base_of<Attribute, T>::value &&
395  !std::is_same<Attribute, T>::value,
396  T>
397  getSplatValue() const {
398  return llvm::cast<T>(getSplatValue<Attribute>());
399  }
400 
401  /// Try to get an iterator of the given type to the start of the held element
402  /// values. Return failure if the type cannot be iterated.
403  template <typename T>
404  auto try_value_begin() const {
405  auto range = tryGetValues<T>();
406  using iterator = decltype(range->begin());
407  return failed(range) ? FailureOr<iterator>(failure()) : range->begin();
408  }
409 
410  /// Try to get an iterator of the given type to the end of the held element
411  /// values. Return failure if the type cannot be iterated.
412  template <typename T>
413  auto try_value_end() const {
414  auto range = tryGetValues<T>();
415  using iterator = decltype(range->begin());
416  return failed(range) ? FailureOr<iterator>(failure()) : range->end();
417  }
418 
419  /// Return the held element values as a range of the given type.
420  template <typename T>
421  auto getValues() const {
422  auto range = tryGetValues<T>();
423  assert(succeeded(range) && "element type cannot be iterated");
424  return std::move(*range);
425  }
426 
427  /// Get an iterator of the given type to the start of the held element values.
428  template <typename T>
429  auto value_begin() const {
430  return getValues<T>().begin();
431  }
432 
433  /// Get an iterator of the given type to the end of the held element values.
434  template <typename T>
435  auto value_end() const {
436  return getValues<T>().end();
437  }
438 
439  /// Try to get the held element values as a range of integer or floating-point
440  /// values.
441  template <typename T>
443  std::enable_if_t<(!std::is_same<T, bool>::value &&
444  std::numeric_limits<T>::is_integer) ||
446  template <typename T, typename = IntFloatValueTemplateCheckT<T>>
447  FailureOr<iterator_range_impl<ElementIterator<T>>> tryGetValues() const {
448  if (!isValidIntOrFloat(sizeof(T), std::numeric_limits<T>::is_integer,
449  std::numeric_limits<T>::is_signed))
450  return failure();
451  const char *rawData = getRawData().data();
452  bool splat = isSplat();
454  getType(), ElementIterator<T>(rawData, splat, 0),
455  ElementIterator<T>(rawData, splat, getNumElements()));
456  }
457 
458  /// Try to get the held element values as a range of std::complex.
459  template <typename T, typename ElementT>
461  std::enable_if_t<detail::is_complex_t<T>::value &&
462  (std::numeric_limits<ElementT>::is_integer ||
464  template <typename T, typename ElementT = typename T::value_type,
466  FailureOr<iterator_range_impl<ElementIterator<T>>> tryGetValues() const {
467  if (!isValidComplex(sizeof(T), std::numeric_limits<ElementT>::is_integer,
468  std::numeric_limits<ElementT>::is_signed))
469  return failure();
470  const char *rawData = getRawData().data();
471  bool splat = isSplat();
473  getType(), ElementIterator<T>(rawData, splat, 0),
474  ElementIterator<T>(rawData, splat, getNumElements()));
475  }
476 
477  /// Try to get the held element values as a range of StringRef.
478  template <typename T>
480  std::enable_if_t<std::is_same<T, StringRef>::value>;
481  template <typename T, typename = StringRefValueTemplateCheckT<T>>
482  FailureOr<iterator_range_impl<ElementIterator<StringRef>>>
483  tryGetValues() const {
484  auto stringRefs = getRawStringData();
485  const char *ptr = reinterpret_cast<const char *>(stringRefs.data());
486  bool splat = isSplat();
488  getType(), ElementIterator<StringRef>(ptr, splat, 0),
490  }
491 
492  /// Try to get the held element values as a range of Attributes.
493  template <typename T>
495  std::enable_if_t<std::is_same<T, Attribute>::value>;
496  template <typename T, typename = AttributeValueTemplateCheckT<T>>
497  FailureOr<iterator_range_impl<AttributeElementIterator>>
498  tryGetValues() const {
500  getType(), AttributeElementIterator(*this, 0),
502  }
503 
504  /// Try to get the held element values a range of T, where T is a derived
505  /// attribute type.
506  template <typename T>
508  std::enable_if_t<std::is_base_of<Attribute, T>::value &&
509  !std::is_same<Attribute, T>::value>;
510  template <typename T>
512  : public llvm::mapped_iterator_base<DerivedAttributeElementIterator<T>,
513  AttributeElementIterator, T> {
514  using llvm::mapped_iterator_base<DerivedAttributeElementIterator<T>,
516  T>::mapped_iterator_base;
517 
518  /// Map the element to the iterator result type.
519  T mapElement(Attribute attr) const { return llvm::cast<T>(attr); }
520  };
521  template <typename T, typename = DerivedAttrValueTemplateCheckT<T>>
522  FailureOr<iterator_range_impl<DerivedAttributeElementIterator<T>>>
523  tryGetValues() const {
524  using DerivedIterT = DerivedAttributeElementIterator<T>;
526  getType(), DerivedIterT(value_begin<Attribute>()),
527  DerivedIterT(value_end<Attribute>()));
528  }
529 
530  /// Try to get the held element values as a range of bool. The element type of
531  /// this attribute must be of integer type of bitwidth 1.
532  template <typename T>
534  std::enable_if_t<std::is_same<T, bool>::value>;
535  template <typename T, typename = BoolValueTemplateCheckT<T>>
536  FailureOr<iterator_range_impl<BoolElementIterator>> tryGetValues() const {
537  if (!isValidBool())
538  return failure();
540  getType(), BoolElementIterator(*this, 0),
542  }
543 
544  /// Try to get the held element values as a range of APInts. The element type
545  /// of this attribute must be of integer type.
546  template <typename T>
548  std::enable_if_t<std::is_same<T, APInt>::value>;
549  template <typename T, typename = APIntValueTemplateCheckT<T>>
550  FailureOr<iterator_range_impl<IntElementIterator>> tryGetValues() const {
551  if (!getElementType().isIntOrIndex())
552  return failure();
554  raw_int_end());
555  }
556 
557  /// Try to get the held element values as a range of complex APInts. The
558  /// element type of this attribute must be a complex of integer type.
559  template <typename T>
561  std::enable_if_t<std::is_same<T, std::complex<APInt>>::value>;
562  template <typename T, typename = ComplexAPIntValueTemplateCheckT<T>>
563  FailureOr<iterator_range_impl<ComplexIntElementIterator>>
564  tryGetValues() const {
565  return tryGetComplexIntValues();
566  }
567 
568  /// Try to get the held element values as a range of APFloat. The element type
569  /// of this attribute must be of float type.
570  template <typename T>
572  std::enable_if_t<std::is_same<T, APFloat>::value>;
573  template <typename T, typename = APFloatValueTemplateCheckT<T>>
574  FailureOr<iterator_range_impl<FloatElementIterator>> tryGetValues() const {
575  return tryGetFloatValues();
576  }
577 
578  /// Try to get the held element values as a range of complex APFloat. The
579  /// element type of this attribute must be a complex of float type.
580  template <typename T>
582  std::enable_if_t<std::is_same<T, std::complex<APFloat>>::value>;
583  template <typename T, typename = ComplexAPFloatValueTemplateCheckT<T>>
584  FailureOr<iterator_range_impl<ComplexFloatElementIterator>>
585  tryGetValues() const {
586  return tryGetComplexFloatValues();
587  }
588 
589  /// Return the raw storage data held by this attribute. Users should generally
590  /// not use this directly, as the internal storage format is not always in the
591  /// form the user might expect.
592  ArrayRef<char> getRawData() const;
593 
594  /// Return the raw StringRef data held by this attribute.
596 
597  /// Return the type of this ElementsAttr, guaranteed to be a vector or tensor
598  /// with static shape.
599  ShapedType getType() const;
600 
601  /// Return the element type of this DenseElementsAttr.
602  Type getElementType() const;
603 
604  /// Returns the number of elements held by this attribute.
605  int64_t getNumElements() const;
606 
607  /// Returns the number of elements held by this attribute.
608  int64_t size() const { return getNumElements(); }
609 
610  /// Returns if the number of elements held by this attribute is 0.
611  bool empty() const { return size() == 0; }
612 
613  //===--------------------------------------------------------------------===//
614  // Mutation Utilities
615  //===--------------------------------------------------------------------===//
616 
617  /// Return a new DenseElementsAttr that has the same data as the current
618  /// attribute, but has been reshaped to 'newType'. The new type must have the
619  /// same total number of elements as well as element type.
620  DenseElementsAttr reshape(ShapedType newType);
621 
622  /// Return a new DenseElementsAttr that has the same data as the current
623  /// attribute, but with a different shape for a splat type. The new type must
624  /// have the same element type.
625  DenseElementsAttr resizeSplat(ShapedType newType);
626 
627  /// Return a new DenseElementsAttr that has the same data as the current
628  /// attribute, but has bitcast elements to 'newElType'. The new type must have
629  /// the same bitwidth as the current element type.
630  DenseElementsAttr bitcast(Type newElType);
631 
632  /// Generates a new DenseElementsAttr by mapping each int value to a new
633  /// underlying APInt. The new values can represent either an integer or float.
634  /// This underlying type must be an DenseIntElementsAttr.
635  DenseElementsAttr mapValues(Type newElementType,
636  function_ref<APInt(const APInt &)> mapping) const;
637 
638  /// Generates a new DenseElementsAttr by mapping each float value to a new
639  /// underlying APInt. the new values can represent either an integer or float.
640  /// This underlying type must be an DenseFPElementsAttr.
642  mapValues(Type newElementType,
643  function_ref<APInt(const APFloat &)> mapping) const;
644 
645 protected:
646  /// Iterators to various elements that require out-of-line definition. These
647  /// are hidden from the user to encourage consistent use of the
648  /// getValues/value_begin/value_end API.
650  return IntElementIterator(*this, 0);
651  }
653  return IntElementIterator(*this, getNumElements());
654  }
655  FailureOr<iterator_range_impl<ComplexIntElementIterator>>
656  tryGetComplexIntValues() const;
657  FailureOr<iterator_range_impl<FloatElementIterator>>
658  tryGetFloatValues() const;
659  FailureOr<iterator_range_impl<ComplexFloatElementIterator>>
660  tryGetComplexFloatValues() const;
661 
662  /// Overload of the raw 'get' method that asserts that the given type is of
663  /// complex type. This method is used to verify type invariants that the
664  /// templatized 'get' method cannot.
665  static DenseElementsAttr getRawComplex(ShapedType type, ArrayRef<char> data,
666  int64_t dataEltSize, bool isInt,
667  bool isSigned);
668 
669  /// Overload of the raw 'get' method that asserts that the given type is of
670  /// integer or floating-point type. This method is used to verify type
671  /// invariants that the templatized 'get' method cannot.
672  static DenseElementsAttr getRawIntOrFloat(ShapedType type,
673  ArrayRef<char> data,
674  int64_t dataEltSize, bool isInt,
675  bool isSigned);
676 
677  /// Check the information for a C++ data type, check if this type is valid for
678  /// the current attribute. This method is used to verify specific type
679  /// invariants that the templatized 'getValues' method cannot.
680  bool isValidBool() const { return getElementType().isInteger(1); }
681  bool isValidIntOrFloat(int64_t dataEltSize, bool isInt, bool isSigned) const;
682  bool isValidComplex(int64_t dataEltSize, bool isInt, bool isSigned) const;
683 };
684 
685 /// An attribute that represents a reference to a splat vector or tensor
686 /// constant, meaning all of the elements have the same value.
688 public:
689  using DenseElementsAttr::DenseElementsAttr;
690 
691  /// Method for support type inquiry through isa, cast and dyn_cast.
692  static bool classof(Attribute attr) {
693  auto denseAttr = llvm::dyn_cast<DenseElementsAttr>(attr);
694  return denseAttr && denseAttr.isSplat();
695  }
696 };
697 
698 //===----------------------------------------------------------------------===//
699 // DenseResourceElementsAttr
700 //===----------------------------------------------------------------------===//
701 
703 
704 } // namespace mlir
705 
706 //===----------------------------------------------------------------------===//
707 // Tablegen Attribute Declarations
708 //===----------------------------------------------------------------------===//
709 
710 #define GET_ATTRDEF_CLASSES
711 #include "mlir/IR/BuiltinAttributes.h.inc"
712 
713 //===----------------------------------------------------------------------===//
714 // C++ Attribute Declarations
715 //===----------------------------------------------------------------------===//
716 
717 namespace mlir {
718 //===----------------------------------------------------------------------===//
719 // DenseArrayAttr
720 //===----------------------------------------------------------------------===//
721 
722 namespace detail {
723 /// Base class for DenseArrayAttr that is instantiated and specialized for each
724 /// supported element type below.
725 template <typename T>
726 class DenseArrayAttrImpl : public DenseArrayAttr {
727 public:
728  using DenseArrayAttr::DenseArrayAttr;
729 
730  /// Implicit conversion to ArrayRef<T>.
731  operator ArrayRef<T>() const;
732  ArrayRef<T> asArrayRef() const { return ArrayRef<T>{*this}; }
733 
734  /// Random access to elements.
735  T operator[](std::size_t index) const { return asArrayRef()[index]; }
736 
737  /// Builder from ArrayRef<T>.
738  static DenseArrayAttrImpl get(MLIRContext *context, ArrayRef<T> content);
739 
740  /// Print the short form `[42, 100, -1]` without any type prefix.
741  void print(AsmPrinter &printer) const;
742  void print(raw_ostream &os) const;
743  /// Print the short form `42, 100, -1` without any braces or type prefix.
744  void printWithoutBraces(raw_ostream &os) const;
745 
746  /// Parse the short form `[42, 100, -1]` without any type prefix.
747  static Attribute parse(AsmParser &parser, Type type);
748 
749  /// Parse the short form `42, 100, -1` without any type prefix or braces.
750  static Attribute parseWithoutBraces(AsmParser &parser, Type type);
751 
752  /// Support for isa<>/cast<>.
753  static bool classof(Attribute attr);
754 };
755 
756 extern template class DenseArrayAttrImpl<bool>;
757 extern template class DenseArrayAttrImpl<int8_t>;
758 extern template class DenseArrayAttrImpl<int16_t>;
759 extern template class DenseArrayAttrImpl<int32_t>;
760 extern template class DenseArrayAttrImpl<int64_t>;
761 extern template class DenseArrayAttrImpl<float>;
762 extern template class DenseArrayAttrImpl<double>;
763 } // namespace detail
764 
765 // Public name for all the supported DenseArrayAttr
773 
774 //===----------------------------------------------------------------------===//
775 // DenseResourceElementsAttr
776 //===----------------------------------------------------------------------===//
777 
778 namespace detail {
779 /// Base class for DenseResourceElementsAttr that is instantiated and
780 /// specialized for each supported element type below.
781 template <typename T>
783 public:
784  using DenseResourceElementsAttr::DenseResourceElementsAttr;
785 
786  /// A builder that inserts a new resource using the provided blob. The handle
787  /// of the inserted blob is used when building the attribute. The provided
788  /// `blobName` is used as a hint for the key of the new handle for the `blob`
789  /// resource, but may be changed if necessary to ensure uniqueness during
790  /// insertion.
792  get(ShapedType type, StringRef blobName, AsmResourceBlob blob);
793 
794  /// Return the data of this attribute as an ArrayRef<T> if it is present,
795  /// returns std::nullopt otherwise.
796  std::optional<ArrayRef<T>> tryGetAsArrayRef() const;
797 
798  /// Support for isa<>/cast<>.
799  static bool classof(Attribute attr);
800 };
801 
802 extern template class DenseResourceElementsAttrBase<bool>;
803 extern template class DenseResourceElementsAttrBase<int8_t>;
804 extern template class DenseResourceElementsAttrBase<int16_t>;
805 extern template class DenseResourceElementsAttrBase<int32_t>;
806 extern template class DenseResourceElementsAttrBase<int64_t>;
807 extern template class DenseResourceElementsAttrBase<uint8_t>;
808 extern template class DenseResourceElementsAttrBase<uint16_t>;
809 extern template class DenseResourceElementsAttrBase<uint32_t>;
810 extern template class DenseResourceElementsAttrBase<uint64_t>;
811 extern template class DenseResourceElementsAttrBase<float>;
812 extern template class DenseResourceElementsAttrBase<double>;
813 } // namespace detail
814 
815 // Public names for all the supported DenseResourceElementsAttr.
816 
839 
840 //===----------------------------------------------------------------------===//
841 // BoolAttr
842 //===----------------------------------------------------------------------===//
843 
844 /// Special case of IntegerAttr to represent boolean integers, i.e., signless i1
845 /// integers.
846 class BoolAttr : public Attribute {
847 public:
848  using Attribute::Attribute;
849  using ValueType = bool;
850 
851  static BoolAttr get(MLIRContext *context, bool value);
852 
853  /// Enable conversion to IntegerAttr and its interfaces. This uses conversion
854  /// vs. inheritance to avoid bringing in all of IntegerAttrs methods.
855  operator IntegerAttr() const { return IntegerAttr(impl); }
856  operator TypedAttr() const { return IntegerAttr(impl); }
857 
858  /// Return the boolean value of this attribute.
859  bool getValue() const;
860 
861  /// Methods for support type inquiry through isa, cast, and dyn_cast.
862  static bool classof(Attribute attr);
863 };
864 
865 //===----------------------------------------------------------------------===//
866 // FlatSymbolRefAttr
867 //===----------------------------------------------------------------------===//
868 
869 /// A symbol reference with a reference path containing a single element. This
870 /// is used to refer to an operation within the current symbol table.
871 class FlatSymbolRefAttr : public SymbolRefAttr {
872 public:
873  using SymbolRefAttr::SymbolRefAttr;
874  using ValueType = StringRef;
875 
876  /// Construct a symbol reference for the given value name.
877  static FlatSymbolRefAttr get(StringAttr value) {
878  return SymbolRefAttr::get(value);
879  }
880  static FlatSymbolRefAttr get(MLIRContext *ctx, StringRef value) {
881  return SymbolRefAttr::get(ctx, value);
882  }
883 
884  /// Convenience getter for building a SymbolRefAttr based on an operation
885  /// that implements the SymbolTrait.
886  static FlatSymbolRefAttr get(Operation *symbol) {
887  return SymbolRefAttr::get(symbol);
888  }
889 
890  /// Returns the name of the held symbol reference as a StringAttr.
891  StringAttr getAttr() const { return getRootReference(); }
892 
893  /// Returns the name of the held symbol reference.
894  StringRef getValue() const { return getAttr().getValue(); }
895 
896  /// Methods for support type inquiry through isa, cast, and dyn_cast.
897  static bool classof(Attribute attr) {
898  SymbolRefAttr refAttr = llvm::dyn_cast<SymbolRefAttr>(attr);
899  return refAttr && refAttr.getNestedReferences().empty();
900  }
901 
902 private:
903  using SymbolRefAttr::get;
904  using SymbolRefAttr::getNestedReferences;
905 };
906 
907 //===----------------------------------------------------------------------===//
908 // DenseFPElementsAttr
909 //===----------------------------------------------------------------------===//
910 
911 /// An attribute that represents a reference to a dense float vector or tensor
912 /// object. Each element is stored as a double.
914 public:
916 
917  using DenseIntOrFPElementsAttr::DenseIntOrFPElementsAttr;
918 
919  /// Get an instance of a DenseFPElementsAttr with the given arguments. This
920  /// simply wraps the DenseElementsAttr::get calls.
921  template <typename Arg>
922  static DenseFPElementsAttr get(const ShapedType &type, Arg &&arg) {
923  return llvm::cast<DenseFPElementsAttr>(
925  }
926  template <typename T>
927  static DenseFPElementsAttr get(const ShapedType &type,
928  const std::initializer_list<T> &list) {
929  return llvm::cast<DenseFPElementsAttr>(DenseElementsAttr::get(type, list));
930  }
931 
932  /// Generates a new DenseElementsAttr by mapping each value attribute, and
933  /// constructing the DenseElementsAttr given the new element type.
935  mapValues(Type newElementType,
936  function_ref<APInt(const APFloat &)> mapping) const;
937 
938  /// Iterator access to the float element values.
939  iterator begin() const { return tryGetFloatValues()->begin(); }
940  iterator end() const { return tryGetFloatValues()->end(); }
941 
942  /// Method for supporting type inquiry through isa, cast and dyn_cast.
943  static bool classof(Attribute attr);
944 };
945 
946 //===----------------------------------------------------------------------===//
947 // DenseIntElementsAttr
948 //===----------------------------------------------------------------------===//
949 
950 /// An attribute that represents a reference to a dense integer vector or tensor
951 /// object.
953 public:
954  /// DenseIntElementsAttr iterates on APInt, so we can use the raw element
955  /// iterator directly.
957 
958  using DenseIntOrFPElementsAttr::DenseIntOrFPElementsAttr;
959 
960  /// Get an instance of a DenseIntElementsAttr with the given arguments. This
961  /// simply wraps the DenseElementsAttr::get calls.
962  template <typename Arg>
963  static DenseIntElementsAttr get(const ShapedType &type, Arg &&arg) {
964  return llvm::cast<DenseIntElementsAttr>(
966  }
967  template <typename T>
968  static DenseIntElementsAttr get(const ShapedType &type,
969  const std::initializer_list<T> &list) {
970  return llvm::cast<DenseIntElementsAttr>(DenseElementsAttr::get(type, list));
971  }
972 
973  /// Generates a new DenseElementsAttr by mapping each value attribute, and
974  /// constructing the DenseElementsAttr given the new element type.
975  DenseElementsAttr mapValues(Type newElementType,
976  function_ref<APInt(const APInt &)> mapping) const;
977 
978  /// Iterator access to the integer element values.
979  iterator begin() const { return raw_int_begin(); }
980  iterator end() const { return raw_int_end(); }
981 
982  /// Method for supporting type inquiry through isa, cast and dyn_cast.
983  static bool classof(Attribute attr);
984 };
985 
986 //===----------------------------------------------------------------------===//
987 // SparseElementsAttr
988 //===----------------------------------------------------------------------===//
989 
990 template <typename T>
991 auto SparseElementsAttr::try_value_begin_impl(OverloadToken<T>) const
992  -> FailureOr<iterator<T>> {
993  auto zeroValue = getZeroValue<T>();
994  auto valueIt = getValues().try_value_begin<T>();
995  if (failed(valueIt))
996  return failure();
997  const std::vector<ptrdiff_t> flatSparseIndices(getFlattenedSparseIndices());
998  std::function<T(ptrdiff_t)> mapFn =
999  [flatSparseIndices{flatSparseIndices}, valueIt{std::move(*valueIt)},
1000  zeroValue{std::move(zeroValue)}](ptrdiff_t index) {
1001  // Try to map the current index to one of the sparse indices.
1002  for (unsigned i = 0, e = flatSparseIndices.size(); i != e; ++i)
1003  if (flatSparseIndices[i] == index)
1004  return *std::next(valueIt, i);
1005  // Otherwise, return the zero value.
1006  return zeroValue;
1007  };
1008  return iterator<T>(llvm::seq<ptrdiff_t>(0, getNumElements()).begin(), mapFn);
1009 }
1010 
1011 //===----------------------------------------------------------------------===//
1012 // DistinctAttr
1013 //===----------------------------------------------------------------------===//
1014 
1015 namespace detail {
1016 struct DistinctAttrStorage;
1017 class DistinctAttributeUniquer;
1018 } // namespace detail
1019 
1020 /// An attribute that associates a referenced attribute with a unique
1021 /// identifier. Every call to the create function allocates a new distinct
1022 /// attribute instance. The address of the attribute instance serves as a
1023 /// temporary identifier. Similar to the names of SSA values, the final
1024 /// identifiers are generated during pretty printing. This delayed numbering
1025 /// ensures the printed identifiers are deterministic even if multiple distinct
1026 /// attribute instances are created in-parallel.
1027 ///
1028 /// Examples:
1029 ///
1030 /// #distinct = distinct[0]<42.0 : f32>
1031 /// #distinct1 = distinct[1]<42.0 : f32>
1032 /// #distinct2 = distinct[2]<array<i32: 10, 42>>
1033 ///
1034 /// NOTE: The distinct attribute cannot be defined using ODS since it uses a
1035 /// custom distinct attribute uniquer that cannot be set from ODS.
1037  : public detail::StorageUserBase<DistinctAttr, Attribute,
1038  detail::DistinctAttrStorage,
1039  detail::DistinctAttributeUniquer> {
1040 public:
1041  using Base::Base;
1042 
1043  /// Returns the referenced attribute.
1044  Attribute getReferencedAttr() const;
1045 
1046  /// Creates a distinct attribute that associates a referenced attribute with a
1047  /// unique identifier.
1048  static DistinctAttr create(Attribute referencedAttr);
1049 
1050  static constexpr StringLiteral name = "builtin.distinct";
1051 };
1052 
1053 //===----------------------------------------------------------------------===//
1054 // StringAttr
1055 //===----------------------------------------------------------------------===//
1056 
1057 /// Define comparisons for StringAttr against nullptr and itself to avoid the
1058 /// StringRef overloads from being chosen when not desirable.
1059 inline bool operator==(StringAttr lhs, std::nullptr_t) { return !lhs; }
1060 inline bool operator!=(StringAttr lhs, std::nullptr_t) {
1061  return static_cast<bool>(lhs);
1062 }
1063 inline bool operator==(StringAttr lhs, StringAttr rhs) {
1064  return (Attribute)lhs == (Attribute)rhs;
1065 }
1066 inline bool operator!=(StringAttr lhs, StringAttr rhs) { return !(lhs == rhs); }
1067 
1068 /// Allow direct comparison with StringRef.
1069 inline bool operator==(StringAttr lhs, StringRef rhs) {
1070  return lhs.getValue() == rhs;
1071 }
1072 inline bool operator!=(StringAttr lhs, StringRef rhs) { return !(lhs == rhs); }
1073 inline bool operator==(StringRef lhs, StringAttr rhs) {
1074  return rhs.getValue() == lhs;
1075 }
1076 inline bool operator!=(StringRef lhs, StringAttr rhs) { return !(lhs == rhs); }
1077 
1078 } // namespace mlir
1079 
1080 //===----------------------------------------------------------------------===//
1081 // Attribute Utilities
1082 //===----------------------------------------------------------------------===//
1083 
1084 namespace mlir {
1085 
1086 /// Given a list of strides (in which ShapedType::kDynamic
1087 /// represents a dynamic value), return the single result AffineMap which
1088 /// represents the linearized strided layout map. Dimensions correspond to the
1089 /// offset followed by the strides in order. Symbols are inserted for each
1090 /// dynamic dimension in order. A stride is always positive.
1091 ///
1092 /// Examples:
1093 /// =========
1094 ///
1095 /// 1. For offset: 0 strides: ?, ?, 1 return
1096 /// (i, j, k)[M, N]->(M * i + N * j + k)
1097 ///
1098 /// 2. For offset: 3 strides: 32, ?, 16 return
1099 /// (i, j, k)[M]->(3 + 32 * i + M * j + 16 * k)
1100 ///
1101 /// 3. For offset: ? strides: ?, ?, ? return
1102 /// (i, j, k)[off, M, N, P]->(off + M * i + N * j + P * k)
1103 AffineMap makeStridedLinearLayoutMap(ArrayRef<int64_t> strides, int64_t offset,
1104  MLIRContext *context);
1105 
1106 } // namespace mlir
1107 
1108 namespace llvm {
1109 
1110 template <>
1111 struct DenseMapInfo<mlir::StringAttr> : public DenseMapInfo<mlir::Attribute> {
1112  static mlir::StringAttr getEmptyKey() {
1113  const void *pointer = llvm::DenseMapInfo<const void *>::getEmptyKey();
1114  return mlir::StringAttr::getFromOpaquePointer(pointer);
1115  }
1116  static mlir::StringAttr getTombstoneKey() {
1117  const void *pointer = llvm::DenseMapInfo<const void *>::getTombstoneKey();
1118  return mlir::StringAttr::getFromOpaquePointer(pointer);
1119  }
1120 };
1121 template <>
1122 struct PointerLikeTypeTraits<mlir::StringAttr>
1123  : public PointerLikeTypeTraits<mlir::Attribute> {
1124  static inline mlir::StringAttr getFromVoidPointer(void *p) {
1125  return mlir::StringAttr::getFromOpaquePointer(p);
1126  }
1127 };
1128 
1129 template <>
1130 struct PointerLikeTypeTraits<mlir::IntegerAttr>
1131  : public PointerLikeTypeTraits<mlir::Attribute> {
1132  static inline mlir::IntegerAttr getFromVoidPointer(void *p) {
1133  return mlir::IntegerAttr::getFromOpaquePointer(p);
1134  }
1135 };
1136 
1137 template <>
1138 struct PointerLikeTypeTraits<mlir::SymbolRefAttr>
1139  : public PointerLikeTypeTraits<mlir::Attribute> {
1140  static inline mlir::SymbolRefAttr getFromVoidPointer(void *ptr) {
1141  return mlir::SymbolRefAttr::getFromOpaquePointer(ptr);
1142  }
1143 };
1144 
1145 } // namespace llvm
1146 
1147 #endif // MLIR_IR_BUILTINATTRIBUTES_H
static int64_t getNumElements(Type t)
Compute the total number of elements in the given type, also taking into account nested types.
This base class exposes generic asm parser hooks, usable across the various derived parsers.
This base class exposes generic asm printer hooks, usable across the various derived printers.
This class represents a processed binary blob of data.
Definition: AsmState.h:91
Attributes are known-constant values of operations.
Definition: Attributes.h:25
constexpr Attribute()=default
Special case of IntegerAttr to represent boolean integers, i.e., signless i1 integers.
A utility iterator that allows walking over the internal Attribute values of a DenseElementsAttr.
A utility iterator that allows walking over the internal bool values.
bool operator*() const
Accesses the bool value at this iterator position.
Iterator for walking over complex APFloat values.
std::complex< APFloat > mapElement(const std::complex< APInt > &value) const
Map the element to the iterator result type.
A utility iterator that allows walking over the internal raw complex APInt values.
std::complex< APInt > operator*() const
Accesses the raw std::complex<APInt> value at this iterator position.
Iterator for walking raw element values of the specified type 'T', which may be any c++ data type mat...
const T & operator*() const
Accesses the raw value at this iterator position.
Iterator for walking over APFloat values.
APFloat mapElement(const APInt &value) const
Map the element to the iterator result type.
A utility iterator that allows walking over the internal raw APInt values.
APInt operator*() const
Accesses the raw APInt value at this iterator position.
An attribute that represents a reference to a dense vector or tensor object.
std::enable_if_t<!std::is_base_of< Attribute, T >::value||std::is_same< Attribute, T >::value, T > getSplatValue() const
Return the splat value for this attribute.
ArrayRef< StringRef > getRawStringData() const
Return the raw StringRef data held by this attribute.
IntElementIterator raw_int_begin() const
Iterators to various elements that require out-of-line definition.
static DenseElementsAttr getRawIntOrFloat(ShapedType type, ArrayRef< char > data, int64_t dataEltSize, bool isInt, bool isSigned)
Overload of the raw 'get' method that asserts that the given type is of integer or floating-point typ...
auto value_begin() const
Get an iterator of the given type to the start of the held element values.
static DenseElementsAttr getRawComplex(ShapedType type, ArrayRef< char > data, int64_t dataEltSize, bool isInt, bool isSigned)
Overload of the raw 'get' method that asserts that the given type is of complex type.
auto try_value_begin() const
Try to get an iterator of the given type to the start of the held element values.
static bool classof(Attribute attr)
Method for support type inquiry through isa, cast and dyn_cast.
std::enable_if_t< std::is_same< T, std::complex< APFloat > >::value > ComplexAPFloatValueTemplateCheckT
Try to get the held element values as a range of complex APFloat.
std::enable_if_t< std::is_same< T, APFloat >::value > APFloatValueTemplateCheckT
Try to get the held element values as a range of APFloat.
std::enable_if_t< std::is_same< T, StringRef >::value > StringRefValueTemplateCheckT
Try to get the held element values as a range of StringRef.
FailureOr< iterator_range_impl< BoolElementIterator > > tryGetValues() const
std::enable_if_t< std::is_same< T, Attribute >::value > AttributeValueTemplateCheckT
Try to get the held element values as a range of Attributes.
bool isValidComplex(int64_t dataEltSize, bool isInt, bool isSigned) const
FailureOr< iterator_range_impl< ComplexFloatElementIterator > > tryGetValues() const
auto getValues() const
Return the held element values as a range of the given type.
DenseElementsAttr resizeSplat(ShapedType newType)
Return a new DenseElementsAttr that has the same data as the current attribute, but with a different ...
int64_t getNumElements() const
Returns the number of elements held by this attribute.
static DenseElementsAttr getFromRawBuffer(ShapedType type, ArrayRef< char > rawBuffer)
Construct a dense elements attribute from a raw buffer representing the data for this attribute.
std::enable_if_t< std::is_base_of< Attribute, T >::value &&!std::is_same< Attribute, T >::value, T > getSplatValue() const
Return the splat value for derived attribute element types.
int64_t size() const
Returns the number of elements held by this attribute.
FailureOr< iterator_range_impl< ComplexIntElementIterator > > tryGetValues() const
bool isValidBool() const
Check the information for a C++ data type, check if this type is valid for the current attribute.
bool isSplat() const
Returns true if this attribute corresponds to a splat, i.e.
auto try_value_end() const
Try to get an iterator of the given type to the end of the held element values.
ArrayRef< char > getRawData() const
Return the raw storage data held by this attribute.
FailureOr< iterator_range_impl< DerivedAttributeElementIterator< T > > > tryGetValues() const
std::enable_if_t<(!std::is_same< T, bool >::value &&std::numeric_limits< T >::is_integer)||is_valid_cpp_fp_type< T >::value > IntFloatValueTemplateCheckT
Try to get the held element values as a range of integer or floating-point values.
FailureOr< iterator_range_impl< ElementIterator< T > > > tryGetValues() const
constexpr Attribute()=default
static DenseElementsAttr get(const ShapedType &type, ArrayRef< T > values)
Constructs a dense integer elements attribute from an array of integer or floating-point values.
FailureOr< iterator_range_impl< FloatElementIterator > > tryGetValues() const
DenseElementsAttr mapValues(Type newElementType, function_ref< APInt(const APInt &)> mapping) const
Generates a new DenseElementsAttr by mapping each int value to a new underlying APInt.
std::enable_if_t< detail::is_complex_t< T >::value &&(std::numeric_limits< ElementT >::is_integer||is_valid_cpp_fp_type< ElementT >::value)> ComplexValueTemplateCheckT
Try to get the held element values as a range of std::complex.
static DenseElementsAttr get(const ShapedType &type, const std::initializer_list< T > &list)
Construct a dense elements attribute for an initializer_list of values.
decltype(std::declval< AttrT >().template value_begin< T >()) iterator
The iterator for the given element type T.
decltype(std::declval< AttrT >().template getValues< T >()) iterator_range
The iterator range over the given element T.
Type getElementType() const
Return the element type of this DenseElementsAttr.
FailureOr< iterator_range_impl< ComplexFloatElementIterator > > tryGetComplexFloatValues() const
IntElementIterator raw_int_end() const
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
ShapedType getType() const
Return the type of this ElementsAttr, guaranteed to be a vector or tensor with static shape.
FailureOr< iterator_range_impl< FloatElementIterator > > tryGetFloatValues() const
static bool isValidRawBuffer(ShapedType type, ArrayRef< char > rawBuffer, bool &detectedSplat)
Returns true if the given buffer is a valid raw buffer for the given type.
FailureOr< iterator_range_impl< AttributeElementIterator > > tryGetValues() const
bool empty() const
Returns if the number of elements held by this attribute is 0.
FailureOr< iterator_range_impl< IntElementIterator > > tryGetValues() const
DenseElementsAttr bitcast(Type newElType)
Return a new DenseElementsAttr that has the same data as the current attribute, but has bitcast eleme...
static DenseElementsAttr get(const ShapedType &type, T value)
Constructs a dense integer elements attribute from a single element.
std::enable_if_t< std::is_same< T, bool >::value > BoolValueTemplateCheckT
Try to get the held element values as a range of bool.
bool isValidIntOrFloat(int64_t dataEltSize, bool isInt, bool isSigned) const
DenseElementsAttr reshape(ShapedType newType)
Return a new DenseElementsAttr that has the same data as the current attribute, but has been reshaped...
std::enable_if_t< std::is_same< T, APInt >::value > APIntValueTemplateCheckT
Try to get the held element values as a range of APInts.
std::enable_if_t< std::is_same< T, std::complex< APInt > >::value > ComplexAPIntValueTemplateCheckT
Try to get the held element values as a range of complex APInts.
FailureOr< iterator_range_impl< ElementIterator< StringRef > > > tryGetValues() const
FailureOr< iterator_range_impl< ComplexIntElementIterator > > tryGetComplexIntValues() const
auto value_end() const
Get an iterator of the given type to the end of the held element values.
static DenseElementsAttr get(const ShapedType &type, ArrayRef< T > values)
Constructs a dense complex elements attribute from an array of complex values.
FailureOr< iterator_range_impl< ElementIterator< T > > > tryGetValues() const
std::enable_if_t< std::is_base_of< Attribute, T >::value &&!std::is_same< Attribute, T >::value > DerivedAttrValueTemplateCheckT
Try to get the held element values a range of T, where T is a derived attribute type.
An attribute that represents a reference to a dense float vector or tensor object.
static DenseFPElementsAttr get(const ShapedType &type, const std::initializer_list< T > &list)
static DenseFPElementsAttr get(const ShapedType &type, Arg &&arg)
Get an instance of a DenseFPElementsAttr with the given arguments.
iterator begin() const
Iterator access to the float element values.
An attribute that represents a reference to a dense integer vector or tensor object.
static DenseIntElementsAttr get(const ShapedType &type, const std::initializer_list< T > &list)
iterator begin() const
Iterator access to the integer element values.
static DenseIntElementsAttr get(const ShapedType &type, Arg &&arg)
Get an instance of a DenseIntElementsAttr with the given arguments.
An attribute that associates a referenced attribute with a unique identifier.
static constexpr StringLiteral name
static DistinctAttr create(Attribute referencedAttr)
Creates a distinct attribute that associates a referenced attribute with a unique identifier.
Attribute getReferencedAttr() const
Returns the referenced attribute.
A symbol reference with a reference path containing a single element.
static FlatSymbolRefAttr get(StringAttr value)
Construct a symbol reference for the given value name.
static FlatSymbolRefAttr get(MLIRContext *ctx, StringRef value)
static bool classof(Attribute attr)
Methods for support type inquiry through isa, cast, and dyn_cast.
static FlatSymbolRefAttr get(Operation *symbol)
Convenience getter for building a SymbolRefAttr based on an operation that implements the SymbolTrait...
StringRef getValue() const
Returns the name of the held symbol reference.
StringAttr getAttr() const
Returns the name of the held symbol reference as a StringAttr.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
An attribute that represents a reference to a splat vector or tensor constant, meaning all of the ele...
static bool classof(Attribute attr)
Method for support type inquiry through isa, cast and dyn_cast.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
bool isInteger() const
Return true if this is an integer type (with the specified width).
Definition: Types.cpp:56
Base class for DenseArrayAttr that is instantiated and specialized for each supported element type be...
static DenseArrayAttrImpl get(MLIRContext *context, ArrayRef< T > content)
Builder from ArrayRef<T>.
static bool classof(Attribute attr)
Support for isa<>/cast<>.
void print(AsmPrinter &printer) const
Print the short form [42, 100, -1] without any type prefix.
static Attribute parse(AsmParser &parser, Type type)
Parse the short form [42, 100, -1] without any type prefix.
static Attribute parseWithoutBraces(AsmParser &parser, Type type)
Parse the short form 42, 100, -1 without any type prefix or braces.
void printWithoutBraces(raw_ostream &os) const
Print the short form 42, 100, -1 without any braces or type prefix.
T operator[](std::size_t index) const
Random access to elements.
Impl iterator for indexed DenseElementsAttr iterators that records a data pointer and data index that...
const char * getData() const
Return the data base pointer.
ptrdiff_t getDataIndex() const
Return the current index for this iterator, adjusted for the case of a splat.
DenseElementIndexedIteratorImpl(const char *data, bool isSplat, size_t dataIndex)
Base class for DenseResourceElementsAttr that is instantiated and specialized for each supported elem...
This class provides iterator utilities for an ElementsAttr range.
Utility class for implementing users of storage classes uniqued by a StorageUniquer.
StorageUserBase< ConcreteT, BaseT, StorageT, UniquerT, Traits... > Base
Utility declarations for the concrete attribute class.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
std::pair< const char *, bool > DenseIterPtrAndSplat
Pair of raw pointer and a boolean flag of whether the pointer holds a splat,.
Include the generated interface declarations.
bool operator==(StringAttr lhs, std::nullptr_t)
Define comparisons for StringAttr against nullptr and itself to avoid the StringRef overloads from be...
bool operator!=(RegionBranchPoint lhs, RegionBranchPoint rhs)
AffineExpr operator*(int64_t val, AffineExpr expr)
Definition: AffineExpr.h:265
AffineMap makeStridedLinearLayoutMap(ArrayRef< int64_t > strides, int64_t offset, MLIRContext *context)
Given a list of strides (in which ShapedType::kDynamic represents a dynamic value),...
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
static mlir::StringAttr getTombstoneKey()
static mlir::IntegerAttr getFromVoidPointer(void *p)
static mlir::StringAttr getFromVoidPointer(void *p)
static mlir::SymbolRefAttr getFromVoidPointer(void *ptr)
T mapElement(Attribute attr) const
Map the element to the iterator result type.
Type trait used to check if the given type T is a potentially valid C++ floating point type that can ...
static constexpr bool value
The type is a valid floating point type if it is a builtin floating point type, or is a potentially u...
This class defines a dialect specific handle to a resource blob.
Type trait detector that checks if a given type T is a complex type.