My Project
Attributes.h
Go to the documentation of this file.
1 //===- Attributes.h - MLIR Attribute Classes --------------------*- C++ -*-===//
2 //
3 // Part of the MLIR Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef MLIR_IR_ATTRIBUTES_H
10 #define MLIR_IR_ATTRIBUTES_H
11 
13 #include "llvm/ADT/APFloat.h"
14 #include "llvm/ADT/Sequence.h"
15 
16 namespace mlir {
17 class AffineMap;
18 class Dialect;
19 class FunctionType;
20 class Identifier;
21 class IntegerSet;
22 class Location;
23 class MLIRContext;
24 class ShapedType;
25 class Type;
26 
27 namespace detail {
28 
29 struct AffineMapAttributeStorage;
30 struct ArrayAttributeStorage;
31 struct BoolAttributeStorage;
32 struct DictionaryAttributeStorage;
33 struct IntegerAttributeStorage;
34 struct IntegerSetAttributeStorage;
35 struct FloatAttributeStorage;
36 struct OpaqueAttributeStorage;
37 struct StringAttributeStorage;
38 struct SymbolRefAttributeStorage;
39 struct TypeAttributeStorage;
40 
42 struct DenseElementsAttributeStorage;
43 struct OpaqueElementsAttributeStorage;
44 struct SparseElementsAttributeStorage;
45 } // namespace detail
46 
53 class Attribute {
54 public:
56  enum Kind {
57  // Reserve attribute kinds for dialect specific extensions.
58 #define DEFINE_SYM_KIND_RANGE(Dialect) \
59  FIRST_##Dialect##_ATTR, LAST_##Dialect##_ATTR = FIRST_##Dialect##_ATTR + 0xff,
60 #include "DialectSymbolRegistry.def"
61  };
62 
64  template <typename ConcreteType, typename BaseType = Attribute,
65  typename StorageType = AttributeStorage>
66  using AttrBase = detail::StorageUserBase<ConcreteType, BaseType, StorageType,
68 
70  using ValueType = void;
71 
72  Attribute() : impl(nullptr) {}
73  /* implicit */ Attribute(const ImplType *impl)
74  : impl(const_cast<ImplType *>(impl)) {}
75 
76  Attribute(const Attribute &other) = default;
77  Attribute &operator=(const Attribute &other) = default;
78 
79  bool operator==(Attribute other) const { return impl == other.impl; }
80  bool operator!=(Attribute other) const { return !(*this == other); }
81  explicit operator bool() const { return impl; }
82 
83  bool operator!() const { return impl == nullptr; }
84 
85  template <typename U> bool isa() const;
86  template <typename U> U dyn_cast() const;
87  template <typename U> U dyn_cast_or_null() const;
88  template <typename U> U cast() const;
89 
90  // Support dyn_cast'ing Attribute to itself.
91  static bool classof(Attribute) { return true; }
92 
94  unsigned getKind() const { return impl->getKind(); }
95 
97  Type getType() const;
98 
100  MLIRContext *getContext() const;
101 
103  Dialect &getDialect() const;
104 
106  void print(raw_ostream &os) const;
107  void dump() const;
108 
110  const void *getAsOpaquePointer() const { return impl; }
112  static Attribute getFromOpaquePointer(const void *ptr) {
113  return Attribute(reinterpret_cast<const ImplType *>(ptr));
114  }
115 
116  friend ::llvm::hash_code hash_value(Attribute arg);
117 
118 protected:
120 };
121 
122 inline raw_ostream &operator<<(raw_ostream &os, Attribute attr) {
123  attr.print(os);
124  return os;
125 }
126 
127 namespace StandardAttributes {
128 enum Kind {
129  AffineMap = Attribute::FIRST_STANDARD_ATTR,
141 
148 
156 
157  // Represents a location as a 'void*' pointer to a front-end's opaque
158  // location information, which must live longer than the MLIR objects that
159  // refer to it. OpaqueLocation's are never serialized.
160  //
161  // TODO: OpaqueLocation,
162 
163  // Represents a value inlined through a function call.
164  // TODO: InlinedLocation,
165 
168 };
169 } // namespace StandardAttributes
170 
171 //===----------------------------------------------------------------------===//
172 // AffineMapAttr
173 //===----------------------------------------------------------------------===//
174 
176  : public Attribute::AttrBase<AffineMapAttr, Attribute,
177  detail::AffineMapAttributeStorage> {
178 public:
179  using Base::Base;
181 
182  static AffineMapAttr get(AffineMap value);
183 
184  AffineMap getValue() const;
185 
187  static bool kindof(unsigned kind) {
188  return kind == StandardAttributes::AffineMap;
189  }
190 };
191 
192 //===----------------------------------------------------------------------===//
193 // ArrayAttr
194 //===----------------------------------------------------------------------===//
195 
198 class ArrayAttr : public Attribute::AttrBase<ArrayAttr, Attribute,
199  detail::ArrayAttributeStorage> {
200 public:
201  using Base::Base;
203 
204  static ArrayAttr get(ArrayRef<Attribute> value, MLIRContext *context);
205 
206  ArrayRef<Attribute> getValue() const;
207 
210  iterator begin() const { return getValue().begin(); }
211  iterator end() const { return getValue().end(); }
212  size_t size() const { return getValue().size(); }
213 
215  static bool kindof(unsigned kind) {
216  return kind == StandardAttributes::Array;
217  }
218 
219 private:
221  template <typename AttrTy>
222  class attr_value_iterator final
223  : public llvm::mapped_iterator<iterator, AttrTy (*)(Attribute)> {
224  public:
225  explicit attr_value_iterator(iterator it)
226  : llvm::mapped_iterator<iterator, AttrTy (*)(Attribute)>(
227  it, [](Attribute attr) { return attr.cast<AttrTy>(); }) {}
228  AttrTy operator*() { return (*this->I).template cast<AttrTy>(); }
229  };
230 
231 public:
232  template <typename AttrTy>
234  return llvm::make_range(attr_value_iterator<AttrTy>(begin()),
235  attr_value_iterator<AttrTy>(end()));
236  }
237 };
238 
239 //===----------------------------------------------------------------------===//
240 // BoolAttr
241 //===----------------------------------------------------------------------===//
242 
243 class BoolAttr : public Attribute::AttrBase<BoolAttr, Attribute,
244  detail::BoolAttributeStorage> {
245 public:
246  using Base::Base;
247  using ValueType = bool;
248 
249  static BoolAttr get(bool value, MLIRContext *context);
250 
251  bool getValue() const;
252 
254  static bool kindof(unsigned kind) { return kind == StandardAttributes::Bool; }
255 };
256 
257 //===----------------------------------------------------------------------===//
258 // DictionaryAttr
259 //===----------------------------------------------------------------------===//
260 
264 using NamedAttribute = std::pair<Identifier, Attribute>;
265 
270  : public Attribute::AttrBase<DictionaryAttr, Attribute,
271  detail::DictionaryAttributeStorage> {
272 public:
273  using Base::Base;
275 
276  static DictionaryAttr get(ArrayRef<NamedAttribute> value,
277  MLIRContext *context);
278 
279  ArrayRef<NamedAttribute> getValue() const;
280 
282  Attribute get(StringRef name) const;
283  Attribute get(Identifier name) const;
284 
287  iterator begin() const;
288  iterator end() const;
289  bool empty() const { return size() == 0; }
290  size_t size() const;
291 
293  static bool kindof(unsigned kind) {
294  return kind == StandardAttributes::Dictionary;
295  }
296 };
297 
298 //===----------------------------------------------------------------------===//
299 // FloatAttr
300 //===----------------------------------------------------------------------===//
301 
302 class FloatAttr : public Attribute::AttrBase<FloatAttr, Attribute,
303  detail::FloatAttributeStorage> {
304 public:
305  using Base::Base;
306  using ValueType = APFloat;
307 
311  static FloatAttr get(Type type, double value);
312  static FloatAttr getChecked(Type type, double value, Location loc);
313 
315  static FloatAttr get(Type type, const APFloat &value);
316  static FloatAttr getChecked(Type type, const APFloat &value, Location loc);
317 
318  APFloat getValue() const;
319 
322  double getValueAsDouble() const;
323  static double getValueAsDouble(APFloat val);
324 
326  static bool kindof(unsigned kind) {
327  return kind == StandardAttributes::Float;
328  }
329 
331  static LogicalResult verifyConstructionInvariants(Optional<Location> loc,
332  MLIRContext *ctx, Type type,
333  double value);
334  static LogicalResult verifyConstructionInvariants(Optional<Location> loc,
335  MLIRContext *ctx, Type type,
336  const APFloat &value);
337 };
338 
339 //===----------------------------------------------------------------------===//
340 // IntegerAttr
341 //===----------------------------------------------------------------------===//
342 
344  : public Attribute::AttrBase<IntegerAttr, Attribute,
345  detail::IntegerAttributeStorage> {
346 public:
347  using Base::Base;
348  using ValueType = APInt;
349 
350  static IntegerAttr get(Type type, int64_t value);
351  static IntegerAttr get(Type type, const APInt &value);
352 
353  APInt getValue() const;
354  // TODO(jpienaar): Change callers to use getValue instead.
355  int64_t getInt() const;
356 
358  static bool kindof(unsigned kind) {
359  return kind == StandardAttributes::Integer;
360  }
361 };
362 
363 //===----------------------------------------------------------------------===//
364 // IntegerSetAttr
365 //===----------------------------------------------------------------------===//
366 
368  : public Attribute::AttrBase<IntegerSetAttr, Attribute,
369  detail::IntegerSetAttributeStorage> {
370 public:
371  using Base::Base;
373 
374  static IntegerSetAttr get(IntegerSet value);
375 
376  IntegerSet getValue() const;
377 
379  static bool kindof(unsigned kind) {
380  return kind == StandardAttributes::IntegerSet;
381  }
382 };
383 
384 //===----------------------------------------------------------------------===//
385 // OpaqueAttr
386 //===----------------------------------------------------------------------===//
387 
391 class OpaqueAttr : public Attribute::AttrBase<OpaqueAttr, Attribute,
392  detail::OpaqueAttributeStorage> {
393 public:
394  using Base::Base;
395 
397  static OpaqueAttr get(Identifier dialect, StringRef attrData, Type type,
398  MLIRContext *context);
399 
403  static OpaqueAttr getChecked(Identifier dialect, StringRef attrData,
404  Type type, Location location);
405 
407  Identifier getDialectNamespace() const;
408 
410  StringRef getAttrData() const;
411 
413  static LogicalResult verifyConstructionInvariants(Optional<Location> loc,
414  MLIRContext *context,
415  Identifier dialect,
416  StringRef attrData,
417  Type type);
418 
419  static bool kindof(unsigned kind) {
420  return kind == StandardAttributes::Opaque;
421  }
422 };
423 
424 //===----------------------------------------------------------------------===//
425 // StringAttr
426 //===----------------------------------------------------------------------===//
427 
428 class StringAttr : public Attribute::AttrBase<StringAttr, Attribute,
429  detail::StringAttributeStorage> {
430 public:
431  using Base::Base;
432  using ValueType = StringRef;
433 
435  static StringAttr get(StringRef bytes, MLIRContext *context);
436 
438  static StringAttr get(StringRef bytes, Type type);
439 
440  StringRef getValue() const;
441 
443  static bool kindof(unsigned kind) {
444  return kind == StandardAttributes::String;
445  }
446 };
447 
448 //===----------------------------------------------------------------------===//
449 // SymbolRefAttr
450 //===----------------------------------------------------------------------===//
451 
452 class FlatSymbolRefAttr;
453 
457  : public Attribute::AttrBase<SymbolRefAttr, Attribute,
458  detail::SymbolRefAttributeStorage> {
459 public:
460  using Base::Base;
461 
463  static FlatSymbolRefAttr get(StringRef value, MLIRContext *ctx);
464 
467  static SymbolRefAttr get(StringRef value,
468  ArrayRef<FlatSymbolRefAttr> references,
469  MLIRContext *ctx);
470 
473  StringRef getRootReference() const;
474 
477  StringRef getLeafReference() const;
478 
481  ArrayRef<FlatSymbolRefAttr> getNestedReferences() const;
482 
484  static bool kindof(unsigned kind) {
485  return kind == StandardAttributes::SymbolRef;
486  }
487 };
488 
492 public:
493  using SymbolRefAttr::SymbolRefAttr;
494  using ValueType = StringRef;
495 
497  static FlatSymbolRefAttr get(StringRef value, MLIRContext *ctx) {
498  return SymbolRefAttr::get(value, ctx);
499  }
500 
502  StringRef getValue() const { return getRootReference(); }
503 
505  static bool classof(Attribute attr) {
506  SymbolRefAttr refAttr = attr.dyn_cast<SymbolRefAttr>();
507  return refAttr && refAttr.getNestedReferences().empty();
508  }
509 
510 private:
511  using SymbolRefAttr::get;
513 };
514 
515 //===----------------------------------------------------------------------===//
516 // Type
517 //===----------------------------------------------------------------------===//
518 
519 class TypeAttr : public Attribute::AttrBase<TypeAttr, Attribute,
520  detail::TypeAttributeStorage> {
521 public:
522  using Base::Base;
523  using ValueType = Type;
524 
525  static TypeAttr get(Type value);
526 
527  Type getValue() const;
528 
530  static bool kindof(unsigned kind) { return kind == StandardAttributes::Type; }
531 };
532 
533 //===----------------------------------------------------------------------===//
534 // UnitAttr
535 //===----------------------------------------------------------------------===//
536 
539 class UnitAttr : public Attribute::AttrBase<UnitAttr> {
540 public:
541  using Base::Base;
542 
543  static UnitAttr get(MLIRContext *context);
544 
545  static bool kindof(unsigned kind) { return kind == StandardAttributes::Unit; }
546 };
547 
548 //===----------------------------------------------------------------------===//
549 // Elements Attributes
550 //===----------------------------------------------------------------------===//
551 
552 namespace detail {
553 template <typename T> class ElementsAttrIterator;
554 template <typename T> class ElementsAttrRange;
555 } // namespace detail
556 
559 class ElementsAttr : public Attribute {
560 public:
561  using Attribute::Attribute;
562  template <typename T> using iterator = detail::ElementsAttrIterator<T>;
563  template <typename T> using iterator_range = detail::ElementsAttrRange<T>;
564 
567  ShapedType getType() const;
568 
571  Attribute getValue(ArrayRef<uint64_t> index) const;
572 
575  template <typename T> T getValue(ArrayRef<uint64_t> index) const {
576  return getValue(index).template cast<T>();
577  }
578 
582  template <typename T> iterator_range<T> getValues() const;
583 
585  bool isValidIndex(ArrayRef<uint64_t> index) const;
586 
588  int64_t getNumElements() const;
589 
593  ElementsAttr mapValues(Type newElementType,
594  function_ref<APInt(const APInt &)> mapping) const;
595 
599  ElementsAttr mapValues(Type newElementType,
600  function_ref<APInt(const APFloat &)> mapping) const;
601 
603  static bool classof(Attribute attr) {
606  }
607 
608 protected:
611  uint64_t getFlattenedIndex(ArrayRef<uint64_t> index) const;
612 };
613 
614 namespace detail {
618 public:
619  static inline const void *getAsVoidPointer(const char *ptr) { return ptr; }
620  static inline const char *getFromVoidPointer(const void *ptr) {
621  return static_cast<const char *>(ptr);
622  }
623 
624  // Note: We could steal more bits if the need arises.
625  enum { NumLowBitsAvailable = 1 };
626 };
627 
629 using DenseIterPtrAndSplat =
630  llvm::PointerIntPair<const char *, 1, bool,
632 
635 template <typename ConcreteT, typename T, typename PointerT = T *,
636  typename ReferenceT = T &>
638  : public indexed_accessor_iterator<ConcreteT, DenseIterPtrAndSplat, T,
639  PointerT, ReferenceT> {
640 protected:
641  DenseElementIndexedIteratorImpl(const char *data, bool isSplat,
642  size_t dataIndex)
643  : indexed_accessor_iterator<ConcreteT, DenseIterPtrAndSplat, T, PointerT,
644  ReferenceT>({data, isSplat}, dataIndex) {}
645 
648  ptrdiff_t getDataIndex() const {
649  bool isSplat = this->base.getInt();
650  return isSplat ? 0 : this->index;
651  }
652 
654  const char *getData() const { return this->base.getPointer(); }
655 };
656 } // namespace detail
657 
661  : public Attribute::AttrBase<DenseElementsAttr, ElementsAttr,
662  detail::DenseElementsAttributeStorage> {
663 public:
664  using Base::Base;
665 
667  static bool classof(Attribute attr) {
669  }
670 
674  static DenseElementsAttr get(ShapedType type, ArrayRef<Attribute> values);
675 
680  template <typename T, typename = typename std::enable_if<
681  std::numeric_limits<T>::is_integer ||
682  llvm::is_one_of<T, float, double>::value>::type>
683  static DenseElementsAttr get(const ShapedType &type, ArrayRef<T> values) {
684  const char *data = reinterpret_cast<const char *>(values.data());
685  return getRawIntOrFloat(
686  type, ArrayRef<char>(data, values.size() * sizeof(T)), sizeof(T),
687  /*isInt=*/std::numeric_limits<T>::is_integer);
688  }
689 
691  template <typename T, typename = typename std::enable_if<
692  std::numeric_limits<T>::is_integer ||
693  llvm::is_one_of<T, float, double>::value>::type>
694  static DenseElementsAttr get(const ShapedType &type, T value) {
695  return get(type, llvm::makeArrayRef(value));
696  }
697 
699  static DenseElementsAttr get(ShapedType type, ArrayRef<bool> values);
700 
705  static DenseElementsAttr get(ShapedType type, ArrayRef<APInt> values);
706 
711  static DenseElementsAttr get(ShapedType type, ArrayRef<APFloat> values);
712 
716  template <typename T>
717  static DenseElementsAttr get(const ShapedType &type,
718  const std::initializer_list<T> &list) {
719  return get(type, ArrayRef<T>(list));
720  }
721 
722  //===--------------------------------------------------------------------===//
723  // Iterators
724  //===--------------------------------------------------------------------===//
725 
729  : public indexed_accessor_iterator<AttributeElementIterator, const void *,
730  Attribute, Attribute, Attribute> {
731  public:
733  Attribute operator*() const;
734 
735  private:
736  friend DenseElementsAttr;
737 
739  AttributeElementIterator(DenseElementsAttr attr, size_t index);
740  };
741 
745  template <typename T>
747  : public detail::DenseElementIndexedIteratorImpl<ElementIterator<T>,
748  const T> {
749  public:
751  const T &operator*() const {
752  return reinterpret_cast<const T *>(this->getData())[this->getDataIndex()];
753  }
754 
755  private:
756  friend DenseElementsAttr;
757 
759  ElementIterator(const char *data, bool isSplat, size_t dataIndex)
761  data, isSplat, dataIndex) {}
762  };
763 
766  : public detail::DenseElementIndexedIteratorImpl<BoolElementIterator,
767  bool, bool, bool> {
768  public:
770  bool operator*() const;
771 
772  private:
773  friend DenseElementsAttr;
774 
776  BoolElementIterator(DenseElementsAttr attr, size_t dataIndex);
777  };
778 
781  : public detail::DenseElementIndexedIteratorImpl<IntElementIterator,
782  APInt, APInt, APInt> {
783  public:
785  APInt operator*() const;
786 
787  private:
788  friend DenseElementsAttr;
789 
791  IntElementIterator(DenseElementsAttr attr, size_t dataIndex);
792 
794  size_t bitWidth;
795  };
796 
799  : public llvm::mapped_iterator<IntElementIterator,
800  std::function<APFloat(const APInt &)>> {
801  friend DenseElementsAttr;
802 
804  FloatElementIterator(const llvm::fltSemantics &smt, IntElementIterator it);
805 
806  public:
807  using reference = APFloat;
808  };
809 
810  //===--------------------------------------------------------------------===//
811  // Value Querying
812  //===--------------------------------------------------------------------===//
813 
816  bool isSplat() const;
817 
820  Attribute getSplatValue() const { return getSplatValue<Attribute>(); }
821  template <typename T>
822  typename std::enable_if<!std::is_base_of<Attribute, T>::value ||
823  std::is_same<Attribute, T>::value,
824  T>::type
825  getSplatValue() const {
826  assert(isSplat() && "expected the attribute to be a splat");
827  return *getValues<T>().begin();
828  }
830  template <typename T>
831  typename std::enable_if<std::is_base_of<Attribute, T>::value &&
832  !std::is_same<Attribute, T>::value,
833  T>::type
834  getSplatValue() const {
835  return getSplatValue().template cast<T>();
836  }
837 
841  return getValue<Attribute>(index);
842  }
843  template <typename T> T getValue(ArrayRef<uint64_t> index) const {
844  // Skip to the element corresponding to the flattened index.
845  return *std::next(getValues<T>().begin(), getFlattenedIndex(index));
846  }
847 
850  template <typename T, typename = typename std::enable_if<
851  (!std::is_same<T, bool>::value &&
852  std::numeric_limits<T>::is_integer) ||
853  llvm::is_one_of<T, float, double>::value>::type>
855  assert(isValidIntOrFloat(sizeof(T), std::numeric_limits<T>::is_integer));
856  auto rawData = getRawData().data();
857  bool splat = isSplat();
858  return {ElementIterator<T>(rawData, splat, 0),
859  ElementIterator<T>(rawData, splat, getNumElements())};
860  }
861 
863  llvm::iterator_range<AttributeElementIterator> getAttributeValues() const;
864  template <typename T, typename = typename std::enable_if<
865  std::is_same<T, Attribute>::value>::type>
867  return getAttributeValues();
868  }
869  AttributeElementIterator attr_value_begin() const;
870  AttributeElementIterator attr_value_end() const;
871 
874  template <typename T>
876  llvm::mapped_iterator<AttributeElementIterator, T (*)(Attribute)>;
877  template <typename T, typename = typename std::enable_if<
878  std::is_base_of<Attribute, T>::value &&
879  !std::is_same<Attribute, T>::value>::type>
881  auto castFn = [](Attribute attr) { return attr.template cast<T>(); };
882  return llvm::map_range(getAttributeValues(),
883  static_cast<T (*)(Attribute)>(castFn));
884  }
885 
888  llvm::iterator_range<BoolElementIterator> getBoolValues() const;
889  template <typename T, typename = typename std::enable_if<
890  std::is_same<T, bool>::value>::type>
892  return getBoolValues();
893  }
894 
897  llvm::iterator_range<IntElementIterator> getIntValues() const;
898  template <typename T, typename = typename std::enable_if<
899  std::is_same<T, APInt>::value>::type>
901  return getIntValues();
902  }
903  IntElementIterator int_value_begin() const;
904  IntElementIterator int_value_end() const;
905 
908  llvm::iterator_range<FloatElementIterator> getFloatValues() const;
909  template <typename T, typename = typename std::enable_if<
910  std::is_same<T, APFloat>::value>::type>
912  return getFloatValues();
913  }
914  FloatElementIterator float_value_begin() const;
915  FloatElementIterator float_value_end() const;
916 
917  //===--------------------------------------------------------------------===//
918  // Mutation Utilities
919  //===--------------------------------------------------------------------===//
920 
924  DenseElementsAttr reshape(ShapedType newType);
925 
929  DenseElementsAttr mapValues(Type newElementType,
930  function_ref<APInt(const APInt &)> mapping) const;
931 
936  mapValues(Type newElementType,
937  function_ref<APInt(const APFloat &)> mapping) const;
938 
939 protected:
941  ArrayRef<char> getRawData() const;
942 
945  return IntElementIterator(*this, 0);
946  }
948  return IntElementIterator(*this, getNumElements());
949  }
950 
954  static DenseElementsAttr getRaw(ShapedType type, ArrayRef<APInt> values);
955 
958  static DenseElementsAttr getRaw(ShapedType type, ArrayRef<char> data,
959  bool isSplat);
960 
964  static DenseElementsAttr getRawIntOrFloat(ShapedType type,
965  ArrayRef<char> data,
966  int64_t dataEltSize, bool isInt);
967 
971  bool isValidIntOrFloat(int64_t dataEltSize, bool isInt) const;
972 };
973 
977 public:
979 
980  using DenseElementsAttr::DenseElementsAttr;
981 
984  template <typename Arg>
985  static DenseFPElementsAttr get(const ShapedType &type, Arg &&arg) {
986  return DenseElementsAttr::get(type, llvm::makeArrayRef(arg))
987  .template cast<DenseFPElementsAttr>();
988  }
989  template <typename T>
990  static DenseFPElementsAttr get(const ShapedType &type,
991  const std::initializer_list<T> &list) {
992  return DenseElementsAttr::get(type, list)
993  .template cast<DenseFPElementsAttr>();
994  }
995 
999  mapValues(Type newElementType,
1000  function_ref<APInt(const APFloat &)> mapping) const;
1001 
1003  iterator begin() const { return float_value_begin(); }
1004  iterator end() const { return float_value_end(); }
1005 
1007  static bool classof(Attribute attr);
1008 };
1009 
1013 public:
1017 
1018  using DenseElementsAttr::DenseElementsAttr;
1019 
1022  template <typename Arg>
1023  static DenseIntElementsAttr get(const ShapedType &type, Arg &&arg) {
1024  return DenseElementsAttr::get(type, llvm::makeArrayRef(arg))
1025  .template cast<DenseIntElementsAttr>();
1026  }
1027  template <typename T>
1028  static DenseIntElementsAttr get(const ShapedType &type,
1029  const std::initializer_list<T> &list) {
1030  return DenseElementsAttr::get(type, list)
1031  .template cast<DenseIntElementsAttr>();
1032  }
1033 
1036  DenseElementsAttr mapValues(Type newElementType,
1037  function_ref<APInt(const APInt &)> mapping) const;
1038 
1040  iterator begin() const { return raw_int_begin(); }
1041  iterator end() const { return raw_int_end(); }
1042 
1044  static bool classof(Attribute attr);
1045 };
1046 
1053  : public Attribute::AttrBase<OpaqueElementsAttr, ElementsAttr,
1054  detail::OpaqueElementsAttributeStorage> {
1055 public:
1056  using Base::Base;
1057  using ValueType = StringRef;
1058 
1059  static OpaqueElementsAttr get(Dialect *dialect, ShapedType type,
1060  StringRef bytes);
1061 
1062  StringRef getValue() const;
1063 
1066  Attribute getValue(ArrayRef<uint64_t> index) const;
1067 
1071  bool decode(ElementsAttr &result);
1072 
1074  Dialect *getDialect() const;
1075 
1077  static bool kindof(unsigned kind) {
1078  return kind == StandardAttributes::OpaqueElements;
1079  }
1080 };
1081 
1101  : public Attribute::AttrBase<SparseElementsAttr, ElementsAttr,
1102  detail::SparseElementsAttributeStorage> {
1103 public:
1104  using Base::Base;
1105 
1106  template <typename T>
1107  using iterator =
1108  llvm::mapped_iterator<llvm::detail::value_sequence_iterator<ptrdiff_t>,
1109  std::function<T(ptrdiff_t)>>;
1110 
1112  static SparseElementsAttr get(ShapedType type, DenseElementsAttr indices,
1113  DenseElementsAttr values);
1114 
1115  DenseIntElementsAttr getIndices() const;
1116 
1117  DenseElementsAttr getValues() const;
1118 
1121  template <typename T> llvm::iterator_range<iterator<T>> getValues() const {
1122  auto zeroValue = getZeroValue<T>();
1123  auto valueIt = getValues().getValues<T>().begin();
1124  const std::vector<ptrdiff_t> flatSparseIndices(getFlattenedSparseIndices());
1125  // TODO(riverriddle): Move-capture flatSparseIndices when c++14 is
1126  // available.
1127  std::function<T(ptrdiff_t)> mapFn = [=](ptrdiff_t index) {
1128  // Try to map the current index to one of the sparse indices.
1129  for (unsigned i = 0, e = flatSparseIndices.size(); i != e; ++i)
1130  if (flatSparseIndices[i] == index)
1131  return *std::next(valueIt, i);
1132  // Otherwise, return the zero value.
1133  return zeroValue;
1134  };
1135  return llvm::map_range(llvm::seq<ptrdiff_t>(0, getNumElements()), mapFn);
1136  }
1137 
1140  Attribute getValue(ArrayRef<uint64_t> index) const;
1141 
1143  static bool kindof(unsigned kind) {
1144  return kind == StandardAttributes::SparseElements;
1145  }
1146 
1147 private:
1149  APFloat getZeroAPFloat() const;
1150 
1152  APInt getZeroAPInt() const;
1153 
1155  Attribute getZeroAttr() const;
1156 
1160  template <typename T>
1161  typename std::enable_if<std::is_base_of<Attribute, T>::value, T>::type
1162  getZeroValue() const {
1163  return getZeroAttr().template cast<T>();
1164  }
1166  template <typename T>
1167  typename std::enable_if<std::is_same<APInt, T>::value, T>::type
1168  getZeroValue() const {
1169  return getZeroAPInt();
1170  }
1172  template <typename T>
1173  typename std::enable_if<std::is_same<APFloat, T>::value, T>::type
1174  getZeroValue() const {
1175  return getZeroAPFloat();
1176  }
1178  template <typename T>
1179  typename std::enable_if<std::numeric_limits<T>::is_integer ||
1180  llvm::is_one_of<T, float, double>::value,
1181  T>::type
1182  getZeroValue() const {
1183  return T(0);
1184  }
1185 
1188  std::vector<ptrdiff_t> getFlattenedSparseIndices() const;
1189 };
1190 
1194 public:
1195  using DenseElementsAttr::DenseElementsAttr;
1196 
1198  static bool classof(Attribute attr) {
1199  auto denseAttr = attr.dyn_cast<DenseElementsAttr>();
1200  return denseAttr && denseAttr.isSplat();
1201  }
1202 };
1203 
1204 namespace detail {
1207 template <typename T>
1208 class ElementsAttrIterator
1209  : public llvm::iterator_facade_base<ElementsAttrIterator<T>,
1210  std::random_access_iterator_tag, T,
1211  std::ptrdiff_t, T, T> {
1212  // NOTE: We use a dummy enable_if here because MSVC cannot use 'decltype'
1213  // inside of a conversion operator.
1214  using DenseIteratorT = typename std::enable_if<
1215  true,
1216  decltype(std::declval<DenseElementsAttr>().getValues<T>().begin())>::type;
1217  using SparseIteratorT = SparseElementsAttr::iterator<T>;
1218 
1220  union Iterator {
1221  Iterator(DenseIteratorT &&it) : denseIt(std::move(it)) {}
1222  Iterator(SparseIteratorT &&it) : sparseIt(std::move(it)) {}
1223  Iterator() {}
1224  ~Iterator() {}
1225 
1226  operator const DenseIteratorT &() const { return denseIt; }
1227  operator const SparseIteratorT &() const { return sparseIt; }
1228  operator DenseIteratorT &() { return denseIt; }
1229  operator SparseIteratorT &() { return sparseIt; }
1230 
1232  DenseIteratorT denseIt;
1234  SparseIteratorT sparseIt;
1235  };
1236 
1239  template <typename RetT, template <typename> class ProcessFn,
1240  typename... Args>
1241  RetT process(Args &... args) const {
1242  switch (attrKind) {
1244  return ProcessFn<DenseIteratorT>()(args...);
1246  return ProcessFn<SparseIteratorT>()(args...);
1247  }
1248  llvm_unreachable("unexpected attribute kind");
1249  }
1250 
1252  template <typename ItT> struct PlusAssign {
1253  void operator()(ItT &it, ptrdiff_t offset) { it += offset; }
1254  };
1255  template <typename ItT> struct Minus {
1256  ptrdiff_t operator()(const ItT &lhs, const ItT &rhs) { return lhs - rhs; }
1257  };
1258  template <typename ItT> struct MinusAssign {
1259  void operator()(ItT &it, ptrdiff_t offset) { it -= offset; }
1260  };
1261  template <typename ItT> struct Dereference {
1262  T operator()(ItT &it) { return *it; }
1263  };
1264  template <typename ItT> struct ConstructIter {
1265  void operator()(ItT &dest, const ItT &it) { ::new (&dest) ItT(it); }
1266  };
1267  template <typename ItT> struct DestructIter {
1268  void operator()(ItT &it) { it.~ItT(); }
1269  };
1270 
1271 public:
1273  : attrKind(rhs.attrKind) {
1274  process<void, ConstructIter>(it, rhs.it);
1275  }
1276  ~ElementsAttrIterator() { process<void, DestructIter>(it); }
1277 
1279  ptrdiff_t operator-(const ElementsAttrIterator<T> &rhs) const {
1280  assert(attrKind == rhs.attrKind && "incompatible iterators");
1281  return process<ptrdiff_t, Minus>(it, rhs.it);
1282  }
1283  bool operator==(const ElementsAttrIterator<T> &rhs) const {
1284  return rhs.attrKind == attrKind && process<bool, std::equal_to>(it, rhs.it);
1285  }
1286  bool operator<(const ElementsAttrIterator<T> &rhs) const {
1287  assert(attrKind == rhs.attrKind && "incompatible iterators");
1288  return process<bool, std::less>(it, rhs.it);
1289  }
1291  process<void, PlusAssign>(it, offset);
1292  return *this;
1293  }
1295  process<void, MinusAssign>(it, offset);
1296  return *this;
1297  }
1298 
1300  T operator*() { return process<T, Dereference>(it); }
1301 
1302 private:
1303  template <typename IteratorT>
1304  ElementsAttrIterator(unsigned attrKind, IteratorT &&it)
1305  : attrKind(attrKind), it(std::forward<IteratorT>(it)) {}
1306 
1308  friend ElementsAttr;
1309 
1311  unsigned attrKind;
1312 
1314  Iterator it;
1315 };
1316 
1317 template <typename T>
1318 class ElementsAttrRange : public llvm::iterator_range<ElementsAttrIterator<T>> {
1320 };
1321 } // namespace detail
1322 
1324 template <typename T>
1326  if (DenseElementsAttr denseAttr = dyn_cast<DenseElementsAttr>()) {
1327  auto values = denseAttr.getValues<T>();
1328  return {iterator<T>(getKind(), values.begin()),
1329  iterator<T>(getKind(), values.end())};
1330  }
1331  if (SparseElementsAttr sparseAttr = dyn_cast<SparseElementsAttr>()) {
1332  auto values = sparseAttr.getValues<T>();
1333  return {iterator<T>(getKind(), values.begin()),
1334  iterator<T>(getKind(), values.end())};
1335  }
1336  llvm_unreachable("unexpected attribute kind");
1337 }
1338 
1339 //===----------------------------------------------------------------------===//
1340 // Attributes Utils
1341 //===----------------------------------------------------------------------===//
1342 
1343 template <typename U> bool Attribute::isa() const {
1344  assert(impl && "isa<> used on a null attribute.");
1345  return U::classof(*this);
1346 }
1347 template <typename U> U Attribute::dyn_cast() const {
1348  return isa<U>() ? U(impl) : U(nullptr);
1349 }
1350 template <typename U> U Attribute::dyn_cast_or_null() const {
1351  return (impl && isa<U>()) ? U(impl) : U(nullptr);
1352 }
1353 template <typename U> U Attribute::cast() const {
1354  assert(isa<U>());
1355  return U(impl);
1356 }
1357 
1358 // Make Attribute hashable.
1359 inline ::llvm::hash_code hash_value(Attribute arg) {
1361 }
1362 
1363 //===----------------------------------------------------------------------===//
1364 // NamedAttributeList
1365 //===----------------------------------------------------------------------===//
1366 
1375 public:
1377  : attrs((attrs && !attrs.empty()) ? attrs : nullptr) {}
1379 
1380  bool operator!=(const NamedAttributeList &other) const {
1381  return !(*this == other);
1382  }
1383  bool operator==(const NamedAttributeList &other) const {
1384  return attrs == other.attrs;
1385  }
1386 
1389  DictionaryAttr getDictionary() const { return attrs; }
1390 
1392  ArrayRef<NamedAttribute> getAttrs() const;
1393 
1395  void setAttrs(ArrayRef<NamedAttribute> attributes);
1396 
1398  Attribute get(StringRef name) const;
1399  Attribute get(Identifier name) const;
1400 
1403  void set(Identifier name, Attribute value);
1404 
1405  enum class RemoveResult { Removed, NotFound };
1406 
1409  RemoveResult remove(Identifier name);
1410 
1411 private:
1412  DictionaryAttr attrs;
1413 };
1414 
1415 } // end namespace mlir.
1416 
1417 namespace llvm {
1418 
1419 // Attribute hash just like pointers.
1420 template <> struct DenseMapInfo<mlir::Attribute> {
1422  auto pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
1423  return mlir::Attribute(static_cast<mlir::Attribute::ImplType *>(pointer));
1424  }
1427  return mlir::Attribute(static_cast<mlir::Attribute::ImplType *>(pointer));
1428  }
1429  static unsigned getHashValue(mlir::Attribute val) {
1430  return mlir::hash_value(val);
1431  }
1432  static bool isEqual(mlir::Attribute LHS, mlir::Attribute RHS) {
1433  return LHS == RHS;
1434  }
1435 };
1436 
1438 template <> struct PointerLikeTypeTraits<mlir::Attribute> {
1439  static inline void *getAsVoidPointer(mlir::Attribute attr) {
1440  return const_cast<void *>(attr.getAsOpaquePointer());
1441  }
1442  static inline mlir::Attribute getFromVoidPointer(void *ptr) {
1444  }
1445  enum { NumLowBitsAvailable = 3 };
1446 };
1447 
1448 template <>
1449 struct PointerLikeTypeTraits<mlir::SymbolRefAttr>
1450  : public PointerLikeTypeTraits<mlir::Attribute> {
1451  static inline mlir::SymbolRefAttr getFromVoidPointer(void *ptr) {
1452  return PointerLikeTypeTraits<mlir::Attribute>::getFromVoidPointer(ptr)
1453  .cast<mlir::SymbolRefAttr>();
1454  }
1455 };
1456 
1457 } // namespace llvm
1458 
1459 #endif
Definition: Attributes.h:456
Definition: InferTypeOpInterface.cpp:20
Definition: Attributes.h:1052
static void * getAsVoidPointer(mlir::Attribute attr)
Definition: Attributes.h:1439
Definition: Attributes.h:976
U cast() const
Definition: Attributes.h:1353
Definition: Attributes.h:130
U dyn_cast_or_null() const
Definition: Attributes.h:1350
Elements Attributes.
Definition: Attributes.h:143
Definition: PassRegistry.cpp:413
static bool classof(Attribute attr)
Method for support type inquiry through isa, cast and dyn_cast.
Definition: Attributes.h:1198
Definition: Attributes.h:139
static const char * getFromVoidPointer(const void *ptr)
Definition: Attributes.h:620
Definition: Attributes.h:519
Definition: Attributes.h:129
Definition: Attributes.h:491
StringRef ValueType
Definition: Attributes.h:432
const void * getAsOpaquePointer() const
Get an opaque pointer to the attribute.
Definition: Attributes.h:110
Definition: LLVM.h:45
A utility iterator that allows walking over the internal raw APInt values.
Definition: Attributes.h:780
static bool classof(Attribute attr)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: Attributes.h:505
static bool classof(Attribute)
Definition: Attributes.h:91
Definition: LLVM.h:49
llvm::ArrayRef< Attribute >::iterator iterator
Support range iteration.
Definition: Attributes.h:209
bool isa() const
Definition: Attributes.h:1343
T getValue(ArrayRef< uint64_t > index) const
Definition: Attributes.h:575
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Definition: Attributes.cpp:572
std::enable_if< std::is_base_of< Attribute, T >::value &&!std::is_same< Attribute, T >::value, T >::type getSplatValue() const
Return the splat value for derived attribute element types.
Definition: Attributes.h:834
Definition: Identifier.h:26
iterator_range< T > getValues() const
static mlir::SymbolRefAttr getFromVoidPointer(void *ptr)
Definition: Attributes.h:1451
Definition: Attributes.h:269
llvm::iterator_range< BoolElementIterator > getValues() const
Definition: Attributes.h:891
static bool kindof(unsigned kind)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: Attributes.h:187
Definition: Attributes.h:198
iterator end() const
Definition: Attributes.h:211
Definition: LLVM.h:40
APFloat reference
Definition: Attributes.h:807
ElementsAttrIterator(const ElementsAttrIterator< T > &rhs)
Definition: Attributes.h:1272
~ElementsAttrIterator()
Definition: Attributes.h:1276
bool operator==(const ElementsAttrIterator< T > &rhs) const
Definition: Attributes.h:1283
llvm::iterator_range< ElementIterator< T > > getValues() const
Definition: Attributes.h:854
Definition: Attributes.h:131
llvm::iterator_range< DerivedAttributeElementIterator< T > > getValues() const
Definition: Attributes.h:880
Definition: StandardTypes.h:178
Definition: Attributes.h:132
Definition: Location.h:52
iterator begin() const
Iterator access to the float element values.
Definition: Attributes.h:1003
std::pair< Identifier, Attribute > NamedAttribute
Definition: Attributes.h:264
A utility iterator that allows walking over the internal bool values.
Definition: Attributes.h:765
static bool kindof(unsigned kind)
Method for support type inquiry through isa, cast and dyn_cast.
Definition: Attributes.h:1077
static mlir::Attribute getTombstoneKey()
Definition: Attributes.h:1425
APFloat ValueType
Definition: Attributes.h:306
llvm::iterator_range< AttributeElementIterator > getValues() const
Definition: Attributes.h:866
Definition: Attributes.h:553
Definition: LogicalResult.h:18
static bool classof(Attribute attr)
Method for support type inquiry through isa, cast and dyn_cast.
Definition: Attributes.h:667
Definition: Attributes.h:153
NamedAttributeList(DictionaryAttr attrs=nullptr)
Definition: Attributes.h:1376
bool operator!=(const NamedAttributeList &other) const
Definition: Attributes.h:1380
iterator end() const
Definition: Attributes.h:1041
Definition: LLVM.h:37
size_t size() const
Definition: Attributes.h:212
Definition: Attributes.h:155
Definition: Attributes.h:660
ElementsAttrIterator< T > & operator+=(ptrdiff_t offset)
Definition: Attributes.h:1290
DictionaryAttr getDictionary() const
Definition: Attributes.h:1389
llvm::mapped_iterator< llvm::detail::value_sequence_iterator< ptrdiff_t >, std::function< T(ptrdiff_t)> > iterator
Definition: Attributes.h:1109
StringRef ValueType
Definition: Attributes.h:1057
Definition: Attributes.h:53
Definition: Attributes.h:243
ptrdiff_t getDataIndex() const
Definition: Attributes.h:648
Attribute(const ImplType *impl)
Definition: Attributes.h:73
Iterator for walking over APFloat values.
Definition: Attributes.h:798
IntElementIterator raw_int_begin() const
Get iterators to the raw APInt values for each element in this attribute.
Definition: Attributes.h:944
static bool classof(Attribute attr)
Method for support type inquiry through isa, cast and dyn_cast.
Definition: Attributes.h:603
IntElementIterator raw_int_end() const
Definition: Attributes.h:947
Definition: Dialect.h:39
Definition: Attributes.h:133
Definition: Attributes.h:343
Definition: Attributes.h:428
llvm::PointerIntPair< const char *, 1, bool, DenseElementDataPointerTypeTraits > DenseIterPtrAndSplat
Pair of raw pointer and a boolean flag of whether the pointer holds a splat,.
Definition: Attributes.h:631
StringRef getValue() const
Returns the name of the held symbol reference.
Definition: Attributes.h:502
ArrayRef< FlatSymbolRefAttr > getNestedReferences() const
Definition: Attributes.cpp:259
Definition: Attributes.h:152
Definition: AffineMap.h:37
Definition: Attributes.h:1374
bool operator==(Attribute other) const
Definition: Attributes.h:79
static bool kindof(unsigned kind)
Method for support type inquiry through isa, cast and dyn_cast.
Definition: Attributes.h:1143
llvm::iterator_range< iterator< T > > getValues() const
Definition: Attributes.h:1121
Attribute()
Definition: Attributes.h:72
Definition: STLExtras.h:145
static bool kindof(unsigned kind)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: Attributes.h:530
static bool kindof(unsigned kind)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: Attributes.h:443
const char * getData() const
Return the data base pointer.
Definition: Attributes.h:654
void print(raw_ostream &os) const
Print the attribute.
Definition: AsmPrinter.cpp:2061
Attribute getValue(ArrayRef< uint64_t > index) const
Definition: Attributes.h:840
Definition: Attributes.h:391
Definition: Types.h:84
iterator end() const
Definition: Attributes.h:1004
void ValueType
Definition: Attributes.h:70
Definition: Attributes.h:136
Definition: Attributes.h:1193
static bool kindof(unsigned kind)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: Attributes.h:215
T operator*()
Dereference the iterator at the current index.
Definition: Attributes.h:1300
static bool kindof(unsigned kind)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: Attributes.h:326
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:201
Definition: Attributes.h:137
Definition: Attributes.h:302
static bool kindof(unsigned kind)
Definition: Attributes.h:545
Definition: Attributes.h:175
static mlir::Attribute getEmptyKey()
Definition: Attributes.h:1421
bool operator!=(Attribute other) const
Definition: Attributes.h:80
Kind
Integer identifier for all the concrete attribute kinds.
Definition: Attributes.h:56
Definition: Attributes.h:154
static FlatSymbolRefAttr get(StringRef value, MLIRContext *ctx)
Construct a symbol reference for the given value name.
Definition: Attributes.cpp:241
static bool kindof(unsigned kind)
Definition: Attributes.h:419
Definition: LLVM.h:50
inline ::llvm::hash_code hash_value(Attribute arg)
Definition: Attributes.h:1359
Definition: Attributes.h:367
bool operator==(const NamedAttributeList &other) const
Definition: Attributes.h:1383
Definition: Attributes.h:140
bool operator!() const
Definition: Attributes.h:83
U dyn_cast() const
Definition: Attributes.h:1347
Definition: Attributes.h:138
Definition: Attributes.h:746
Definition: StorageUniquerSupport.h:30
const T & operator*() const
Accesses the raw value at this iterator position.
Definition: Attributes.h:751
ptrdiff_t operator-(const ElementsAttrIterator< T > &rhs) const
Methods necessary to support random access iteration.
Definition: Attributes.h:1279
Definition: MLIRContext.h:34
static bool kindof(unsigned kind)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: Attributes.h:379
void print(OpAsmPrinter &p, AffineIfOp op)
Definition: AffineOps.cpp:1671
llvm::mapped_iterator< AttributeElementIterator, T(*)(Attribute)> DerivedAttributeElementIterator
Definition: Attributes.h:876
APInt ValueType
Definition: Attributes.h:348
T getValue(ArrayRef< uint64_t > index) const
Definition: Attributes.h:843
llvm::iterator_range< FloatElementIterator > getValues() const
Definition: Attributes.h:911
static bool isEqual(mlir::Attribute LHS, mlir::Attribute RHS)
Definition: Attributes.h:1432
Definition: AttributeSupport.h:34
llvm::ArrayRef< NamedAttribute >::iterator iterator
Support range iteration.
Definition: Attributes.h:286
Definition: Attributes.h:554
llvm::iterator_range< attr_value_iterator< AttrTy > > getAsRange()
Definition: Attributes.h:233
RemoveResult
Definition: Attributes.h:1405
bool empty() const
Definition: Attributes.h:289
static const void * getAsVoidPointer(const char *ptr)
Definition: Attributes.h:619
ImplType * impl
Definition: Attributes.h:119
static bool kindof(unsigned kind)
Methods for supporting type inquiry through isa, cast, and dyn_cast.
Definition: Attributes.h:293
static bool kindof(unsigned kind)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: Attributes.h:358
static bool kindof(unsigned kind)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: Attributes.h:484
bool ValueType
Definition: Attributes.h:247
static unsigned getHashValue(mlir::Attribute val)
Definition: Attributes.h:1429
raw_ostream & operator<<(raw_ostream &os, SubViewOp::Range &range)
Definition: Ops.cpp:2759
Definition: Attributes.h:539
Attribute getSplatValue() const
Definition: Attributes.h:820
llvm::iterator_range< IntElementIterator > getValues() const
Definition: Attributes.h:900
AffineExpr operator*(int64_t val, AffineExpr expr)
Definition: AffineExpr.h:206
iterator begin() const
Definition: Attributes.h:210
Definition: Attributes.h:144
Definition: Attributes.h:145
bool isSplat() const
Definition: Attributes.cpp:715
StringRef ValueType
Definition: Attributes.h:494
Definition: Attributes.h:559
std::enable_if<!std::is_base_of< Attribute, T >::value||std::is_same< Attribute, T >::value, T >::type getSplatValue() const
Definition: Attributes.h:825
Kind
Definition: Attributes.h:128
static mlir::Attribute getFromVoidPointer(void *ptr)
Definition: Attributes.h:1442
iterator begin() const
Iterator access to the integer element values.
Definition: Attributes.h:1040
static Attribute getFromOpaquePointer(const void *ptr)
Construct an attribute from the opaque pointer representation.
Definition: Attributes.h:112
Definition: Attributes.h:135
unsigned getKind() const
Return the classification for this attribute.
Definition: Attributes.h:94
Locations.
Definition: Attributes.h:150
ElementsAttrIterator< T > & operator-=(ptrdiff_t offset)
Definition: Attributes.h:1294
Definition: Attributes.h:1100
Definition: Attributes.h:134
static bool kindof(unsigned kind)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: Attributes.h:254
DenseElementIndexedIteratorImpl(const char *data, bool isSplat, size_t dataIndex)
Definition: Attributes.h:641
Definition: Attributes.h:1012
Definition: IntegerSet.h:42
Definition: AttributeSupport.h:89