diff options
author | River Riddle <riverriddle@google.com> | 2019-06-18 16:41:00 -0700 |
---|---|---|
committer | Mehdi Amini <joker.eph@gmail.com> | 2019-06-19 23:07:24 -0700 |
commit | 18743a33ac0caf08b69f097383c176a8a653e4f5 (patch) | |
tree | 6aa4e3a0b692c3222d086aa57f8fd53694e966f7 | |
parent | 34cb51743d906e8475b44bc603a8f164b5f11f3a (diff) | |
download | bcm5719-llvm-18743a33ac0caf08b69f097383c176a8a653e4f5.tar.gz bcm5719-llvm-18743a33ac0caf08b69f097383c176a8a653e4f5.zip |
NFC: Reorder the attribute classes alphabetically to improve readability.
PiperOrigin-RevId: 253894445
-rw-r--r-- | mlir/include/mlir/IR/Attributes.h | 363 | ||||
-rw-r--r-- | mlir/lib/IR/AttributeDetail.h | 302 | ||||
-rw-r--r-- | mlir/lib/IR/Attributes.cpp | 214 |
3 files changed, 433 insertions, 446 deletions
diff --git a/mlir/include/mlir/IR/Attributes.h b/mlir/include/mlir/IR/Attributes.h index cf1bb9e4f36..76e57e527e4 100644 --- a/mlir/include/mlir/IR/Attributes.h +++ b/mlir/include/mlir/IR/Attributes.h @@ -30,21 +30,23 @@ class Identifier; class IntegerSet; class Location; class MLIRContext; -class Type; class ShapedType; +class Type; namespace detail { -struct OpaqueAttributeStorage; +struct AffineMapAttributeStorage; +struct ArrayAttributeStorage; struct BoolAttributeStorage; struct DictionaryAttributeStorage; struct IntegerAttributeStorage; +struct IntegerSetAttributeStorage; struct FloatAttributeStorage; +struct OpaqueAttributeStorage; struct StringAttributeStorage; -struct ArrayAttributeStorage; -struct AffineMapAttributeStorage; -struct IntegerSetAttributeStorage; struct TypeAttributeStorage; + +/// Elements Attributes. struct DenseElementsAttributeStorage; struct OpaqueElementsAttributeStorage; struct SparseElementsAttributeStorage; @@ -137,19 +139,20 @@ inline raw_ostream &operator<<(raw_ostream &os, Attribute attr) { namespace StandardAttributes { enum Kind { - Unit = Attribute::FIRST_STANDARD_ATTR, - Opaque, + AffineMap = Attribute::FIRST_STANDARD_ATTR, + Array, Bool, Dictionary, - Integer, Float, + Function, + Integer, + IntegerSet, + Opaque, String, Type, - Array, - AffineMap, - IntegerSet, - Function, + Unit, + /// Elements Attributes. DenseElements, OpaqueElements, SparseElements, @@ -158,51 +161,44 @@ enum Kind { }; } // namespace StandardAttributes -/// Unit attributes are attributes that hold no specific value and are given -/// meaning by their existence. -class UnitAttr : public Attribute::AttrBase<UnitAttr> { +class AffineMapAttr + : public Attribute::AttrBase<AffineMapAttr, Attribute, + detail::AffineMapAttributeStorage> { public: using Base::Base; + using ValueType = AffineMap; - static UnitAttr get(MLIRContext *context) { - return Base::get(context, StandardAttributes::Unit); - } + static AffineMapAttr get(AffineMap value); - static bool kindof(unsigned kind) { return kind == StandardAttributes::Unit; } + AffineMap getValue() const; + + /// Methods for support type inquiry through isa, cast, and dyn_cast. + static bool kindof(unsigned kind) { + return kind == StandardAttributes::AffineMap; + } }; -/// Opaque attributes represent attributes of non-registered dialects. These are -/// attribute represented in their raw string form, and can only usefully be -/// tested for attribute equality. -class OpaqueAttr : public Attribute::AttrBase<OpaqueAttr, Attribute, - detail::OpaqueAttributeStorage> { +/// Array attributes are lists of other attributes. They are not necessarily +/// type homogenous given that attributes don't, in general, carry types. +class ArrayAttr : public Attribute::AttrBase<ArrayAttr, Attribute, + detail::ArrayAttributeStorage> { public: using Base::Base; + using ValueType = ArrayRef<Attribute>; - /// Get or create a new OpaqueAttr with the provided dialect and string data. - static OpaqueAttr get(Identifier dialect, StringRef attrData, - MLIRContext *context); - - /// Get or create a new OpaqueAttr with the provided dialect and string data. - /// If the given identifier is not a valid namespace for a dialect, then a - /// null attribute is returned. - static OpaqueAttr getChecked(Identifier dialect, StringRef attrData, - MLIRContext *context, Location location); - - /// Returns the dialect namespace of the opaque attribute. - Identifier getDialectNamespace() const; + static ArrayAttr get(ArrayRef<Attribute> value, MLIRContext *context); - /// Returns the raw attribute data of the opaque attribute. - StringRef getAttrData() const; + ArrayRef<Attribute> getValue() const; - /// Verify the construction of an opaque attribute. - static LogicalResult - verifyConstructionInvariants(llvm::Optional<Location> loc, - MLIRContext *context, Identifier dialect, - StringRef attrData); + /// Support range iteration. + using iterator = llvm::ArrayRef<Attribute>::iterator; + iterator begin() const { return getValue().begin(); } + iterator end() const { return getValue().end(); } + size_t size() const { return getValue().size(); } + /// Methods for support type inquiry through isa, cast, and dyn_cast. static bool kindof(unsigned kind) { - return kind == StandardAttributes::Opaque; + return kind == StandardAttributes::Array; } }; @@ -220,23 +216,40 @@ public: static bool kindof(unsigned kind) { return kind == StandardAttributes::Bool; } }; -class IntegerAttr - : public Attribute::AttrBase<IntegerAttr, Attribute, - detail::IntegerAttributeStorage> { +/// NamedAttribute is used for dictionary attributes, it holds an identifier for +/// the name and a value for the attribute. The attribute pointer should always +/// be non-null. +using NamedAttribute = std::pair<Identifier, Attribute>; + +/// Dictionary attribute is an attribute that represents a sorted collection of +/// named attribute values. The elements are sorted by name, and each name must +/// be unique within the collection. +class DictionaryAttr + : public Attribute::AttrBase<DictionaryAttr, Attribute, + detail::DictionaryAttributeStorage> { public: using Base::Base; - using ValueType = APInt; + using ValueType = ArrayRef<NamedAttribute>; - static IntegerAttr get(Type type, int64_t value); - static IntegerAttr get(Type type, const APInt &value); + static DictionaryAttr get(ArrayRef<NamedAttribute> value, + MLIRContext *context); - APInt getValue() const; - // TODO(jpienaar): Change callers to use getValue instead. - int64_t getInt() const; + ArrayRef<NamedAttribute> getValue() const; - /// Methods for support type inquiry through isa, cast, and dyn_cast. + /// Return the specified attribute if present, null otherwise. + Attribute get(StringRef name) const; + Attribute get(Identifier name) const; + + /// Support range iteration. + using iterator = llvm::ArrayRef<NamedAttribute>::iterator; + iterator begin() const; + iterator end() const; + bool empty() const { return size() == 0; } + size_t size() const; + + /// Methods for supporting type inquiry through isa, cast, and dyn_cast. static bool kindof(unsigned kind) { - return kind == StandardAttributes::Integer; + return kind == StandardAttributes::Dictionary; } }; @@ -277,114 +290,111 @@ public: Type type, const APFloat &value); }; -class StringAttr : public Attribute::AttrBase<StringAttr, Attribute, - detail::StringAttributeStorage> { +/// A function attribute represents a reference to a function object. +class FunctionAttr + : public Attribute::AttrBase<FunctionAttr, Attribute, + detail::StringAttributeStorage> { public: using Base::Base; - using ValueType = StringRef; + using ValueType = Function *; - static StringAttr get(StringRef bytes, MLIRContext *context); + static FunctionAttr get(Function *value); + static FunctionAttr get(StringRef value, MLIRContext *ctx); + /// Returns the name of the held function reference. StringRef getValue() const; /// Methods for support type inquiry through isa, cast, and dyn_cast. static bool kindof(unsigned kind) { - return kind == StandardAttributes::String; + return kind == StandardAttributes::Function; } }; -/// Array attributes are lists of other attributes. They are not necessarily -/// type homogenous given that attributes don't, in general, carry types. -class ArrayAttr : public Attribute::AttrBase<ArrayAttr, Attribute, - detail::ArrayAttributeStorage> { +class IntegerAttr + : public Attribute::AttrBase<IntegerAttr, Attribute, + detail::IntegerAttributeStorage> { public: using Base::Base; - using ValueType = ArrayRef<Attribute>; - - static ArrayAttr get(ArrayRef<Attribute> value, MLIRContext *context); + using ValueType = APInt; - ArrayRef<Attribute> getValue() const; + static IntegerAttr get(Type type, int64_t value); + static IntegerAttr get(Type type, const APInt &value); - /// Support range iteration. - using iterator = llvm::ArrayRef<Attribute>::iterator; - iterator begin() const { return getValue().begin(); } - iterator end() const { return getValue().end(); } - size_t size() const { return getValue().size(); } + APInt getValue() const; + // TODO(jpienaar): Change callers to use getValue instead. + int64_t getInt() const; /// Methods for support type inquiry through isa, cast, and dyn_cast. static bool kindof(unsigned kind) { - return kind == StandardAttributes::Array; + return kind == StandardAttributes::Integer; } }; -/// NamedAttribute is used for dictionary attributes, it holds an identifier for -/// the name and a value for the attribute. The attribute pointer should always -/// be non-null. -using NamedAttribute = std::pair<Identifier, Attribute>; - -/// Dictionary attribute is an attribute that represents a sorted collection of -/// named attribute values. The elements are sorted by name, and each name must -/// be unique within the collection. -class DictionaryAttr - : public Attribute::AttrBase<DictionaryAttr, Attribute, - detail::DictionaryAttributeStorage> { +class IntegerSetAttr + : public Attribute::AttrBase<IntegerSetAttr, Attribute, + detail::IntegerSetAttributeStorage> { public: using Base::Base; - using ValueType = ArrayRef<NamedAttribute>; - - static DictionaryAttr get(ArrayRef<NamedAttribute> value, - MLIRContext *context); - - ArrayRef<NamedAttribute> getValue() const; + using ValueType = IntegerSet; - /// Return the specified attribute if present, null otherwise. - Attribute get(StringRef name) const; - Attribute get(Identifier name) const; + static IntegerSetAttr get(IntegerSet value); - /// Support range iteration. - using iterator = llvm::ArrayRef<NamedAttribute>::iterator; - iterator begin() const; - iterator end() const; - bool empty() const { return size() == 0; } - size_t size() const; + IntegerSet getValue() const; - /// Methods for supporting type inquiry through isa, cast, and dyn_cast. + /// Methods for support type inquiry through isa, cast, and dyn_cast. static bool kindof(unsigned kind) { - return kind == StandardAttributes::Dictionary; + return kind == StandardAttributes::IntegerSet; } }; -class AffineMapAttr - : public Attribute::AttrBase<AffineMapAttr, Attribute, - detail::AffineMapAttributeStorage> { +/// Opaque attributes represent attributes of non-registered dialects. These are +/// attribute represented in their raw string form, and can only usefully be +/// tested for attribute equality. +class OpaqueAttr : public Attribute::AttrBase<OpaqueAttr, Attribute, + detail::OpaqueAttributeStorage> { public: using Base::Base; - using ValueType = AffineMap; - static AffineMapAttr get(AffineMap value); + /// Get or create a new OpaqueAttr with the provided dialect and string data. + static OpaqueAttr get(Identifier dialect, StringRef attrData, + MLIRContext *context); - AffineMap getValue() const; + /// Get or create a new OpaqueAttr with the provided dialect and string data. + /// If the given identifier is not a valid namespace for a dialect, then a + /// null attribute is returned. + static OpaqueAttr getChecked(Identifier dialect, StringRef attrData, + MLIRContext *context, Location location); + + /// Returns the dialect namespace of the opaque attribute. + Identifier getDialectNamespace() const; + + /// Returns the raw attribute data of the opaque attribute. + StringRef getAttrData() const; + + /// Verify the construction of an opaque attribute. + static LogicalResult + verifyConstructionInvariants(llvm::Optional<Location> loc, + MLIRContext *context, Identifier dialect, + StringRef attrData); - /// Methods for support type inquiry through isa, cast, and dyn_cast. static bool kindof(unsigned kind) { - return kind == StandardAttributes::AffineMap; + return kind == StandardAttributes::Opaque; } }; -class IntegerSetAttr - : public Attribute::AttrBase<IntegerSetAttr, Attribute, - detail::IntegerSetAttributeStorage> { +class StringAttr : public Attribute::AttrBase<StringAttr, Attribute, + detail::StringAttributeStorage> { public: using Base::Base; - using ValueType = IntegerSet; + using ValueType = StringRef; - static IntegerSetAttr get(IntegerSet value); + static StringAttr get(StringRef bytes, MLIRContext *context); - IntegerSet getValue() const; + StringRef getValue() const; /// Methods for support type inquiry through isa, cast, and dyn_cast. static bool kindof(unsigned kind) { - return kind == StandardAttributes::IntegerSet; + return kind == StandardAttributes::String; } }; @@ -402,26 +412,23 @@ public: static bool kindof(unsigned kind) { return kind == StandardAttributes::Type; } }; -/// A function attribute represents a reference to a function object. -class FunctionAttr - : public Attribute::AttrBase<FunctionAttr, Attribute, - detail::StringAttributeStorage> { +/// Unit attributes are attributes that hold no specific value and are given +/// meaning by their existence. +class UnitAttr : public Attribute::AttrBase<UnitAttr> { public: using Base::Base; - using ValueType = Function *; - - static FunctionAttr get(Function *value); - static FunctionAttr get(StringRef value, MLIRContext *ctx); - /// Returns the name of the held function reference. - StringRef getValue() const; - - /// Methods for support type inquiry through isa, cast, and dyn_cast. - static bool kindof(unsigned kind) { - return kind == StandardAttributes::Function; + static UnitAttr get(MLIRContext *context) { + return Base::get(context, StandardAttributes::Unit); } + + static bool kindof(unsigned kind) { return kind == StandardAttributes::Unit; } }; +//===----------------------------------------------------------------------===// +// Elements Attributes +//===----------------------------------------------------------------------===// + /// A base attribute that represents a reference to a static shaped tensor or /// vector constant. class ElementsAttr : public Attribute { @@ -686,30 +693,6 @@ protected: bool isValidIntOrFloat(int64_t dataEltSize, bool isInt) const; }; -/// An attribute that represents a reference to a dense integer vector or tensor -/// object. -class DenseIntElementsAttr : public DenseElementsAttr { -public: - /// DenseIntElementsAttr iterates on APInt, so we can use the raw element - /// iterator directly. - using iterator = DenseElementsAttr::IntElementIterator; - - using DenseElementsAttr::DenseElementsAttr; - - /// Generates a new DenseElementsAttr by mapping each value attribute, and - /// constructing the DenseElementsAttr given the new element type. - DenseElementsAttr - mapValues(Type newElementType, - llvm::function_ref<APInt(const APInt &)> mapping) const; - - /// Iterator access to the integer element values. - iterator begin() const { return raw_int_begin(); } - iterator end() const { return raw_int_end(); } - - /// Method for supporting type inquiry through isa, cast and dyn_cast. - static bool classof(Attribute attr); -}; - /// An attribute that represents a reference to a dense float vector or tensor /// object. Each element is stored as a double. class DenseFPElementsAttr : public DenseElementsAttr { @@ -732,36 +715,28 @@ public: static bool classof(Attribute attr); }; -/// An attribute that represents a reference to a splat vector or tensor -/// constant, meaning all of the elements have the same value. -class SplatElementsAttr : public DenseElementsAttr { +/// An attribute that represents a reference to a dense integer vector or tensor +/// object. +class DenseIntElementsAttr : public DenseElementsAttr { public: - using DenseElementsAttr::DenseElementsAttr; - using ValueType = Attribute; + /// DenseIntElementsAttr iterates on APInt, so we can use the raw element + /// iterator directly. + using iterator = DenseElementsAttr::IntElementIterator; - /// 'type' must be a vector or tensor with static shape. - static SplatElementsAttr get(ShapedType type, Attribute elt); - Attribute getValue() const { return getSplatValue(); } + using DenseElementsAttr::DenseElementsAttr; - /// Generates a new SplatElementsAttr by mapping each int value to a new - /// underlying APInt. The new values can represent either a integer or float. - /// This ElementsAttr should contain integers. - SplatElementsAttr + /// Generates a new DenseElementsAttr by mapping each value attribute, and + /// constructing the DenseElementsAttr given the new element type. + DenseElementsAttr mapValues(Type newElementType, llvm::function_ref<APInt(const APInt &)> mapping) const; - /// Generates a new SplatElementsAttr by mapping each float value to a new - /// underlying APInt. The new values can represent either a integer or float. - /// This ElementsAttr should contain floats. - SplatElementsAttr - mapValues(Type newElementType, - llvm::function_ref<APInt(const APFloat &)> mapping) const; + /// Iterator access to the integer element values. + iterator begin() const { return raw_int_begin(); } + iterator end() const { return raw_int_end(); } - /// Method for support type inquiry through isa, cast and dyn_cast. - static bool classof(Attribute attr) { - auto denseAttr = attr.dyn_cast<DenseElementsAttr>(); - return denseAttr && denseAttr.isSplat(); - } + /// Method for supporting type inquiry through isa, cast and dyn_cast. + static bool classof(Attribute attr); }; /// An opaque attribute that represents a reference to a vector or tensor @@ -840,6 +815,38 @@ public: } }; +/// An attribute that represents a reference to a splat vector or tensor +/// constant, meaning all of the elements have the same value. +class SplatElementsAttr : public DenseElementsAttr { +public: + using DenseElementsAttr::DenseElementsAttr; + using ValueType = Attribute; + + /// 'type' must be a vector or tensor with static shape. + static SplatElementsAttr get(ShapedType type, Attribute elt); + Attribute getValue() const { return getSplatValue(); } + + /// Generates a new SplatElementsAttr by mapping each int value to a new + /// underlying APInt. The new values can represent either a integer or float. + /// This ElementsAttr should contain integers. + SplatElementsAttr + mapValues(Type newElementType, + llvm::function_ref<APInt(const APInt &)> mapping) const; + + /// Generates a new SplatElementsAttr by mapping each float value to a new + /// underlying APInt. The new values can represent either a integer or float. + /// This ElementsAttr should contain floats. + SplatElementsAttr + mapValues(Type newElementType, + llvm::function_ref<APInt(const APFloat &)> mapping) const; + + /// Method for support type inquiry through isa, cast and dyn_cast. + static bool classof(Attribute attr) { + auto denseAttr = attr.dyn_cast<DenseElementsAttr>(); + return denseAttr && denseAttr.isSplat(); + } +}; + template <typename U> bool Attribute::isa() const { assert(impl && "isa<> used on a null attribute."); return U::classof(*this); diff --git a/mlir/lib/IR/AttributeDetail.h b/mlir/lib/IR/AttributeDetail.h index f164f505f33..0fe07a97916 100644 --- a/mlir/lib/IR/AttributeDetail.h +++ b/mlir/lib/IR/AttributeDetail.h @@ -24,7 +24,6 @@ #include "mlir/IR/AffineMap.h" #include "mlir/IR/Attributes.h" -#include "mlir/IR/Function.h" #include "mlir/IR/Identifier.h" #include "mlir/IR/IntegerSet.h" #include "mlir/IR/MLIRContext.h" @@ -36,28 +35,43 @@ namespace mlir { namespace detail { -/// Opaque Attribute Storage and Uniquing. -struct OpaqueAttributeStorage : public AttributeStorage { - OpaqueAttributeStorage(Identifier dialectNamespace, StringRef attrData) - : dialectNamespace(dialectNamespace), attrData(attrData) {} +// An attribute representing a reference to an affine map. +struct AffineMapAttributeStorage : public AttributeStorage { + using KeyTy = AffineMap; - /// The hash key used for uniquing. - using KeyTy = std::pair<Identifier, StringRef>; - bool operator==(const KeyTy &key) const { - return key == KeyTy(dialectNamespace, attrData); - } + AffineMapAttributeStorage(AffineMap value) + : AttributeStorage(IndexType::get(value.getContext())), value(value) {} - static OpaqueAttributeStorage *construct(AttributeStorageAllocator &allocator, - const KeyTy &key) { - return new (allocator.allocate<OpaqueAttributeStorage>()) - OpaqueAttributeStorage(key.first, allocator.copyInto(key.second)); + /// Key equality function. + bool operator==(const KeyTy &key) const { return key == value; } + + /// Construct a new storage instance. + static AffineMapAttributeStorage * + construct(AttributeStorageAllocator &allocator, KeyTy key) { + return new (allocator.allocate<AffineMapAttributeStorage>()) + AffineMapAttributeStorage(key); } - // The dialect namespace. - Identifier dialectNamespace; + AffineMap value; +}; - // The parser attribute data for this opaque attribute. - StringRef attrData; +/// An attribute representing an array of other attributes. +struct ArrayAttributeStorage : public AttributeStorage { + using KeyTy = ArrayRef<Attribute>; + + ArrayAttributeStorage(ArrayRef<Attribute> value) : value(value) {} + + /// Key equality function. + bool operator==(const KeyTy &key) const { return key == value; } + + /// Construct a new storage instance. + static ArrayAttributeStorage *construct(AttributeStorageAllocator &allocator, + const KeyTy &key) { + return new (allocator.allocate<ArrayAttributeStorage>()) + ArrayAttributeStorage(allocator.copyInto(key)); + } + + ArrayRef<Attribute> value; }; /// An attribute representing a boolean value. @@ -82,51 +96,51 @@ struct BoolAttributeStorage : public AttributeStorage { bool value; }; -/// An attribute representing a integral value. -struct IntegerAttributeStorage final +/// An attribute representing a dictionary of sorted named attributes. +struct DictionaryAttributeStorage final : public AttributeStorage, - public llvm::TrailingObjects<IntegerAttributeStorage, uint64_t> { - using KeyTy = std::pair<Type, APInt>; + private llvm::TrailingObjects<DictionaryAttributeStorage, + NamedAttribute> { + using KeyTy = ArrayRef<NamedAttribute>; - IntegerAttributeStorage(Type type, size_t numObjects) - : AttributeStorage(type), numObjects(numObjects) { - assert((type.isIndex() || type.isa<IntegerType>()) && "invalid type"); - } + /// Given a list of NamedAttribute's, canonicalize the list (sorting + /// by name) and return the unique'd result. + static DictionaryAttributeStorage *get(ArrayRef<NamedAttribute> attrs); - /// Key equality and hash functions. - bool operator==(const KeyTy &key) const { - return key == KeyTy(getType(), getValue()); - } - static unsigned hashKey(const KeyTy &key) { - return llvm::hash_combine(key.first, llvm::hash_value(key.second)); - } + /// Key equality function. + bool operator==(const KeyTy &key) const { return key == getElements(); } /// Construct a new storage instance. - static IntegerAttributeStorage * + static DictionaryAttributeStorage * construct(AttributeStorageAllocator &allocator, const KeyTy &key) { - Type type; - APInt value; - std::tie(type, value) = key; + auto size = DictionaryAttributeStorage::totalSizeToAlloc<NamedAttribute>( + key.size()); + auto rawMem = allocator.allocate(size, alignof(NamedAttribute)); - auto elements = ArrayRef<uint64_t>(value.getRawData(), value.getNumWords()); - auto size = - IntegerAttributeStorage::totalSizeToAlloc<uint64_t>(elements.size()); - auto rawMem = allocator.allocate(size, alignof(IntegerAttributeStorage)); - auto result = ::new (rawMem) IntegerAttributeStorage(type, elements.size()); - std::uninitialized_copy(elements.begin(), elements.end(), - result->getTrailingObjects<uint64_t>()); + // Initialize the storage and trailing attribute list. + auto result = ::new (rawMem) DictionaryAttributeStorage(key.size()); + std::uninitialized_copy(key.begin(), key.end(), + result->getTrailingObjects<NamedAttribute>()); return result; } - /// Returns an APInt representing the stored value. - APInt getValue() const { - if (getType().isIndex()) - return APInt(64, {getTrailingObjects<uint64_t>(), numObjects}); - return APInt(getType().getIntOrFloatBitWidth(), - {getTrailingObjects<uint64_t>(), numObjects}); + /// Return the elements of this dictionary attribute. + ArrayRef<NamedAttribute> getElements() const { + return {getTrailingObjects<NamedAttribute>(), numElements}; } - size_t numObjects; +private: + friend class llvm::TrailingObjects<DictionaryAttributeStorage, + NamedAttribute>; + + // This is used by the llvm::TrailingObjects base class. + size_t numTrailingObjects(OverloadToken<NamedAttribute>) const { + return numElements; + } + DictionaryAttributeStorage(unsigned numElements) : numElements(numElements) {} + + /// This is the number of attributes. + const unsigned numElements; }; /// An attribute representing a floating point value. @@ -191,128 +205,113 @@ struct FloatAttributeStorage final size_t numObjects; }; -/// An attribute representing a string value. -struct StringAttributeStorage : public AttributeStorage { - using KeyTy = StringRef; - - StringAttributeStorage(StringRef value) : value(value) {} - - /// Key equality function. - bool operator==(const KeyTy &key) const { return key == value; } +/// An attribute representing a integral value. +struct IntegerAttributeStorage final + : public AttributeStorage, + public llvm::TrailingObjects<IntegerAttributeStorage, uint64_t> { + using KeyTy = std::pair<Type, APInt>; - /// Construct a new storage instance. - static StringAttributeStorage *construct(AttributeStorageAllocator &allocator, - const KeyTy &key) { - return new (allocator.allocate<StringAttributeStorage>()) - StringAttributeStorage(allocator.copyInto(key)); + IntegerAttributeStorage(Type type, size_t numObjects) + : AttributeStorage(type), numObjects(numObjects) { + assert((type.isIndex() || type.isa<IntegerType>()) && "invalid type"); } - StringRef value; -}; - -/// An attribute representing an array of other attributes. -struct ArrayAttributeStorage : public AttributeStorage { - using KeyTy = ArrayRef<Attribute>; - - ArrayAttributeStorage(ArrayRef<Attribute> value) : value(value) {} - - /// Key equality function. - bool operator==(const KeyTy &key) const { return key == value; } - - /// Construct a new storage instance. - static ArrayAttributeStorage *construct(AttributeStorageAllocator &allocator, - const KeyTy &key) { - return new (allocator.allocate<ArrayAttributeStorage>()) - ArrayAttributeStorage(allocator.copyInto(key)); + /// Key equality and hash functions. + bool operator==(const KeyTy &key) const { + return key == KeyTy(getType(), getValue()); + } + static unsigned hashKey(const KeyTy &key) { + return llvm::hash_combine(key.first, llvm::hash_value(key.second)); } - - ArrayRef<Attribute> value; -}; - -/// An attribute representing a dictionary of sorted named attributes. -struct DictionaryAttributeStorage final - : public AttributeStorage, - private llvm::TrailingObjects<DictionaryAttributeStorage, - NamedAttribute> { - using KeyTy = ArrayRef<NamedAttribute>; - - /// Given a list of NamedAttribute's, canonicalize the list (sorting - /// by name) and return the unique'd result. - static DictionaryAttributeStorage *get(ArrayRef<NamedAttribute> attrs); - - /// Key equality function. - bool operator==(const KeyTy &key) const { return key == getElements(); } /// Construct a new storage instance. - static DictionaryAttributeStorage * + static IntegerAttributeStorage * construct(AttributeStorageAllocator &allocator, const KeyTy &key) { - auto size = DictionaryAttributeStorage::totalSizeToAlloc<NamedAttribute>( - key.size()); - auto rawMem = allocator.allocate(size, alignof(NamedAttribute)); + Type type; + APInt value; + std::tie(type, value) = key; - // Initialize the storage and trailing attribute list. - auto result = ::new (rawMem) DictionaryAttributeStorage(key.size()); - std::uninitialized_copy(key.begin(), key.end(), - result->getTrailingObjects<NamedAttribute>()); + auto elements = ArrayRef<uint64_t>(value.getRawData(), value.getNumWords()); + auto size = + IntegerAttributeStorage::totalSizeToAlloc<uint64_t>(elements.size()); + auto rawMem = allocator.allocate(size, alignof(IntegerAttributeStorage)); + auto result = ::new (rawMem) IntegerAttributeStorage(type, elements.size()); + std::uninitialized_copy(elements.begin(), elements.end(), + result->getTrailingObjects<uint64_t>()); return result; } - /// Return the elements of this dictionary attribute. - ArrayRef<NamedAttribute> getElements() const { - return {getTrailingObjects<NamedAttribute>(), numElements}; - } - -private: - friend class llvm::TrailingObjects<DictionaryAttributeStorage, - NamedAttribute>; - - // This is used by the llvm::TrailingObjects base class. - size_t numTrailingObjects(OverloadToken<NamedAttribute>) const { - return numElements; + /// Returns an APInt representing the stored value. + APInt getValue() const { + if (getType().isIndex()) + return APInt(64, {getTrailingObjects<uint64_t>(), numObjects}); + return APInt(getType().getIntOrFloatBitWidth(), + {getTrailingObjects<uint64_t>(), numObjects}); } - DictionaryAttributeStorage(unsigned numElements) : numElements(numElements) {} - /// This is the number of attributes. - const unsigned numElements; + size_t numObjects; }; -// An attribute representing a reference to an affine map. -struct AffineMapAttributeStorage : public AttributeStorage { - using KeyTy = AffineMap; +// An attribute representing a reference to an integer set. +struct IntegerSetAttributeStorage : public AttributeStorage { + using KeyTy = IntegerSet; - AffineMapAttributeStorage(AffineMap value) - : AttributeStorage(IndexType::get(value.getContext())), value(value) {} + IntegerSetAttributeStorage(IntegerSet value) : value(value) {} /// Key equality function. bool operator==(const KeyTy &key) const { return key == value; } /// Construct a new storage instance. - static AffineMapAttributeStorage * + static IntegerSetAttributeStorage * construct(AttributeStorageAllocator &allocator, KeyTy key) { - return new (allocator.allocate<AffineMapAttributeStorage>()) - AffineMapAttributeStorage(key); + return new (allocator.allocate<IntegerSetAttributeStorage>()) + IntegerSetAttributeStorage(key); } - AffineMap value; + IntegerSet value; }; -// An attribute representing a reference to an integer set. -struct IntegerSetAttributeStorage : public AttributeStorage { - using KeyTy = IntegerSet; +/// Opaque Attribute Storage and Uniquing. +struct OpaqueAttributeStorage : public AttributeStorage { + OpaqueAttributeStorage(Identifier dialectNamespace, StringRef attrData) + : dialectNamespace(dialectNamespace), attrData(attrData) {} - IntegerSetAttributeStorage(IntegerSet value) : value(value) {} + /// The hash key used for uniquing. + using KeyTy = std::pair<Identifier, StringRef>; + bool operator==(const KeyTy &key) const { + return key == KeyTy(dialectNamespace, attrData); + } + + static OpaqueAttributeStorage *construct(AttributeStorageAllocator &allocator, + const KeyTy &key) { + return new (allocator.allocate<OpaqueAttributeStorage>()) + OpaqueAttributeStorage(key.first, allocator.copyInto(key.second)); + } + + // The dialect namespace. + Identifier dialectNamespace; + + // The parser attribute data for this opaque attribute. + StringRef attrData; +}; + +/// An attribute representing a string value. +struct StringAttributeStorage : public AttributeStorage { + using KeyTy = StringRef; + + StringAttributeStorage(StringRef value) : value(value) {} /// Key equality function. bool operator==(const KeyTy &key) const { return key == value; } /// Construct a new storage instance. - static IntegerSetAttributeStorage * - construct(AttributeStorageAllocator &allocator, KeyTy key) { - return new (allocator.allocate<IntegerSetAttributeStorage>()) - IntegerSetAttributeStorage(key); + static StringAttributeStorage *construct(AttributeStorageAllocator &allocator, + const KeyTy &key) { + return new (allocator.allocate<StringAttributeStorage>()) + StringAttributeStorage(allocator.copyInto(key)); } - IntegerSet value; + StringRef value; }; /// An attribute representing a reference to a type. @@ -334,28 +333,9 @@ struct TypeAttributeStorage : public AttributeStorage { Type value; }; -/// An attribute representing a reference to a vector or tensor constant, -/// inwhich all elements have the same value. -struct SplatElementsAttributeStorage : public AttributeStorage { - using KeyTy = std::pair<Type, Attribute>; - - SplatElementsAttributeStorage(Type type, Attribute elt) - : AttributeStorage(type), elt(elt) {} - - /// Key equality and hash functions. - bool operator==(const KeyTy &key) const { - return key == std::make_pair(getType(), elt); - } - - /// Construct a new storage instance. - static SplatElementsAttributeStorage * - construct(AttributeStorageAllocator &allocator, KeyTy key) { - return new (allocator.allocate<SplatElementsAttributeStorage>()) - SplatElementsAttributeStorage(key.first, key.second); - } - - Attribute elt; -}; +//===----------------------------------------------------------------------===// +// Elements Attributes +//===----------------------------------------------------------------------===// /// An attribute representing a reference to a dense vector or tensor object. struct DenseElementsAttributeStorage : public AttributeStorage { diff --git a/mlir/lib/IR/Attributes.cpp b/mlir/lib/IR/Attributes.cpp index bbf89958213..ce33508830c 100644 --- a/mlir/lib/IR/Attributes.cpp +++ b/mlir/lib/IR/Attributes.cpp @@ -57,41 +57,26 @@ MLIRContext *Attribute::getContext() const { return getType().getContext(); } Dialect &Attribute::getDialect() const { return impl->getDialect(); } //===----------------------------------------------------------------------===// -// OpaqueAttr +// AffineMapAttr //===----------------------------------------------------------------------===// -OpaqueAttr OpaqueAttr::get(Identifier dialect, StringRef attrData, - MLIRContext *context) { - return Base::get(context, StandardAttributes::Opaque, dialect, attrData); -} - -OpaqueAttr OpaqueAttr::getChecked(Identifier dialect, StringRef attrData, - MLIRContext *context, Location location) { - return Base::getChecked(location, context, StandardAttributes::Opaque, - dialect, attrData); +AffineMapAttr AffineMapAttr::get(AffineMap value) { + return Base::get(value.getResult(0).getContext(), + StandardAttributes::AffineMap, value); } -/// Returns the dialect namespace of the opaque attribute. -Identifier OpaqueAttr::getDialectNamespace() const { - return getImpl()->dialectNamespace; -} +AffineMap AffineMapAttr::getValue() const { return getImpl()->value; } -/// Returns the raw attribute data of the opaque attribute. -StringRef OpaqueAttr::getAttrData() const { return getImpl()->attrData; } +//===----------------------------------------------------------------------===// +// ArrayAttr +//===----------------------------------------------------------------------===// -/// Verify the construction of an opaque attribute. -LogicalResult OpaqueAttr::verifyConstructionInvariants( - llvm::Optional<Location> loc, MLIRContext *context, Identifier dialect, - StringRef attrData) { - if (!Dialect::isValidNamespace(dialect.strref())) { - if (loc) - context->emitError(*loc) - << "invalid dialect namespace '" << dialect << "'"; - return failure(); - } - return success(); +ArrayAttr ArrayAttr::get(ArrayRef<Attribute> value, MLIRContext *context) { + return Base::get(context, StandardAttributes::Array, value); } +ArrayRef<Attribute> ArrayAttr::getValue() const { return getImpl()->value; } + //===----------------------------------------------------------------------===// // BoolAttr //===----------------------------------------------------------------------===// @@ -196,27 +181,6 @@ DictionaryAttr::iterator DictionaryAttr::end() const { size_t DictionaryAttr::size() const { return getValue().size(); } //===----------------------------------------------------------------------===// -// IntegerAttr -//===----------------------------------------------------------------------===// - -IntegerAttr IntegerAttr::get(Type type, const APInt &value) { - return Base::get(type.getContext(), StandardAttributes::Integer, type, value); -} - -IntegerAttr IntegerAttr::get(Type type, int64_t value) { - // This uses 64 bit APInts by default for index type. - if (type.isIndex()) - return get(type, APInt(64, value)); - - auto intType = type.cast<IntegerType>(); - return get(type, APInt(intType.getWidth(), value)); -} - -APInt IntegerAttr::getValue() const { return getImpl()->getValue(); } - -int64_t IntegerAttr::getInt() const { return getValue().getSExtValue(); } - -//===----------------------------------------------------------------------===// // FloatAttr //===----------------------------------------------------------------------===// @@ -287,35 +251,40 @@ FloatAttr::verifyConstructionInvariants(llvm::Optional<Location> loc, } //===----------------------------------------------------------------------===// -// StringAttr +// FunctionAttr //===----------------------------------------------------------------------===// -StringAttr StringAttr::get(StringRef bytes, MLIRContext *context) { - return Base::get(context, StandardAttributes::String, bytes); +FunctionAttr FunctionAttr::get(Function *value) { + assert(value && "Cannot get FunctionAttr for a null function"); + return get(value->getName(), value->getContext()); } -StringRef StringAttr::getValue() const { return getImpl()->value; } +FunctionAttr FunctionAttr::get(StringRef value, MLIRContext *ctx) { + return Base::get(ctx, StandardAttributes::Function, value); +} + +StringRef FunctionAttr::getValue() const { return getImpl()->value; } //===----------------------------------------------------------------------===// -// ArrayAttr +// IntegerAttr //===----------------------------------------------------------------------===// -ArrayAttr ArrayAttr::get(ArrayRef<Attribute> value, MLIRContext *context) { - return Base::get(context, StandardAttributes::Array, value); +IntegerAttr IntegerAttr::get(Type type, const APInt &value) { + return Base::get(type.getContext(), StandardAttributes::Integer, type, value); } -ArrayRef<Attribute> ArrayAttr::getValue() const { return getImpl()->value; } - -//===----------------------------------------------------------------------===// -// AffineMapAttr -//===----------------------------------------------------------------------===// +IntegerAttr IntegerAttr::get(Type type, int64_t value) { + // This uses 64 bit APInts by default for index type. + if (type.isIndex()) + return get(type, APInt(64, value)); -AffineMapAttr AffineMapAttr::get(AffineMap value) { - return Base::get(value.getResult(0).getContext(), - StandardAttributes::AffineMap, value); + auto intType = type.cast<IntegerType>(); + return get(type, APInt(intType.getWidth(), value)); } -AffineMap AffineMapAttr::getValue() const { return getImpl()->value; } +APInt IntegerAttr::getValue() const { return getImpl()->getValue(); } + +int64_t IntegerAttr::getInt() const { return getValue().getSExtValue(); } //===----------------------------------------------------------------------===// // IntegerSetAttr @@ -329,29 +298,60 @@ IntegerSetAttr IntegerSetAttr::get(IntegerSet value) { IntegerSet IntegerSetAttr::getValue() const { return getImpl()->value; } //===----------------------------------------------------------------------===// -// TypeAttr +// OpaqueAttr //===----------------------------------------------------------------------===// -TypeAttr TypeAttr::get(Type value) { - return Base::get(value.getContext(), StandardAttributes::Type, value); +OpaqueAttr OpaqueAttr::get(Identifier dialect, StringRef attrData, + MLIRContext *context) { + return Base::get(context, StandardAttributes::Opaque, dialect, attrData); } -Type TypeAttr::getValue() const { return getImpl()->value; } +OpaqueAttr OpaqueAttr::getChecked(Identifier dialect, StringRef attrData, + MLIRContext *context, Location location) { + return Base::getChecked(location, context, StandardAttributes::Opaque, + dialect, attrData); +} + +/// Returns the dialect namespace of the opaque attribute. +Identifier OpaqueAttr::getDialectNamespace() const { + return getImpl()->dialectNamespace; +} + +/// Returns the raw attribute data of the opaque attribute. +StringRef OpaqueAttr::getAttrData() const { return getImpl()->attrData; } + +/// Verify the construction of an opaque attribute. +LogicalResult OpaqueAttr::verifyConstructionInvariants( + llvm::Optional<Location> loc, MLIRContext *context, Identifier dialect, + StringRef attrData) { + if (!Dialect::isValidNamespace(dialect.strref())) { + if (loc) + context->emitError(*loc) + << "invalid dialect namespace '" << dialect << "'"; + return failure(); + } + return success(); +} //===----------------------------------------------------------------------===// -// FunctionAttr +// StringAttr //===----------------------------------------------------------------------===// -FunctionAttr FunctionAttr::get(Function *value) { - assert(value && "Cannot get FunctionAttr for a null function"); - return get(value->getName(), value->getContext()); +StringAttr StringAttr::get(StringRef bytes, MLIRContext *context) { + return Base::get(context, StandardAttributes::String, bytes); } -FunctionAttr FunctionAttr::get(StringRef value, MLIRContext *ctx) { - return Base::get(ctx, StandardAttributes::Function, value); +StringRef StringAttr::getValue() const { return getImpl()->value; } + +//===----------------------------------------------------------------------===// +// TypeAttr +//===----------------------------------------------------------------------===// + +TypeAttr TypeAttr::get(Type value) { + return Base::get(value.getContext(), StandardAttributes::Type, value); } -StringRef FunctionAttr::getValue() const { return getImpl()->value; } +Type TypeAttr::getValue() const { return getImpl()->value; } //===----------------------------------------------------------------------===// // ElementsAttr @@ -399,28 +399,6 @@ ElementsAttr ElementsAttr::mapValues( } //===----------------------------------------------------------------------===// -// SplatElementsAttr -//===----------------------------------------------------------------------===// - -SplatElementsAttr SplatElementsAttr::get(ShapedType type, Attribute elt) { - return DenseElementsAttr::get(type, elt).cast<SplatElementsAttr>(); -} - -SplatElementsAttr SplatElementsAttr::mapValues( - Type newElementType, - llvm::function_ref<APInt(const APInt &)> mapping) const { - return DenseElementsAttr::mapValues(newElementType, mapping) - .cast<SplatElementsAttr>(); -} - -SplatElementsAttr SplatElementsAttr::mapValues( - Type newElementType, - llvm::function_ref<APInt(const APFloat &)> mapping) const { - return DenseElementsAttr::mapValues(newElementType, mapping) - .cast<SplatElementsAttr>(); -} - -//===----------------------------------------------------------------------===// // DenseElementAttr Utilities //===----------------------------------------------------------------------===// @@ -787,7 +765,7 @@ DenseElementsAttr DenseElementsAttr::mapValues( } //===----------------------------------------------------------------------===// -// DenseIntElementsAttr +// DenseFPElementsAttr //===----------------------------------------------------------------------===// template <typename Fn, typename Attr> @@ -820,9 +798,9 @@ static ShapedType mappingHelper(Fn mapping, Attr &attr, ShapedType inType, return newArrayType; } -DenseElementsAttr DenseIntElementsAttr::mapValues( +DenseElementsAttr DenseFPElementsAttr::mapValues( Type newElementType, - llvm::function_ref<APInt(const APInt &)> mapping) const { + llvm::function_ref<APInt(const APFloat &)> mapping) const { llvm::SmallVector<char, 8> elementData; auto newArrayType = mappingHelper(mapping, *this, getType(), newElementType, elementData); @@ -831,18 +809,18 @@ DenseElementsAttr DenseIntElementsAttr::mapValues( } /// Method for supporting type inquiry through isa, cast and dyn_cast. -bool DenseIntElementsAttr::classof(Attribute attr) { +bool DenseFPElementsAttr::classof(Attribute attr) { return attr.isa<DenseElementsAttr>() && - attr.getType().cast<ShapedType>().getElementType().isa<IntegerType>(); + attr.getType().cast<ShapedType>().getElementType().isa<FloatType>(); } //===----------------------------------------------------------------------===// -// DenseFPElementsAttr +// DenseIntElementsAttr //===----------------------------------------------------------------------===// -DenseElementsAttr DenseFPElementsAttr::mapValues( +DenseElementsAttr DenseIntElementsAttr::mapValues( Type newElementType, - llvm::function_ref<APInt(const APFloat &)> mapping) const { + llvm::function_ref<APInt(const APInt &)> mapping) const { llvm::SmallVector<char, 8> elementData; auto newArrayType = mappingHelper(mapping, *this, getType(), newElementType, elementData); @@ -851,9 +829,9 @@ DenseElementsAttr DenseFPElementsAttr::mapValues( } /// Method for supporting type inquiry through isa, cast and dyn_cast. -bool DenseFPElementsAttr::classof(Attribute attr) { +bool DenseIntElementsAttr::classof(Attribute attr) { return attr.isa<DenseElementsAttr>() && - attr.getType().cast<ShapedType>().getElementType().isa<FloatType>(); + attr.getType().cast<ShapedType>().getElementType().isa<IntegerType>(); } //===----------------------------------------------------------------------===// @@ -963,6 +941,28 @@ Attribute SparseElementsAttr::getValue(ArrayRef<uint64_t> index) const { } //===----------------------------------------------------------------------===// +// SplatElementsAttr +//===----------------------------------------------------------------------===// + +SplatElementsAttr SplatElementsAttr::get(ShapedType type, Attribute elt) { + return DenseElementsAttr::get(type, elt).cast<SplatElementsAttr>(); +} + +SplatElementsAttr SplatElementsAttr::mapValues( + Type newElementType, + llvm::function_ref<APInt(const APInt &)> mapping) const { + return DenseElementsAttr::mapValues(newElementType, mapping) + .cast<SplatElementsAttr>(); +} + +SplatElementsAttr SplatElementsAttr::mapValues( + Type newElementType, + llvm::function_ref<APInt(const APFloat &)> mapping) const { + return DenseElementsAttr::mapValues(newElementType, mapping) + .cast<SplatElementsAttr>(); +} + +//===----------------------------------------------------------------------===// // NamedAttributeList //===----------------------------------------------------------------------===// |