9 #ifndef MLIR_IR_BUILTINATTRIBUTES_H 10 #define MLIR_IR_BUILTINATTRIBUTES_H 14 #include "llvm/ADT/APFloat.h" 15 #include "llvm/ADT/Sequence.h" 21 class DenseIntElementsAttr;
22 class FlatSymbolRefAttr;
40 template <
typename ConcreteT,
typename T,
typename PointerT = T *,
41 typename ReferenceT = T &>
43 :
public llvm::indexed_accessor_iterator<ConcreteT, DenseIterPtrAndSplat, T,
44 PointerT, ReferenceT> {
49 PointerT, ReferenceT>({data, isSplat},
55 bool isSplat = this->base.second;
56 return isSplat ? 0 : this->index;
60 const char *
getData()
const {
return this->base.first; }
64 template <
typename T>
struct is_complex_t :
public std::false_type {};
76 operator ElementsAttr()
const {
77 return *
this ? cast<ElementsAttr>() :
nullptr;
90 (std::numeric_limits<T>::is_specialized &&
91 !std::numeric_limits<T>::is_integer);
107 template <
typename T,
typename =
typename std::enable_if<
108 std::numeric_limits<T>::is_integer ||
111 const char *data =
reinterpret_cast<const char *
>(values.data());
112 return getRawIntOrFloat(
114 std::numeric_limits<T>::is_integer, std::numeric_limits<T>::is_signed);
118 template <
typename T,
typename =
typename std::enable_if<
119 std::numeric_limits<T>::is_integer ||
123 return get(type, llvm::makeArrayRef(
value));
129 template <
typename T,
typename ElementT =
typename T::value_type,
130 typename =
typename std::enable_if<
132 (std::numeric_limits<ElementT>::is_integer ||
135 const char *data =
reinterpret_cast<const char *
>(values.data());
136 return getRawComplex(type,
ArrayRef<char>(data, values.size() *
sizeof(T)),
137 sizeof(T), std::numeric_limits<ElementT>::is_integer,
138 std::numeric_limits<ElementT>::is_signed);
177 template <
typename T>
179 const std::initializer_list<T> &list) {
208 static bool isValidRawBuffer(ShapedType type,
ArrayRef<char> rawBuffer,
209 bool &detectedSplat);
216 template <
typename IteratorT>
220 template <
typename T,
typename AttrT = DenseElementsAttr>
221 using iterator = decltype(std::declval<AttrT>().
template value_begin<T>());
223 template <
typename T,
typename AttrT = DenseElementsAttr>
225 decltype(std::declval<AttrT>().
template getValues<T>());
230 :
public llvm::indexed_accessor_iterator<AttributeElementIterator,
231 const void *, Attribute,
232 Attribute, Attribute> {
247 template <
typename T>
263 data, isSplat, dataIndex) {}
284 APInt, APInt, APInt> {
303 ComplexIntElementIterator, std::complex<APInt>, std::complex<APInt>,
304 std::complex<APInt>> {
321 :
public llvm::mapped_iterator_base<FloatElementIterator,
322 IntElementIterator, APFloat> {
326 return APFloat(*smt, value);
334 :
BaseT(it), smt(&smt) {}
337 const llvm::fltSemantics *smt;
342 :
public llvm::mapped_iterator_base<ComplexFloatElementIterator,
343 ComplexIntElementIterator,
344 std::complex<APFloat>> {
348 return {APFloat(*smt, value.real()), APFloat(*smt, value.imag())};
357 :
BaseT(it), smt(&smt) {}
360 const llvm::fltSemantics *smt;
369 bool isSplat()
const;
373 template <
typename T>
378 assert(isSplat() &&
"expected the attribute to be a splat");
379 return *value_begin<T>();
382 template <
typename T>
387 return getSplatValue<Attribute>().
template cast<T>();
392 template <
typename T>
395 std::numeric_limits<T>::is_integer) ||
397 template <
typename T,
typename = IntFloatValueTemplateCheckT<T>>
400 std::numeric_limits<T>::is_signed));
401 const char *rawData = getRawData().data();
402 bool splat = isSplat();
406 template <
typename T,
typename = IntFloatValueTemplateCheckT<T>>
409 std::numeric_limits<T>::is_signed));
412 template <
typename T,
typename = IntFloatValueTemplateCheckT<T>>
415 std::numeric_limits<T>::is_signed));
420 template <
typename T,
typename ElementT>
423 (std::numeric_limits<ElementT>::is_integer ||
425 template <
typename T,
typename ElementT =
typename T::value_type,
428 assert(isValidComplex(
sizeof(T), std::numeric_limits<ElementT>::is_integer,
429 std::numeric_limits<ElementT>::is_signed));
430 const char *rawData = getRawData().data();
431 bool splat = isSplat();
435 template <
typename T,
typename ElementT =
typename T::value_type,
438 assert(isValidComplex(
sizeof(T), std::numeric_limits<ElementT>::is_integer,
439 std::numeric_limits<ElementT>::is_signed));
442 template <
typename T,
typename ElementT =
typename T::value_type,
445 assert(isValidComplex(
sizeof(T), std::numeric_limits<ElementT>::is_integer,
446 std::numeric_limits<ElementT>::is_signed));
451 template <
typename T>
454 template <
typename T,
typename = StringRefValueTemplateCheckT<T>>
456 auto stringRefs = getRawStringData();
457 const char *ptr =
reinterpret_cast<const char *
>(stringRefs.data());
458 bool splat = isSplat();
462 template <
typename T,
typename = StringRefValueTemplateCheckT<T>>
464 const char *ptr =
reinterpret_cast<const char *
>(getRawStringData().data());
467 template <
typename T,
typename = StringRefValueTemplateCheckT<T>>
469 const char *ptr =
reinterpret_cast<const char *
>(getRawStringData().data());
474 template <
typename T>
477 template <
typename T,
typename = AttributeValueTemplateCheckT<T>>
480 value_end<Attribute>()};
482 template <
typename T,
typename = AttributeValueTemplateCheckT<T>>
486 template <
typename T,
typename = AttributeValueTemplateCheckT<T>>
493 template <
typename T>
497 template <
typename T>
499 :
public llvm::mapped_iterator_base<DerivedAttributeElementIterator<T>,
500 AttributeElementIterator, T> {
501 using llvm::mapped_iterator_base<DerivedAttributeElementIterator<T>,
503 T>::mapped_iterator_base;
508 template <
typename T,
typename = DerivedAttrValueTemplateCheckT<T>>
512 DerivedIterT(value_end<Attribute>())};
514 template <
typename T,
typename = DerivedAttrValueTemplateCheckT<T>>
516 return {value_begin<Attribute>()};
518 template <
typename T,
typename = DerivedAttrValueTemplateCheckT<T>>
520 return {value_end<Attribute>()};
525 template <
typename T>
528 template <
typename T,
typename = BoolValueTemplateCheckT<T>>
530 assert(isValidBool() &&
"bool is not the value of this elements attribute");
534 template <
typename T,
typename = BoolValueTemplateCheckT<T>>
536 assert(isValidBool() &&
"bool is not the value of this elements attribute");
539 template <
typename T,
typename = BoolValueTemplateCheckT<T>>
541 assert(isValidBool() &&
"bool is not the value of this elements attribute");
547 template <
typename T>
550 template <
typename T,
typename = APIntValueTemplateCheckT<T>>
552 assert(
getElementType().isIntOrIndex() &&
"expected integral type");
555 template <
typename T,
typename = APIntValueTemplateCheckT<T>>
557 assert(
getElementType().isIntOrIndex() &&
"expected integral type");
558 return raw_int_begin();
560 template <
typename T,
typename = APIntValueTemplateCheckT<T>>
562 assert(
getElementType().isIntOrIndex() &&
"expected integral type");
563 return raw_int_end();
568 template <
typename T>
570 std::is_same<T, std::complex<APInt>>
::value>::type;
571 template <
typename T,
typename = ComplexAPIntValueTemplateCheckT<T>>
573 return getComplexIntValues();
575 template <
typename T,
typename = ComplexAPIntValueTemplateCheckT<T>>
577 return complex_value_begin();
579 template <
typename T,
typename = ComplexAPIntValueTemplateCheckT<T>>
581 return complex_value_end();
586 template <
typename T>
589 template <
typename T,
typename = APFloatValueTemplateCheckT<T>>
591 return getFloatValues();
593 template <
typename T,
typename = APFloatValueTemplateCheckT<T>>
595 return float_value_begin();
597 template <
typename T,
typename = APFloatValueTemplateCheckT<T>>
599 return float_value_end();
604 template <
typename T>
606 std::is_same<T, std::complex<APFloat>>
::value>::type;
607 template <
typename T,
typename = ComplexAPFloatValueTemplateCheckT<T>>
609 return getComplexFloatValues();
611 template <
typename T,
typename = ComplexAPFloatValueTemplateCheckT<T>>
613 return complex_float_value_begin();
615 template <
typename T,
typename = ComplexAPFloatValueTemplateCheckT<T>>
617 return complex_float_value_end();
630 ShapedType getType()
const;
642 bool empty()
const {
return size() == 0; }
673 mapValues(
Type newElementType,
693 getComplexFloatValues()
const;
701 int64_t dataEltSize,
bool isInt,
709 int64_t dataEltSize,
bool isInt,
717 bool isValidComplex(int64_t dataEltSize,
bool isInt,
bool isSigned)
const;
724 using DenseElementsAttr::DenseElementsAttr;
729 return denseAttr && denseAttr.
isSplat();
738 #define GET_ATTRDEF_CLASSES 739 #include "mlir/IR/BuiltinAttributes.h.inc" 749 template <
typename T>
752 using DenseArrayBaseAttr::DenseArrayBaseAttr;
763 void print(raw_ostream &os)
const;
765 void printWithoutBraces(raw_ostream &os)
const;
810 operator IntegerAttr()
const {
return IntegerAttr(
impl); }
813 bool getValue()
const;
827 using SymbolRefAttr::SymbolRefAttr;
832 return SymbolRefAttr::get(
value);
835 return SymbolRefAttr::get(ctx,
value);
841 return SymbolRefAttr::get(symbol);
845 StringAttr
getAttr()
const {
return getRootReference(); }
848 StringRef
getValue()
const {
return getAttr().getValue(); }
852 SymbolRefAttr refAttr = attr.
dyn_cast<SymbolRefAttr>();
853 return refAttr && refAttr.getNestedReferences().empty();
857 using SymbolRefAttr::get;
858 using SymbolRefAttr::getNestedReferences;
871 using DenseIntOrFPElementsAttr::DenseIntOrFPElementsAttr;
875 template <
typename Arg>
878 .template cast<DenseFPElementsAttr>();
880 template <
typename T>
882 const std::initializer_list<T> &list) {
884 .template cast<DenseFPElementsAttr>();
890 mapValues(
Type newElementType,
913 using DenseIntOrFPElementsAttr::DenseIntOrFPElementsAttr;
917 template <
typename Arg>
920 .template cast<DenseIntElementsAttr>();
922 template <
typename T>
924 const std::initializer_list<T> &list) {
926 .template cast<DenseIntElementsAttr>();
946 template <
typename T>
947 auto SparseElementsAttr::value_begin()
const ->
iterator<T> {
948 auto zeroValue = getZeroValue<T>();
949 auto valueIt = getValues().value_begin<T>();
950 const std::vector<ptrdiff_t> flatSparseIndices(getFlattenedSparseIndices());
951 std::function<T(ptrdiff_t)> mapFn =
952 [flatSparseIndices{flatSparseIndices}, valueIt{std::move(valueIt)},
953 zeroValue{std::move(zeroValue)}](ptrdiff_t index) {
955 for (
unsigned i = 0, e = flatSparseIndices.size(); i != e; ++i)
956 if (flatSparseIndices[i] == index)
957 return *std::next(valueIt, i);
970 inline bool operator==(StringAttr lhs, std::nullptr_t) {
return !lhs; }
972 return static_cast<bool>(lhs);
977 inline bool operator!=(StringAttr lhs, StringAttr rhs) {
return !(lhs == rhs); }
981 return lhs.getValue() == rhs;
983 inline bool operator!=(StringAttr lhs, StringRef rhs) {
return !(lhs == rhs); }
985 return rhs.getValue() == lhs;
987 inline bool operator!=(StringRef lhs, StringAttr rhs) {
return !(lhs == rhs); }
1003 return mlir::StringAttr::getFromOpaquePointer(pointer);
1007 return mlir::StringAttr::getFromOpaquePointer(pointer);
1011 struct PointerLikeTypeTraits<
mlir::StringAttr>
1012 :
public PointerLikeTypeTraits<mlir::Attribute> {
1014 return mlir::StringAttr::getFromOpaquePointer(p);
1019 struct PointerLikeTypeTraits<
mlir::SymbolRefAttr>
1020 :
public PointerLikeTypeTraits<mlir::Attribute> {
1022 return mlir::SymbolRefAttr::getFromOpaquePointer(ptr);
1028 #endif // MLIR_IR_BUILTINATTRIBUTES_H
TODO: Remove this file when SCCP and integer range analysis have been ported to the new framework...
void printWithoutBraces(raw_ostream &os) const
Print the short form 42, 100, -1 without any braces or type prefix.
typename std::enable_if<(!std::is_same< T, bool >::value &&std::numeric_limits< T >::is_integer)||is_valid_cpp_fp_type< T >::value >::type IntFloatValueTemplateCheckT
Return the held element values as a range of integer or floating-point values.
An attribute that represents a reference to a dense float vector or tensor object.
ElementIterator< StringRef > value_begin() const
T mapElement(Attribute attr) const
Map the element to the iterator result type.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Operation is a basic unit of execution within MLIR.
iterator_range_impl< ElementIterator< T > > getValues() const
typename std::enable_if< std::is_same< T, std::complex< APInt > >::value >::type ComplexAPIntValueTemplateCheckT
Return the held element values as a range of complex APInts.
static bool classof(Attribute attr)
Method for support type inquiry through isa, cast and dyn_cast.
FloatElementIterator value_begin() const
A symbol reference with a reference path containing a single element.
A utility iterator that allows walking over the internal raw APInt values.
FloatElementIterator value_end() const
static mlir::StringAttr getEmptyKey()
static bool classof(Attribute attr)
Methods for support type inquiry through isa, cast, and dyn_cast.
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
bool isValidBool() const
Check the information for a C++ data type, check if this type is valid for the current attribute...
A utility iterator that allows walking over the internal raw complex APInt values.
static Type getElementType(Type type, ArrayRef< int32_t > indices, function_ref< InFlightDiagnostic(StringRef)> emitErrorFn)
Walks the given type hierarchy with the given indices, potentially down to component granularity...
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.
Type trait detector that checks if a given type T is a complex type.
bool operator!=(StringAttr lhs, std::nullptr_t)
static mlir::SymbolRefAttr getFromVoidPointer(void *ptr)
ComplexFloatElementIterator value_begin() const
DerivedAttributeElementIterator< T > value_begin() const
iterator_range_impl< ComplexIntElementIterator > getValues() const
static bool isValidIntOrFloat(Type type, int64_t dataEltSize, bool isInt, bool isSigned)
Check the information for a C++ data type, check if this type is valid for the current attribute...
typename std::enable_if< std::is_same< T, std::complex< APFloat > >::value >::type ComplexAPFloatValueTemplateCheckT
Return the held element values as a range of complex APFloat.
AttributeElementIterator value_end() const
std::complex< APFloat > mapElement(const std::complex< APInt > &value) const
Map the element to the iterator result type.
ElementIterator< T > value_end() const
iterator_range_impl< ElementIterator< StringRef > > getValues() const
static constexpr const bool value
iterator begin() const
Iterator access to the float element values.
ElementIterator< StringRef > value_end() const
A utility iterator that allows walking over the internal bool values.
AttributeElementIterator value_begin() const
typename std::enable_if< std::is_base_of< Attribute, T >::value &&!std::is_same< Attribute, T >::value >::type DerivedAttrValueTemplateCheckT
Return the held element values a range of T, where T is a derived attribute type. ...
typename std::enable_if< std::is_same< T, StringRef >::value >::type StringRefValueTemplateCheckT
Return the held element values as a range of StringRef.
typename std::enable_if< std::is_same< T, APInt >::value >::type APIntValueTemplateCheckT
Return the held element values as a range of APInts.
static mlir::StringAttr getFromVoidPointer(void *p)
An attribute that represents a reference to a dense vector or tensor object.
APFloat mapElement(const APInt &value) const
Map the element to the iterator result type.
iterator_range_impl< AttributeElementIterator > getValues() const
iterator_range_impl< ElementIterator< T > > getValues() const
iterator_range_impl< FloatElementIterator > getValues() const
Attributes are known-constant values of operations.
Special case of IntegerAttr to represent boolean integers, i.e., signless i1 integers.
ptrdiff_t getDataIndex() const
Return the current index for this iterator, adjusted for the case of a splat.
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
Iterator for walking over APFloat values.
IntElementIterator raw_int_begin() const
Iterators to various elements that require out-of-line definition.
IntElementIterator raw_int_end() const
iterator_range_impl< BoolElementIterator > getValues() const
ElementIterator< T > value_begin() const
StringRef getValue() const
Returns the name of the held symbol reference.
typename std::enable_if< std::is_same< T, Attribute >::value >::type AttributeValueTemplateCheckT
Return the held element values as a range of Attributes.
const char * getData() const
Return the data base pointer.
ComplexIntElementIterator value_begin() const
IntElementIterator value_end() const
StringAttr getAttr() const
Returns the name of the held symbol reference as a StringAttr.
This base class exposes generic asm parser hooks, usable across the various derived parsers...
iterator_range_impl< IntElementIterator > getValues() const
ElementIterator< T > value_end() const
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
DerivedAttributeElementIterator< T > value_end() const
An attribute that represents a reference to a splat vector or tensor constant, meaning all of the ele...
ArrayRef< T > asArrayRef()
IntElementIterator value_begin() const
Type getType() const
Return the type of this attribute.
BoolElementIterator value_end() const
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.
static int64_t getNumElements(ShapedType type)
typename std::enable_if< std::is_same< T, APFloat >::value >::type APFloatValueTemplateCheckT
Return the held element values as a range of APFloat.
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.
ElementIterator< T > value_begin() const
MLIRContext is the top-level object for a collection of MLIR operations.
int64_t size() const
Returns the number of elements held by this attribute.
typename std::enable_if< detail::is_complex_t< T >::value &&(std::numeric_limits< ElementT >::is_integer||is_valid_cpp_fp_type< ElementT >::value)>::type ComplexValueTemplateCheckT
Return the held element values as a range of std::complex.
This class provides iterator utilities for an ElementsAttr range.
ComplexFloatElementIterator value_end() const
This base class exposes generic asm printer hooks, usable across the various derived printers...
iterator_range_impl< DerivedAttributeElementIterator< T > > getValues() const
Base class for DenseArrayAttr that is instantiated and specialized for each supported element type be...
AffineExpr operator*(int64_t val, AffineExpr expr)
BoolElementIterator value_begin() const
iterator_range_impl< ComplexFloatElementIterator > getValues() const
ComplexIntElementIterator value_end() const
bool isSplat() const
Returns true if this attribute corresponds to a splat, i.e.
Iterator for walking over complex APFloat values.
static mlir::StringAttr getTombstoneKey()
Impl iterator for indexed DenseElementsAttr iterators that records a data pointer and data index that...
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 this attribute.
A utility iterator that allows walking over the internal Attribute values of a DenseElementsAttr.
iterator begin() const
Iterator access to the integer element values.
Type trait used to check if the given type T is a potentially valid C++ floating point type that can ...
std::pair< const char *, bool > DenseIterPtrAndSplat
Pair of raw pointer and a boolean flag of whether the pointer holds a splat,.
DenseElementIndexedIteratorImpl(const char *data, bool isSplat, size_t dataIndex)
bool operator==(StringAttr lhs, std::nullptr_t)
Define comparisons for StringAttr against nullptr and itself to avoid the StringRef overloads from be...
bool empty() const
Returns if the number of elements held by this attribute is 0.
An attribute that represents a reference to a dense integer vector or tensor object.
typename std::enable_if< std::is_same< T, bool >::value >::type BoolValueTemplateCheckT
Return the held element values as a range of bool.