MLIR  20.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 namespace detail {
722 /// Base class for DenseArrayAttr that is instantiated and specialized for each
723 /// supported element type below.
724 template <typename T>
725 class DenseArrayAttrImpl : public DenseArrayAttr {
726 public:
727  using DenseArrayAttr::DenseArrayAttr;
728 
729  /// Implicit conversion to ArrayRef<T>.
730  operator ArrayRef<T>() const;
731  ArrayRef<T> asArrayRef() const { return ArrayRef<T>{*this}; }
732 
733  /// Random access to elements.
734  T operator[](std::size_t index) const { return asArrayRef()[index]; }
735 
736  /// Builder from ArrayRef<T>.
737  static DenseArrayAttrImpl get(MLIRContext *context, ArrayRef<T> content);
738 
739  /// Print the short form `[42, 100, -1]` without any type prefix.
740  void print(AsmPrinter &printer) const;
741  void print(raw_ostream &os) const;
742  /// Print the short form `42, 100, -1` without any braces or type prefix.
743  void printWithoutBraces(raw_ostream &os) const;
744 
745  /// Parse the short form `[42, 100, -1]` without any type prefix.
746  static Attribute parse(AsmParser &parser, Type type);
747 
748  /// Parse the short form `42, 100, -1` without any type prefix or braces.
749  static Attribute parseWithoutBraces(AsmParser &parser, Type type);
750 
751  /// Support for isa<>/cast<>.
752  static bool classof(Attribute attr);
753 };
754 
755 extern template class DenseArrayAttrImpl<bool>;
756 extern template class DenseArrayAttrImpl<int8_t>;
757 extern template class DenseArrayAttrImpl<int16_t>;
758 extern template class DenseArrayAttrImpl<int32_t>;
759 extern template class DenseArrayAttrImpl<int64_t>;
760 extern template class DenseArrayAttrImpl<float>;
761 extern template class DenseArrayAttrImpl<double>;
762 } // namespace detail
763 
764 // Public name for all the supported DenseArrayAttr
772 
773 //===----------------------------------------------------------------------===//
774 // DenseResourceElementsAttr
775 
776 namespace detail {
777 /// Base class for DenseResourceElementsAttr that is instantiated and
778 /// specialized for each supported element type below.
779 template <typename T>
781 public:
782  using DenseResourceElementsAttr::DenseResourceElementsAttr;
783 
784  /// A builder that inserts a new resource using the provided blob. The handle
785  /// of the inserted blob is used when building the attribute. The provided
786  /// `blobName` is used as a hint for the key of the new handle for the `blob`
787  /// resource, but may be changed if necessary to ensure uniqueness during
788  /// insertion.
790  get(ShapedType type, StringRef blobName, AsmResourceBlob blob);
791 
792  /// Return the data of this attribute as an ArrayRef<T> if it is present,
793  /// returns std::nullopt otherwise.
794  std::optional<ArrayRef<T>> tryGetAsArrayRef() const;
795 
796  /// Support for isa<>/cast<>.
797  static bool classof(Attribute attr);
798 };
799 
800 extern template class DenseResourceElementsAttrBase<bool>;
801 extern template class DenseResourceElementsAttrBase<int8_t>;
802 extern template class DenseResourceElementsAttrBase<int16_t>;
803 extern template class DenseResourceElementsAttrBase<int32_t>;
804 extern template class DenseResourceElementsAttrBase<int64_t>;
805 extern template class DenseResourceElementsAttrBase<uint8_t>;
806 extern template class DenseResourceElementsAttrBase<uint16_t>;
807 extern template class DenseResourceElementsAttrBase<uint32_t>;
808 extern template class DenseResourceElementsAttrBase<uint64_t>;
809 extern template class DenseResourceElementsAttrBase<float>;
810 extern template class DenseResourceElementsAttrBase<double>;
811 } // namespace detail
812 
813 // Public names for all the supported DenseResourceElementsAttr.
814 
837 
838 //===----------------------------------------------------------------------===//
839 // BoolAttr
840 //===----------------------------------------------------------------------===//
841 
842 /// Special case of IntegerAttr to represent boolean integers, i.e., signless i1
843 /// integers.
844 class BoolAttr : public Attribute {
845 public:
846  using Attribute::Attribute;
847  using ValueType = bool;
848 
849  static BoolAttr get(MLIRContext *context, bool value);
850 
851  /// Enable conversion to IntegerAttr and its interfaces. This uses conversion
852  /// vs. inheritance to avoid bringing in all of IntegerAttrs methods.
853  operator IntegerAttr() const { return IntegerAttr(impl); }
854  operator TypedAttr() const { return IntegerAttr(impl); }
855 
856  /// Return the boolean value of this attribute.
857  bool getValue() const;
858 
859  /// Methods for support type inquiry through isa, cast, and dyn_cast.
860  static bool classof(Attribute attr);
861 };
862 
863 //===----------------------------------------------------------------------===//
864 // FlatSymbolRefAttr
865 //===----------------------------------------------------------------------===//
866 
867 /// A symbol reference with a reference path containing a single element. This
868 /// is used to refer to an operation within the current symbol table.
869 class FlatSymbolRefAttr : public SymbolRefAttr {
870 public:
871  using SymbolRefAttr::SymbolRefAttr;
872  using ValueType = StringRef;
873 
874  /// Construct a symbol reference for the given value name.
875  static FlatSymbolRefAttr get(StringAttr value) {
876  return SymbolRefAttr::get(value);
877  }
878  static FlatSymbolRefAttr get(MLIRContext *ctx, StringRef value) {
879  return SymbolRefAttr::get(ctx, value);
880  }
881 
882  /// Convenience getter for building a SymbolRefAttr based on an operation
883  /// that implements the SymbolTrait.
884  static FlatSymbolRefAttr get(Operation *symbol) {
885  return SymbolRefAttr::get(symbol);
886  }
887 
888  /// Returns the name of the held symbol reference as a StringAttr.
889  StringAttr getAttr() const { return getRootReference(); }
890 
891  /// Returns the name of the held symbol reference.
892  StringRef getValue() const { return getAttr().getValue(); }
893 
894  /// Methods for support type inquiry through isa, cast, and dyn_cast.
895  static bool classof(Attribute attr) {
896  SymbolRefAttr refAttr = llvm::dyn_cast<SymbolRefAttr>(attr);
897  return refAttr && refAttr.getNestedReferences().empty();
898  }
899 
900 private:
901  using SymbolRefAttr::get;
902  using SymbolRefAttr::getNestedReferences;
903 };
904 
905 //===----------------------------------------------------------------------===//
906 // DenseFPElementsAttr
907 //===----------------------------------------------------------------------===//
908 
909 /// An attribute that represents a reference to a dense float vector or tensor
910 /// object. Each element is stored as a double.
912 public:
914 
915  using DenseIntOrFPElementsAttr::DenseIntOrFPElementsAttr;
916 
917  /// Get an instance of a DenseFPElementsAttr with the given arguments. This
918  /// simply wraps the DenseElementsAttr::get calls.
919  template <typename Arg>
920  static DenseFPElementsAttr get(const ShapedType &type, Arg &&arg) {
921  return llvm::cast<DenseFPElementsAttr>(
923  }
924  template <typename T>
925  static DenseFPElementsAttr get(const ShapedType &type,
926  const std::initializer_list<T> &list) {
927  return llvm::cast<DenseFPElementsAttr>(DenseElementsAttr::get(type, list));
928  }
929 
930  /// Generates a new DenseElementsAttr by mapping each value attribute, and
931  /// constructing the DenseElementsAttr given the new element type.
933  mapValues(Type newElementType,
934  function_ref<APInt(const APFloat &)> mapping) const;
935 
936  /// Iterator access to the float element values.
937  iterator begin() const { return tryGetFloatValues()->begin(); }
938  iterator end() const { return tryGetFloatValues()->end(); }
939 
940  /// Method for supporting type inquiry through isa, cast and dyn_cast.
941  static bool classof(Attribute attr);
942 };
943 
944 //===----------------------------------------------------------------------===//
945 // DenseIntElementsAttr
946 //===----------------------------------------------------------------------===//
947 
948 /// An attribute that represents a reference to a dense integer vector or tensor
949 /// object.
951 public:
952  /// DenseIntElementsAttr iterates on APInt, so we can use the raw element
953  /// iterator directly.
955 
956  using DenseIntOrFPElementsAttr::DenseIntOrFPElementsAttr;
957 
958  /// Get an instance of a DenseIntElementsAttr with the given arguments. This
959  /// simply wraps the DenseElementsAttr::get calls.
960  template <typename Arg>
961  static DenseIntElementsAttr get(const ShapedType &type, Arg &&arg) {
962  return llvm::cast<DenseIntElementsAttr>(
964  }
965  template <typename T>
966  static DenseIntElementsAttr get(const ShapedType &type,
967  const std::initializer_list<T> &list) {
968  return llvm::cast<DenseIntElementsAttr>(DenseElementsAttr::get(type, list));
969  }
970 
971  /// Generates a new DenseElementsAttr by mapping each value attribute, and
972  /// constructing the DenseElementsAttr given the new element type.
973  DenseElementsAttr mapValues(Type newElementType,
974  function_ref<APInt(const APInt &)> mapping) const;
975 
976  /// Iterator access to the integer element values.
977  iterator begin() const { return raw_int_begin(); }
978  iterator end() const { return raw_int_end(); }
979 
980  /// Method for supporting type inquiry through isa, cast and dyn_cast.
981  static bool classof(Attribute attr);
982 };
983 
984 //===----------------------------------------------------------------------===//
985 // SparseElementsAttr
986 //===----------------------------------------------------------------------===//
987 
988 template <typename T>
989 auto SparseElementsAttr::try_value_begin_impl(OverloadToken<T>) const
990  -> FailureOr<iterator<T>> {
991  auto zeroValue = getZeroValue<T>();
992  auto valueIt = getValues().try_value_begin<T>();
993  if (failed(valueIt))
994  return failure();
995  const std::vector<ptrdiff_t> flatSparseIndices(getFlattenedSparseIndices());
996  std::function<T(ptrdiff_t)> mapFn =
997  [flatSparseIndices{flatSparseIndices}, valueIt{std::move(*valueIt)},
998  zeroValue{std::move(zeroValue)}](ptrdiff_t index) {
999  // Try to map the current index to one of the sparse indices.
1000  for (unsigned i = 0, e = flatSparseIndices.size(); i != e; ++i)
1001  if (flatSparseIndices[i] == index)
1002  return *std::next(valueIt, i);
1003  // Otherwise, return the zero value.
1004  return zeroValue;
1005  };
1006  return iterator<T>(llvm::seq<ptrdiff_t>(0, getNumElements()).begin(), mapFn);
1007 }
1008 
1009 //===----------------------------------------------------------------------===//
1010 // DistinctAttr
1011 //===----------------------------------------------------------------------===//
1012 
1013 namespace detail {
1014 struct DistinctAttrStorage;
1015 class DistinctAttributeUniquer;
1016 } // namespace detail
1017 
1018 /// An attribute that associates a referenced attribute with a unique
1019 /// identifier. Every call to the create function allocates a new distinct
1020 /// attribute instance. The address of the attribute instance serves as a
1021 /// temporary identifier. Similar to the names of SSA values, the final
1022 /// identifiers are generated during pretty printing. This delayed numbering
1023 /// ensures the printed identifiers are deterministic even if multiple distinct
1024 /// attribute instances are created in-parallel.
1025 ///
1026 /// Examples:
1027 ///
1028 /// #distinct = distinct[0]<42.0 : f32>
1029 /// #distinct1 = distinct[1]<42.0 : f32>
1030 /// #distinct2 = distinct[2]<array<i32: 10, 42>>
1031 ///
1032 /// NOTE: The distinct attribute cannot be defined using ODS since it uses a
1033 /// custom distinct attribute uniquer that cannot be set from ODS.
1035  : public detail::StorageUserBase<DistinctAttr, Attribute,
1036  detail::DistinctAttrStorage,
1037  detail::DistinctAttributeUniquer> {
1038 public:
1039  using Base::Base;
1040 
1041  /// Returns the referenced attribute.
1042  Attribute getReferencedAttr() const;
1043 
1044  /// Creates a distinct attribute that associates a referenced attribute with a
1045  /// unique identifier.
1046  static DistinctAttr create(Attribute referencedAttr);
1047 
1048  static constexpr StringLiteral name = "builtin.distinct";
1049 };
1050 
1051 //===----------------------------------------------------------------------===//
1052 // StringAttr
1053 //===----------------------------------------------------------------------===//
1054 
1055 /// Define comparisons for StringAttr against nullptr and itself to avoid the
1056 /// StringRef overloads from being chosen when not desirable.
1057 inline bool operator==(StringAttr lhs, std::nullptr_t) { return !lhs; }
1058 inline bool operator!=(StringAttr lhs, std::nullptr_t) {
1059  return static_cast<bool>(lhs);
1060 }
1061 inline bool operator==(StringAttr lhs, StringAttr rhs) {
1062  return (Attribute)lhs == (Attribute)rhs;
1063 }
1064 inline bool operator!=(StringAttr lhs, StringAttr rhs) { return !(lhs == rhs); }
1065 
1066 /// Allow direct comparison with StringRef.
1067 inline bool operator==(StringAttr lhs, StringRef rhs) {
1068  return lhs.getValue() == rhs;
1069 }
1070 inline bool operator!=(StringAttr lhs, StringRef rhs) { return !(lhs == rhs); }
1071 inline bool operator==(StringRef lhs, StringAttr rhs) {
1072  return rhs.getValue() == lhs;
1073 }
1074 inline bool operator!=(StringRef lhs, StringAttr rhs) { return !(lhs == rhs); }
1075 
1076 } // namespace mlir
1077 
1078 //===----------------------------------------------------------------------===//
1079 // Attribute Utilities
1080 //===----------------------------------------------------------------------===//
1081 
1082 namespace mlir {
1083 
1084 /// Given a list of strides (in which ShapedType::kDynamic
1085 /// represents a dynamic value), return the single result AffineMap which
1086 /// represents the linearized strided layout map. Dimensions correspond to the
1087 /// offset followed by the strides in order. Symbols are inserted for each
1088 /// dynamic dimension in order. A stride is always positive.
1089 ///
1090 /// Examples:
1091 /// =========
1092 ///
1093 /// 1. For offset: 0 strides: ?, ?, 1 return
1094 /// (i, j, k)[M, N]->(M * i + N * j + k)
1095 ///
1096 /// 2. For offset: 3 strides: 32, ?, 16 return
1097 /// (i, j, k)[M]->(3 + 32 * i + M * j + 16 * k)
1098 ///
1099 /// 3. For offset: ? strides: ?, ?, ? return
1100 /// (i, j, k)[off, M, N, P]->(off + M * i + N * j + P * k)
1101 AffineMap makeStridedLinearLayoutMap(ArrayRef<int64_t> strides, int64_t offset,
1102  MLIRContext *context);
1103 
1104 } // namespace mlir
1105 
1106 namespace llvm {
1107 
1108 template <>
1109 struct DenseMapInfo<mlir::StringAttr> : public DenseMapInfo<mlir::Attribute> {
1110  static mlir::StringAttr getEmptyKey() {
1111  const void *pointer = llvm::DenseMapInfo<const void *>::getEmptyKey();
1112  return mlir::StringAttr::getFromOpaquePointer(pointer);
1113  }
1114  static mlir::StringAttr getTombstoneKey() {
1115  const void *pointer = llvm::DenseMapInfo<const void *>::getTombstoneKey();
1116  return mlir::StringAttr::getFromOpaquePointer(pointer);
1117  }
1118 };
1119 template <>
1120 struct PointerLikeTypeTraits<mlir::StringAttr>
1121  : public PointerLikeTypeTraits<mlir::Attribute> {
1122  static inline mlir::StringAttr getFromVoidPointer(void *p) {
1123  return mlir::StringAttr::getFromOpaquePointer(p);
1124  }
1125 };
1126 
1127 template <>
1128 struct PointerLikeTypeTraits<mlir::IntegerAttr>
1129  : public PointerLikeTypeTraits<mlir::Attribute> {
1130  static inline mlir::IntegerAttr getFromVoidPointer(void *p) {
1131  return mlir::IntegerAttr::getFromOpaquePointer(p);
1132  }
1133 };
1134 
1135 template <>
1136 struct PointerLikeTypeTraits<mlir::SymbolRefAttr>
1137  : public PointerLikeTypeTraits<mlir::Attribute> {
1138  static inline mlir::SymbolRefAttr getFromVoidPointer(void *ptr) {
1139  return mlir::SymbolRefAttr::getFromOpaquePointer(ptr);
1140  }
1141 };
1142 
1143 } // namespace llvm
1144 
1145 #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:90
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:66
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.