[Mlir-commits] [mlir] 2f37cdd - [mlir][IR][NFC] Move a majority of the builtin attributes to ODS
River Riddle
llvmlistbot at llvm.org
Thu Mar 4 13:04:16 PST 2021
Author: River Riddle
Date: 2021-03-04T13:04:06-08:00
New Revision: 2f37cdd5699f65cf6b9da615337cad6fdb012304
URL: https://github.com/llvm/llvm-project/commit/2f37cdd5699f65cf6b9da615337cad6fdb012304
DIFF: https://github.com/llvm/llvm-project/commit/2f37cdd5699f65cf6b9da615337cad6fdb012304.diff
LOG: [mlir][IR][NFC] Move a majority of the builtin attributes to ODS
Now that attributes can be generated using ODS, we can move the builtin attributes as well. This revision removes a majority of the builtin attributes with a few left for followup revisions. The attributes moved to ODS in this revision are: AffineMapAttr, ArrayAttr, DictionaryAttr, IntegerSetAttr, StringAttr, SymbolRefAttr, TypeAttr, and UnitAttr.
Differential Revision: https://reviews.llvm.org/D97591
Added:
mlir/include/mlir/IR/BuiltinAttributes.td
Modified:
mlir/include/mlir/IR/BuiltinAttributes.h
mlir/include/mlir/IR/CMakeLists.txt
mlir/lib/IR/AttributeDetail.h
mlir/lib/IR/BuiltinAttributes.cpp
mlir/lib/IR/CMakeLists.txt
mlir/lib/IR/MLIRContext.cpp
mlir/lib/IR/OperationSupport.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/IR/BuiltinAttributes.h b/mlir/include/mlir/IR/BuiltinAttributes.h
index ab9aa8d8fc89..99bb2b68cc62 100644
--- a/mlir/include/mlir/IR/BuiltinAttributes.h
+++ b/mlir/include/mlir/IR/BuiltinAttributes.h
@@ -16,21 +16,29 @@
namespace mlir {
class AffineMap;
+class FlatSymbolRefAttr;
class FunctionType;
class IntegerSet;
class Location;
class ShapedType;
+} // namespace mlir
+
+//===----------------------------------------------------------------------===//
+// Tablegen Attribute Declarations
+//===----------------------------------------------------------------------===//
+
+#define GET_ATTRDEF_CLASSES
+#include "mlir/IR/BuiltinAttributes.h.inc"
+
+//===----------------------------------------------------------------------===//
+// C++ Attribute Declarations
+//===----------------------------------------------------------------------===//
+namespace mlir {
namespace detail {
-struct AffineMapAttributeStorage;
-struct ArrayAttributeStorage;
-struct DictionaryAttributeStorage;
struct IntegerAttributeStorage;
-struct IntegerSetAttributeStorage;
struct FloatAttributeStorage;
-struct OpaqueAttributeStorage;
-struct StringAttributeStorage;
struct SymbolRefAttributeStorage;
struct TypeAttributeStorage;
@@ -41,139 +49,6 @@ struct OpaqueElementsAttributeStorage;
struct SparseElementsAttributeStorage;
} // namespace detail
-//===----------------------------------------------------------------------===//
-// AffineMapAttr
-//===----------------------------------------------------------------------===//
-
-class AffineMapAttr
- : public Attribute::AttrBase<AffineMapAttr, Attribute,
- detail::AffineMapAttributeStorage> {
-public:
- using Base::Base;
- using ValueType = AffineMap;
-
- static AffineMapAttr get(AffineMap value);
-
- AffineMap getValue() const;
-};
-
-//===----------------------------------------------------------------------===//
-// ArrayAttr
-//===----------------------------------------------------------------------===//
-
-/// 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>;
-
- static ArrayAttr get(MLIRContext *context, ArrayRef<Attribute> value);
-
- ArrayRef<Attribute> getValue() const;
- Attribute operator[](unsigned idx) const;
-
- /// 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(); }
- bool empty() const { return size() == 0; }
-
-private:
- /// Class for underlying value iterator support.
- template <typename AttrTy>
- class attr_value_iterator final
- : public llvm::mapped_iterator<ArrayAttr::iterator,
- AttrTy (*)(Attribute)> {
- public:
- explicit attr_value_iterator(ArrayAttr::iterator it)
- : llvm::mapped_iterator<ArrayAttr::iterator, AttrTy (*)(Attribute)>(
- it, [](Attribute attr) { return attr.cast<AttrTy>(); }) {}
- AttrTy operator*() const { return (*this->I).template cast<AttrTy>(); }
- };
-
-public:
- template <typename AttrTy>
- iterator_range<attr_value_iterator<AttrTy>> getAsRange() {
- return llvm::make_range(attr_value_iterator<AttrTy>(begin()),
- attr_value_iterator<AttrTy>(end()));
- }
- template <typename AttrTy, typename UnderlyingTy = typename AttrTy::ValueType>
- auto getAsValueRange() {
- return llvm::map_range(getAsRange<AttrTy>(), [](AttrTy attr) {
- return static_cast<UnderlyingTy>(attr.getValue());
- });
- }
-};
-
-//===----------------------------------------------------------------------===//
-// DictionaryAttr
-//===----------------------------------------------------------------------===//
-
-/// 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 = ArrayRef<NamedAttribute>;
-
- /// Construct a dictionary attribute with the provided list of named
- /// attributes. This method assumes that the provided list is unordered. If
- /// the caller can guarantee that the attributes are ordered by name,
- /// getWithSorted should be used instead.
- static DictionaryAttr get(MLIRContext *context,
- ArrayRef<NamedAttribute> value);
-
- /// Construct a dictionary with an array of values that is known to already be
- /// sorted by name and uniqued.
- static DictionaryAttr getWithSorted(ArrayRef<NamedAttribute> value,
- MLIRContext *context);
-
- ArrayRef<NamedAttribute> getValue() const;
-
- /// Return the specified attribute if present, null otherwise.
- Attribute get(StringRef name) const;
- Attribute get(Identifier name) const;
-
- /// Return the specified named attribute if present, None otherwise.
- Optional<NamedAttribute> getNamed(StringRef name) const;
- Optional<NamedAttribute> getNamed(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;
-
- /// Sorts the NamedAttributes in the array ordered by name as expected by
- /// getWithSorted and returns whether the values were sorted.
- /// Requires: uniquely named attributes.
- static bool sort(ArrayRef<NamedAttribute> values,
- SmallVectorImpl<NamedAttribute> &storage);
-
- /// Sorts the NamedAttributes in the array ordered by name as expected by
- /// getWithSorted in place on an array and returns whether the values needed
- /// to be sorted.
- /// Requires: uniquely named attributes.
- static bool sortInPlace(SmallVectorImpl<NamedAttribute> &array);
-
- /// Returns an entry with a duplicate name in `array`, if it exists, else
- /// returns llvm::None. If `isSorted` is true, the array is assumed to be
- /// sorted else it will be sorted in place before finding the duplicate entry.
- static Optional<NamedAttribute>
- findDuplicate(SmallVectorImpl<NamedAttribute> &array, bool isSorted);
-
-private:
- /// Return empty dictionary.
- static DictionaryAttr getEmpty(MLIRContext *context);
-};
-
//===----------------------------------------------------------------------===//
// FloatAttr
//===----------------------------------------------------------------------===//
@@ -267,110 +142,9 @@ class BoolAttr : public Attribute {
};
//===----------------------------------------------------------------------===//
-// IntegerSetAttr
-//===----------------------------------------------------------------------===//
-
-class IntegerSetAttr
- : public Attribute::AttrBase<IntegerSetAttr, Attribute,
- detail::IntegerSetAttributeStorage> {
-public:
- using Base::Base;
- using ValueType = IntegerSet;
-
- static IntegerSetAttr get(IntegerSet value);
-
- IntegerSet getValue() const;
-};
-
-//===----------------------------------------------------------------------===//
-// OpaqueAttr
-//===----------------------------------------------------------------------===//
-
-/// 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 Base::getChecked;
-
- /// Get or create a new OpaqueAttr with the provided dialect and string data.
- static OpaqueAttr get(Identifier dialect, StringRef attrData, Type type);
-
- /// 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(function_ref<InFlightDiagnostic()> emitError,
- Identifier dialect, StringRef attrData,
- Type type);
-
- /// 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 verify(function_ref<InFlightDiagnostic()> emitError,
- Identifier dialect, StringRef attrData,
- Type type);
-};
-
-//===----------------------------------------------------------------------===//
-// StringAttr
-//===----------------------------------------------------------------------===//
-
-class StringAttr : public Attribute::AttrBase<StringAttr, Attribute,
- detail::StringAttributeStorage> {
-public:
- using Base::Base;
- using ValueType = StringRef;
-
- /// Get an instance of a StringAttr with the given string.
- static StringAttr get(MLIRContext *context, StringRef bytes);
-
- /// Get an instance of a StringAttr with the given string and Type.
- static StringAttr get(StringRef bytes, Type type);
-
- StringRef getValue() const;
-};
-
-//===----------------------------------------------------------------------===//
-// SymbolRefAttr
+// FlatSymbolRefAttr
//===----------------------------------------------------------------------===//
-class FlatSymbolRefAttr;
-
-/// A symbol reference attribute represents a symbolic reference to another
-/// operation.
-class SymbolRefAttr
- : public Attribute::AttrBase<SymbolRefAttr, Attribute,
- detail::SymbolRefAttributeStorage> {
-public:
- using Base::Base;
-
- /// Construct a symbol reference for the given value name.
- static FlatSymbolRefAttr get(MLIRContext *ctx, StringRef value);
-
- /// Construct a symbol reference for the given value name, and a set of nested
- /// references that are further resolve to a nested symbol.
- static SymbolRefAttr get(MLIRContext *ctx, StringRef value,
- ArrayRef<FlatSymbolRefAttr> references);
-
- /// Returns the name of the top level symbol reference, i.e. the root of the
- /// reference path.
- StringRef getRootReference() const;
-
- /// Returns the name of the fully resolved symbol, i.e. the leaf of the
- /// reference path.
- StringRef getLeafReference() const;
-
- /// Returns the set of nested references representing the path to the symbol
- /// nested under the root reference.
- ArrayRef<FlatSymbolRefAttr> getNestedReferences() const;
-};
-
/// A symbol reference with a reference path containing a single element. This
/// is used to refer to an operation within the current symbol table.
class FlatSymbolRefAttr : public SymbolRefAttr {
@@ -397,35 +171,6 @@ class FlatSymbolRefAttr : public SymbolRefAttr {
using SymbolRefAttr::getNestedReferences;
};
-//===----------------------------------------------------------------------===//
-// Type
-//===----------------------------------------------------------------------===//
-
-class TypeAttr : public Attribute::AttrBase<TypeAttr, Attribute,
- detail::TypeAttributeStorage> {
-public:
- using Base::Base;
- using ValueType = Type;
-
- static TypeAttr get(Type value);
-
- Type getValue() const;
-};
-
-//===----------------------------------------------------------------------===//
-// UnitAttr
-//===----------------------------------------------------------------------===//
-
-/// Unit attributes are attributes that hold no specific value and are given
-/// meaning by their existence.
-class UnitAttr
- : public Attribute::AttrBase<UnitAttr, Attribute, AttributeStorage> {
-public:
- using Base::Base;
-
- static UnitAttr get(MLIRContext *context);
-};
-
//===----------------------------------------------------------------------===//
// Elements Attributes
//===----------------------------------------------------------------------===//
@@ -1460,6 +1205,10 @@ auto ElementsAttr::getValues() const -> iterator_range<T> {
} // end namespace mlir.
+//===----------------------------------------------------------------------===//
+// Attribute Utilities
+//===----------------------------------------------------------------------===//
+
namespace llvm {
template <>
diff --git a/mlir/include/mlir/IR/BuiltinAttributes.td b/mlir/include/mlir/IR/BuiltinAttributes.td
new file mode 100644
index 000000000000..c9911e5b9717
--- /dev/null
+++ b/mlir/include/mlir/IR/BuiltinAttributes.td
@@ -0,0 +1,448 @@
+//===- BuiltinAttributes.td - Builtin attr definitions -----*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the set of builtin MLIR types, or the set of types necessary for the
+// validity of and defining the IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BUILTIN_ATTRIBUTES
+#define BUILTIN_ATTRIBUTES
+
+include "mlir/IR/BuiltinDialect.td"
+
+// TODO: Currently the attributes defined in this file are prefixed with
+// `Builtin_`. This is to
diff erentiate the attributes here with the ones in
+// OpBase.td. We should remove the definitions in OpBase.td, and repoint users
+// to this file instead.
+
+// Base class for Builtin dialect attributes.
+class Builtin_Attr<string name> : AttrDef<Builtin_Dialect, name> {
+ let mnemonic = ?;
+}
+
+//===----------------------------------------------------------------------===//
+// AffineMapAttr
+//===----------------------------------------------------------------------===//
+
+def Builtin_AffineMapAttr : Builtin_Attr<"AffineMap"> {
+ let summary = "An Attribute containing an AffineMap object";
+ let description = [{
+ Syntax:
+
+ ```
+ affine-map-attribute ::= `affine_map` `<` affine-map `>`
+ ```
+
+ Examples:
+
+ ```mlir
+ affine_map<(d0) -> (d0)>
+ affine_map<(d0, d1, d2) -> (d0, d1)>
+ ```
+ }];
+ let parameters = (ins "AffineMap":$value);
+ let builders = [
+ AttrBuilderWithInferredContext<(ins "AffineMap":$value), [{
+ return $_get(value.getContext(), value);
+ }]>
+ ];
+ let extraClassDeclaration = "using ValueType = AffineMap;";
+ let skipDefaultBuilders = 1;
+ let typeBuilder = "IndexType::get($_value.getContext())";
+}
+
+//===----------------------------------------------------------------------===//
+// ArrayAttr
+//===----------------------------------------------------------------------===//
+
+def Builtin_ArrayAttr : Builtin_Attr<"Array"> {
+ let summary = "A collection of other Attribute values";
+ let description = [{
+ Syntax:
+
+ ```
+ array-attribute ::= `[` (attribute-value (`,` attribute-value)*)? `]`
+ ```
+
+ An array attribute is an attribute that represents a collection of attribute
+ values.
+
+ Examples:
+
+ ```mlir
+ []
+ [10, i32]
+ [affine_map<(d0, d1, d2) -> (d0, d1)>, i32, "string attribute"]
+ ```
+ }];
+ let parameters = (ins ArrayRefParameter<"Attribute", "">:$value);
+ let extraClassDeclaration = [{
+ using ValueType = ArrayRef<Attribute>;
+
+ /// Return the element at the given index.
+ Attribute operator[](unsigned idx) const {
+ assert(idx < size() && "index out of bounds");
+ return getValue()[idx];
+ }
+
+ /// 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(); }
+ bool empty() const { return size() == 0; }
+
+ private:
+ /// Class for underlying value iterator support.
+ template <typename AttrTy>
+ class attr_value_iterator final
+ : public llvm::mapped_iterator<ArrayAttr::iterator,
+ AttrTy (*)(Attribute)> {
+ public:
+ explicit attr_value_iterator(ArrayAttr::iterator it)
+ : llvm::mapped_iterator<ArrayAttr::iterator, AttrTy (*)(Attribute)>(
+ it, [](Attribute attr) { return attr.cast<AttrTy>(); }) {}
+ AttrTy operator*() const { return (*this->I).template cast<AttrTy>(); }
+ };
+
+ public:
+ template <typename AttrTy>
+ iterator_range<attr_value_iterator<AttrTy>> getAsRange() {
+ return llvm::make_range(attr_value_iterator<AttrTy>(begin()),
+ attr_value_iterator<AttrTy>(end()));
+ }
+ template <typename AttrTy,
+ typename UnderlyingTy = typename AttrTy::ValueType>
+ auto getAsValueRange() {
+ return llvm::map_range(getAsRange<AttrTy>(), [](AttrTy attr) {
+ return static_cast<UnderlyingTy>(attr.getValue());
+ });
+ }
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// DictionaryAttr
+//===----------------------------------------------------------------------===//
+
+def Builtin_DictionaryAttr : Builtin_Attr<"Dictionary"> {
+ let summary = "An dictionary of named Attribute values";
+ let description = [{
+ Syntax:
+
+ ```
+ dictionary-attribute ::= `{` (attribute-entry (`,` attribute-entry)*)? `}`
+ ```
+
+ A 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.
+
+ Examples:
+
+ ```mlir
+ {}
+ {attr_name = "string attribute"}
+ {int_attr = 10, "string attr name" = "string attribute"}
+ ```
+ }];
+ let parameters = (ins ArrayRefParameter<"NamedAttribute", "">:$value);
+ let builders = [
+ AttrBuilder<(ins "ArrayRef<NamedAttribute>":$value)>
+ ];
+ let extraClassDeclaration = [{
+ using ValueType = ArrayRef<NamedAttribute>;
+
+ /// Construct a dictionary with an array of values that is known to already
+ /// be sorted by name and uniqued.
+ static DictionaryAttr getWithSorted(MLIRContext *context,
+ ArrayRef<NamedAttribute> value);
+
+ /// Return the specified attribute if present, null otherwise.
+ Attribute get(StringRef name) const;
+ Attribute get(Identifier name) const;
+
+ /// Return the specified named attribute if present, None otherwise.
+ Optional<NamedAttribute> getNamed(StringRef name) const;
+ Optional<NamedAttribute> getNamed(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;
+
+ /// Sorts the NamedAttributes in the array ordered by name as expected by
+ /// getWithSorted and returns whether the values were sorted.
+ /// Requires: uniquely named attributes.
+ static bool sort(ArrayRef<NamedAttribute> values,
+ SmallVectorImpl<NamedAttribute> &storage);
+
+ /// Sorts the NamedAttributes in the array ordered by name as expected by
+ /// getWithSorted in place on an array and returns whether the values needed
+ /// to be sorted.
+ /// Requires: uniquely named attributes.
+ static bool sortInPlace(SmallVectorImpl<NamedAttribute> &array);
+
+ /// Returns an entry with a duplicate name in `array`, if it exists, else
+ /// returns llvm::None. If `isSorted` is true, the array is assumed to be
+ /// sorted else it will be sorted in place before finding the duplicate entry.
+ static Optional<NamedAttribute>
+ findDuplicate(SmallVectorImpl<NamedAttribute> &array, bool isSorted);
+
+ private:
+ /// Return empty dictionary.
+ static DictionaryAttr getEmpty(MLIRContext *context);
+
+ /// Return empty dictionary. This is a special variant of the above method
+ /// that is used by the MLIRContext to cache the empty dictionary instance.
+ static DictionaryAttr getEmptyUnchecked(MLIRContext *context);
+
+ /// Allow access to `getEmptyUnchecked`.
+ friend MLIRContext;
+
+ public:
+ }];
+ let skipDefaultBuilders = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// IntegerSetAttr
+//===----------------------------------------------------------------------===//
+
+def Builtin_IntegerSetAttr : Builtin_Attr<"IntegerSet"> {
+ let summary = "An Attribute containing an IntegerSet object";
+ let description = [{
+ Syntax:
+
+ ```
+ integer-set-attribute ::= `affine_set` `<` integer-set `>`
+ ```
+
+ Examples:
+
+ ```mlir
+ affine_set<(d0) : (d0 - 2 >= 0)>
+ ```
+ }];
+ let parameters = (ins "IntegerSet":$value);
+ let builders = [
+ AttrBuilderWithInferredContext<(ins "IntegerSet":$value), [{
+ return $_get(value.getContext(), value);
+ }]>
+ ];
+ let extraClassDeclaration = "using ValueType = IntegerSet;";
+ let skipDefaultBuilders = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// OpaqueAttr
+//===----------------------------------------------------------------------===//
+
+def Builtin_OpaqueAttr : Builtin_Attr<"Opaque"> {
+ let summary = "An opaque representation of another Attribute";
+ let description = [{
+ Syntax:
+
+ ```
+ opaque-attribute ::= dialect-namespace `<` attr-data `>`
+ ```
+
+ 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.
+
+ Examples:
+
+ ```mlir
+ #dialect<"opaque attribute data">
+ ```
+ }];
+ let parameters = (ins "Identifier":$dialectNamespace,
+ StringRefParameter<"">:$attrData,
+ AttributeSelfTypeParameter<"">:$type);
+ let builders = [
+ AttrBuilderWithInferredContext<(ins "Identifier":$dialect,
+ "StringRef":$attrData,
+ "Type":$type), [{
+ return $_get(dialect.getContext(), dialect, attrData, type);
+ }]>
+ ];
+ bit genVerifyDecl = 1;
+ // let skipDefaultBuilders = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// StringAttr
+//===----------------------------------------------------------------------===//
+
+def Builtin_StringAttr : Builtin_Attr<"String"> {
+ let summary = "An Attribute containing a string";
+ let description = [{
+ Syntax:
+
+ ```
+ string-attribute ::= string-literal (`:` type)?
+ ```
+
+ A string attribute is an attribute that represents a string literal value.
+
+ Examples:
+
+ ```mlir
+ "An important string"
+ "string with a type" : !dialect.string
+ ```
+ }];
+ let parameters = (ins StringRefParameter<"">:$value,
+ AttributeSelfTypeParameter<"">:$type);
+ let builders = [
+ AttrBuilderWithInferredContext<(ins "StringRef":$bytes,
+ "Type":$type), [{
+ return $_get(type.getContext(), bytes, type);
+ }]>,
+ AttrBuilder<(ins "StringRef":$bytes), [{
+ return $_get($_ctxt, bytes, NoneType::get($_ctxt));
+ }]>
+ ];
+ let extraClassDeclaration = "using ValueType = StringRef;";
+ let skipDefaultBuilders = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// SymbolRefAttr
+//===----------------------------------------------------------------------===//
+
+def Builtin_SymbolRefAttr : Builtin_Attr<"SymbolRef"> {
+ let summary = "An Attribute containing a symbolic reference to an Operation";
+ let description = [{
+ Syntax:
+
+ ```
+ symbol-ref-attribute ::= symbol-ref-id (`::` symbol-ref-id)*
+ ```
+
+ A symbol reference attribute is a literal attribute that represents a named
+ reference to an operation that is nested within an operation with the
+ `OpTrait::SymbolTable` trait. As such, this reference is given meaning by
+ the nearest parent operation containing the `OpTrait::SymbolTable` trait. It
+ may optionally contain a set of nested references that further resolve to a
+ symbol nested within a
diff erent symbol table.
+
+ This attribute can only be held internally by
+ [array attributes](#array-attribute) and
+ [dictionary attributes](#dictionary-attribute)(including the top-level
+ operation attribute dictionary), i.e. no other attribute kinds such as
+ Locations or extended attribute kinds.
+
+ **Rationale:** Identifying accesses to global data is critical to
+ enabling efficient multi-threaded compilation. Restricting global
+ data access to occur through symbols and limiting the places that can
+ legally hold a symbol reference simplifies reasoning about these data
+ accesses.
+
+ See [`Symbols And SymbolTables`](SymbolsAndSymbolTables.md) for more
+ information.
+
+ Examples:
+
+ ```mlir
+ @flat_reference
+ @parent_reference::@nested_reference
+ ```
+ }];
+ let parameters = (ins
+ StringRefParameter<"">:$rootReference,
+ ArrayRefParameter<"FlatSymbolRefAttr", "">:$nestedReferences
+ );
+ let extraClassDeclaration = [{
+ static FlatSymbolRefAttr get(MLIRContext *ctx, StringRef value);
+
+ /// Returns the name of the fully resolved symbol, i.e. the leaf of the
+ /// reference path.
+ StringRef getLeafReference() const;
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// TypeAttr
+//===----------------------------------------------------------------------===//
+
+def Builtin_TypeAttr : Builtin_Attr<"Type"> {
+ let summary = "An Attribute containing a Type";
+ let description = [{
+ Syntax:
+
+ ```
+ type-attribute ::= type
+ ```
+
+ A type attribute is an attribute that represents a
+ [type object](#type-system).
+
+ Examples:
+
+ ```mlir
+ i32
+ !dialect.type
+ ```
+ }];
+ let parameters = (ins "Type":$value);
+ let builders = [
+ AttrBuilderWithInferredContext<(ins "Type":$type), [{
+ return $_get(type.getContext(), type);
+ }]>,
+ ];
+ let extraClassDeclaration = "using ValueType = Type;";
+ let skipDefaultBuilders = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// UnitAttr
+//===----------------------------------------------------------------------===//
+
+def Builtin_UnitAttr : Builtin_Attr<"Unit"> {
+ let summary = "An Attribute value of `unit` type";
+ let description = [{
+ Syntax:
+
+ ```
+ unit-attribute ::= `unit`
+ ```
+
+ A unit attribute is an attribute that represents a value of `unit` type. The
+ `unit` type allows only one value forming a singleton set. This attribute
+ value is used to represent attributes that only have meaning from their
+ existence.
+
+ One example of such an attribute could be the `swift.self` attribute. This
+ attribute indicates that a function parameter is the self/context parameter.
+ It could be represented as a [boolean attribute](#boolean-attribute)(true or
+ false), but a value of false doesn't really bring any value. The parameter
+ either is the self/context or it isn't.
+
+
+ Examples:
+
+ ```mlir
+ // A unit attribute defined with the `unit` value specifier.
+ func @verbose_form() attributes {dialectName.unitAttr = unit}
+
+ // A unit attribute in an attribute dictionary can also be defined without
+ // the value specifier.
+ func @simple_form() attributes {dialectName.unitAttr}
+ ```
+ }];
+ let extraClassDeclaration = [{
+ static UnitAttr get(MLIRContext *context);
+ }];
+}
+
+#endif // BUILTIN_ATTRIBUTES
diff --git a/mlir/include/mlir/IR/CMakeLists.txt b/mlir/include/mlir/IR/CMakeLists.txt
index 3b7ddbaf2338..fd598f3a3a66 100644
--- a/mlir/include/mlir/IR/CMakeLists.txt
+++ b/mlir/include/mlir/IR/CMakeLists.txt
@@ -2,6 +2,11 @@ add_mlir_interface(OpAsmInterface)
add_mlir_interface(SymbolInterfaces)
add_mlir_interface(RegionKindInterface)
+set(LLVM_TARGET_DEFINITIONS BuiltinAttributes.td)
+mlir_tablegen(BuiltinAttributes.h.inc -gen-attrdef-decls)
+mlir_tablegen(BuiltinAttributes.cpp.inc -gen-attrdef-defs)
+add_public_tablegen_target(MLIRBuiltinAttributesIncGen)
+
set(LLVM_TARGET_DEFINITIONS BuiltinDialect.td)
mlir_tablegen(BuiltinDialect.h.inc -gen-dialect-decls)
add_public_tablegen_target(MLIRBuiltinDialectIncGen)
diff --git a/mlir/lib/IR/AttributeDetail.h b/mlir/lib/IR/AttributeDetail.h
index db86d7a1c27b..9499a0f84c84 100644
--- a/mlir/lib/IR/AttributeDetail.h
+++ b/mlir/lib/IR/AttributeDetail.h
@@ -26,91 +26,6 @@
namespace mlir {
namespace detail {
-// An attribute representing a reference to an affine map.
-struct AffineMapAttributeStorage : public AttributeStorage {
- using KeyTy = AffineMap;
-
- AffineMapAttributeStorage(AffineMap value)
- : AttributeStorage(IndexType::get(value.getContext())), value(value) {}
-
- /// 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);
- }
-
- AffineMap 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));
- }
-
- 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 *
- construct(AttributeStorageAllocator &allocator, const KeyTy &key) {
- auto size = DictionaryAttributeStorage::totalSizeToAlloc<NamedAttribute>(
- key.size());
- auto rawMem = allocator.allocate(size, alignof(DictionaryAttributeStorage));
-
- // 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;
- }
-
- /// 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;
- }
- DictionaryAttributeStorage(unsigned numElements) : numElements(numElements) {}
-
- /// This is the number of attributes.
- const unsigned numElements;
-};
/// An attribute representing a floating point value.
struct FloatAttributeStorage final
@@ -219,131 +134,6 @@ struct IntegerAttributeStorage final
size_t numObjects;
};
-// An attribute representing a reference to an integer set.
-struct IntegerSetAttributeStorage : public AttributeStorage {
- using KeyTy = IntegerSet;
-
- IntegerSetAttributeStorage(IntegerSet 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);
- }
-
- IntegerSet value;
-};
-
-/// Opaque Attribute Storage and Uniquing.
-struct OpaqueAttributeStorage : public AttributeStorage {
- OpaqueAttributeStorage(Identifier dialectNamespace, StringRef attrData,
- Type type)
- : AttributeStorage(type), dialectNamespace(dialectNamespace),
- attrData(attrData) {}
-
- /// The hash key used for uniquing.
- using KeyTy = std::tuple<Identifier, StringRef, Type>;
- bool operator==(const KeyTy &key) const {
- return key == KeyTy(dialectNamespace, attrData, getType());
- }
-
- static OpaqueAttributeStorage *construct(AttributeStorageAllocator &allocator,
- const KeyTy &key) {
- return new (allocator.allocate<OpaqueAttributeStorage>())
- OpaqueAttributeStorage(std::get<0>(key),
- allocator.copyInto(std::get<1>(key)),
- std::get<2>(key));
- }
-
- // 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 = std::pair<StringRef, Type>;
-
- StringAttributeStorage(StringRef value, Type type)
- : AttributeStorage(type), value(value) {}
-
- /// Key equality function.
- bool operator==(const KeyTy &key) const {
- return key == KeyTy(value, getType());
- }
-
- /// Construct a new storage instance.
- static StringAttributeStorage *construct(AttributeStorageAllocator &allocator,
- const KeyTy &key) {
- return new (allocator.allocate<StringAttributeStorage>())
- StringAttributeStorage(allocator.copyInto(key.first), key.second);
- }
-
- StringRef value;
-};
-
-/// An attribute representing a symbol reference.
-struct SymbolRefAttributeStorage final
- : public AttributeStorage,
- public llvm::TrailingObjects<SymbolRefAttributeStorage,
- FlatSymbolRefAttr> {
- using KeyTy = std::pair<StringRef, ArrayRef<FlatSymbolRefAttr>>;
-
- SymbolRefAttributeStorage(StringRef value, size_t numNestedRefs)
- : value(value), numNestedRefs(numNestedRefs) {}
-
- /// Key equality function.
- bool operator==(const KeyTy &key) const {
- return key == KeyTy(value, getNestedRefs());
- }
-
- /// Construct a new storage instance.
- static SymbolRefAttributeStorage *
- construct(AttributeStorageAllocator &allocator, const KeyTy &key) {
- auto size = SymbolRefAttributeStorage::totalSizeToAlloc<FlatSymbolRefAttr>(
- key.second.size());
- auto rawMem = allocator.allocate(size, alignof(SymbolRefAttributeStorage));
- auto result = ::new (rawMem) SymbolRefAttributeStorage(
- allocator.copyInto(key.first), key.second.size());
- std::uninitialized_copy(key.second.begin(), key.second.end(),
- result->getTrailingObjects<FlatSymbolRefAttr>());
- return result;
- }
-
- /// Returns the set of nested references.
- ArrayRef<FlatSymbolRefAttr> getNestedRefs() const {
- return {getTrailingObjects<FlatSymbolRefAttr>(), numNestedRefs};
- }
-
- StringRef value;
- size_t numNestedRefs;
-};
-
-/// An attribute representing a reference to a type.
-struct TypeAttributeStorage : public AttributeStorage {
- using KeyTy = Type;
-
- TypeAttributeStorage(Type value) : value(value) {}
-
- /// Key equality function.
- bool operator==(const KeyTy &key) const { return key == value; }
-
- /// Construct a new storage instance.
- static TypeAttributeStorage *construct(AttributeStorageAllocator &allocator,
- KeyTy key) {
- return new (allocator.allocate<TypeAttributeStorage>())
- TypeAttributeStorage(key);
- }
-
- Type value;
-};
-
//===----------------------------------------------------------------------===//
// Elements Attributes
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/IR/BuiltinAttributes.cpp b/mlir/lib/IR/BuiltinAttributes.cpp
index cccef6c76818..1d76122996de 100644
--- a/mlir/lib/IR/BuiltinAttributes.cpp
+++ b/mlir/lib/IR/BuiltinAttributes.cpp
@@ -22,29 +22,11 @@ using namespace mlir;
using namespace mlir::detail;
//===----------------------------------------------------------------------===//
-// AffineMapAttr
+/// Tablegen Attribute Definitions
//===----------------------------------------------------------------------===//
-AffineMapAttr AffineMapAttr::get(AffineMap value) {
- return Base::get(value.getContext(), value);
-}
-
-AffineMap AffineMapAttr::getValue() const { return getImpl()->value; }
-
-//===----------------------------------------------------------------------===//
-// ArrayAttr
-//===----------------------------------------------------------------------===//
-
-ArrayAttr ArrayAttr::get(MLIRContext *context, ArrayRef<Attribute> value) {
- return Base::get(context, value);
-}
-
-ArrayRef<Attribute> ArrayAttr::getValue() const { return getImpl()->value; }
-
-Attribute ArrayAttr::operator[](unsigned idx) const {
- assert(idx < size() && "index out of bounds");
- return getValue()[idx];
-}
+#define GET_ATTRDEF_CLASSES
+#include "mlir/IR/BuiltinAttributes.cpp.inc"
//===----------------------------------------------------------------------===//
// DictionaryAttr
@@ -152,8 +134,8 @@ DictionaryAttr DictionaryAttr::get(MLIRContext *context,
}
/// Construct a dictionary with an array of values that is known to already be
/// sorted by name and uniqued.
-DictionaryAttr DictionaryAttr::getWithSorted(ArrayRef<NamedAttribute> value,
- MLIRContext *context) {
+DictionaryAttr DictionaryAttr::getWithSorted(MLIRContext *context,
+ ArrayRef<NamedAttribute> value) {
if (value.empty())
return DictionaryAttr::getEmpty(context);
// Ensure that the attribute elements are unique and sorted.
@@ -167,10 +149,6 @@ DictionaryAttr DictionaryAttr::getWithSorted(ArrayRef<NamedAttribute> value,
return Base::get(context, value);
}
-ArrayRef<NamedAttribute> DictionaryAttr::getValue() const {
- return getImpl()->getElements();
-}
-
/// Return the specified attribute if present, null otherwise.
Attribute DictionaryAttr::get(StringRef name) const {
Optional<NamedAttribute> attr = getNamed(name);
@@ -203,6 +181,10 @@ DictionaryAttr::iterator DictionaryAttr::end() const {
}
size_t DictionaryAttr::size() const { return getValue().size(); }
+DictionaryAttr DictionaryAttr::getEmptyUnchecked(MLIRContext *context) {
+ return Base::get(context, ArrayRef<NamedAttribute>());
+}
+
//===----------------------------------------------------------------------===//
// FloatAttr
//===----------------------------------------------------------------------===//
@@ -272,25 +254,14 @@ LogicalResult FloatAttr::verify(function_ref<InFlightDiagnostic()> emitError,
//===----------------------------------------------------------------------===//
FlatSymbolRefAttr SymbolRefAttr::get(MLIRContext *ctx, StringRef value) {
- return Base::get(ctx, value, llvm::None).cast<FlatSymbolRefAttr>();
+ return get(ctx, value, llvm::None).cast<FlatSymbolRefAttr>();
}
-SymbolRefAttr SymbolRefAttr::get(MLIRContext *ctx, StringRef value,
- ArrayRef<FlatSymbolRefAttr> nestedReferences) {
- return Base::get(ctx, value, nestedReferences);
-}
-
-StringRef SymbolRefAttr::getRootReference() const { return getImpl()->value; }
-
StringRef SymbolRefAttr::getLeafReference() const {
ArrayRef<FlatSymbolRefAttr> nestedRefs = getNestedReferences();
return nestedRefs.empty() ? getRootReference() : nestedRefs.back().getValue();
}
-ArrayRef<FlatSymbolRefAttr> SymbolRefAttr::getNestedReferences() const {
- return getImpl()->getNestedRefs();
-}
-
//===----------------------------------------------------------------------===//
// IntegerAttr
//===----------------------------------------------------------------------===//
@@ -368,40 +339,10 @@ bool BoolAttr::classof(Attribute attr) {
return intAttr && intAttr.getType().isSignlessInteger(1);
}
-//===----------------------------------------------------------------------===//
-// IntegerSetAttr
-//===----------------------------------------------------------------------===//
-
-IntegerSetAttr IntegerSetAttr::get(IntegerSet value) {
- return Base::get(value.getConstraint(0).getContext(), value);
-}
-
-IntegerSet IntegerSetAttr::getValue() const { return getImpl()->value; }
-
//===----------------------------------------------------------------------===//
// OpaqueAttr
//===----------------------------------------------------------------------===//
-OpaqueAttr OpaqueAttr::get(Identifier dialect, StringRef attrData, Type type) {
- return Base::get(dialect.getContext(), dialect, attrData, type);
-}
-
-OpaqueAttr OpaqueAttr::getChecked(function_ref<InFlightDiagnostic()> emitError,
- Identifier dialect, StringRef attrData,
- Type type) {
- return Base::getChecked(emitError, dialect.getContext(), dialect, attrData,
- type);
-}
-
-/// 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::verify(function_ref<InFlightDiagnostic()> emitError,
Identifier dialect, StringRef attrData,
Type type) {
@@ -410,31 +351,6 @@ LogicalResult OpaqueAttr::verify(function_ref<InFlightDiagnostic()> emitError,
return success();
}
-//===----------------------------------------------------------------------===//
-// StringAttr
-//===----------------------------------------------------------------------===//
-
-StringAttr StringAttr::get(MLIRContext *context, StringRef bytes) {
- return get(bytes, NoneType::get(context));
-}
-
-/// Get an instance of a StringAttr with the given string and Type.
-StringAttr StringAttr::get(StringRef bytes, Type type) {
- return Base::get(type.getContext(), bytes, type);
-}
-
-StringRef StringAttr::getValue() const { return getImpl()->value; }
-
-//===----------------------------------------------------------------------===//
-// TypeAttr
-//===----------------------------------------------------------------------===//
-
-TypeAttr TypeAttr::get(Type value) {
- return Base::get(value.getContext(), value);
-}
-
-Type TypeAttr::getValue() const { return getImpl()->value; }
-
//===----------------------------------------------------------------------===//
// ElementsAttr
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/IR/CMakeLists.txt b/mlir/lib/IR/CMakeLists.txt
index f9ab7033eb48..49911c9e2ce5 100644
--- a/mlir/lib/IR/CMakeLists.txt
+++ b/mlir/lib/IR/CMakeLists.txt
@@ -33,6 +33,7 @@ add_mlir_library(MLIRIR
${MLIR_MAIN_INCLUDE_DIR}/mlir/IR
DEPENDS
+ MLIRBuiltinAttributesIncGen
MLIRBuiltinDialectIncGen
MLIRBuiltinOpsIncGen
MLIRBuiltinTypesIncGen
diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp
index c42041208491..7a4aac1f947c 100644
--- a/mlir/lib/IR/MLIRContext.cpp
+++ b/mlir/lib/IR/MLIRContext.cpp
@@ -403,8 +403,7 @@ MLIRContext::MLIRContext(const DialectRegistry ®istry)
/// Unknown Location Attribute.
impl->unknownLocAttr = AttributeUniquer::get<UnknownLoc>(this);
/// The empty dictionary attribute.
- impl->emptyDictionaryAttr =
- AttributeUniquer::get<DictionaryAttr>(this, ArrayRef<NamedAttribute>());
+ impl->emptyDictionaryAttr = DictionaryAttr::getEmptyUnchecked(this);
// Register the affine storage objects with the uniquer.
impl->affineUniquer
diff --git a/mlir/lib/IR/OperationSupport.cpp b/mlir/lib/IR/OperationSupport.cpp
index b939c5304e75..28acdc2fcb29 100644
--- a/mlir/lib/IR/OperationSupport.cpp
+++ b/mlir/lib/IR/OperationSupport.cpp
@@ -54,7 +54,7 @@ DictionaryAttr NamedAttrList::getDictionary(MLIRContext *context) const {
dictionarySorted.setPointerAndInt(nullptr, true);
}
if (!dictionarySorted.getPointer())
- dictionarySorted.setPointer(DictionaryAttr::getWithSorted(attrs, context));
+ dictionarySorted.setPointer(DictionaryAttr::getWithSorted(context, attrs));
return dictionarySorted.getPointer().cast<DictionaryAttr>();
}
More information about the Mlir-commits
mailing list