| //===-- AttrTypeBase.td - Base Attr/Type definition file ---*- 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 |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains the base set of constructs for defining Attribute and |
| // Type classes. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef ATTRTYPEBASE_TD |
| #define ATTRTYPEBASE_TD |
| |
| include "mlir/IR/CommonAttrConstraints.td" |
| include "mlir/IR/CommonTypeConstraints.td" |
| include "mlir/IR/Constraints.td" |
| include "mlir/IR/DialectBase.td" |
| include "mlir/IR/Traits.td" |
| |
| //-------------------------------------------------------------------------===// |
| // AttrTrait definitions |
| //===----------------------------------------------------------------------===// |
| |
| // These classes are used to define attribute specific traits. |
| |
| // Specify attribute specific declarations and definitions in `extraAttrDeclaration` |
| // and `extraAttrDefinition` template arguments. |
| class NativeAttrTrait<string name, |
| code extraAttrDeclaration = [{}], |
| code extraAttrDefinition = [{}]> |
| : NativeTrait<name, "Attribute", extraAttrDeclaration, extraAttrDefinition>; |
| |
| class ParamNativeAttrTrait<string prop, string params> |
| : ParamNativeTrait<prop, params, "Attribute">; |
| class GenInternalAttrTrait<string prop> : GenInternalTrait<prop, "Attribute">; |
| class PredAttrTrait<string descr, Pred pred> : PredTrait<descr, pred>; |
| |
| //===----------------------------------------------------------------------===// |
| // TypeTrait definitions |
| //===----------------------------------------------------------------------===// |
| |
| // These classes are used to define type specific traits. |
| |
| // Specify type specific declarations and definitions in `extraTypeDeclaration` |
| // and `extraTypeDefinition` template arguments. |
| class NativeTypeTrait<string name, |
| code extraTypeDeclaration = [{}], |
| code extraTypeDefinition = [{}]> |
| : NativeTrait<name, "Type", extraTypeDeclaration, extraTypeDefinition>; |
| |
| class ParamNativeTypeTrait<string prop, string params> |
| : ParamNativeTrait<prop, params, "Type">; |
| class GenInternalTypeTrait<string prop> : GenInternalTrait<prop, "Type">; |
| class PredTypeTrait<string descr, Pred pred> : PredTrait<descr, pred>; |
| |
| //===----------------------------------------------------------------------===// |
| // Builders |
| //===----------------------------------------------------------------------===// |
| |
| // Class for defining a custom getter. |
| // |
| // TableGen generates several generic getter methods for each attribute and type |
| // by default, corresponding to the specified dag parameters. If the default |
| // generated ones cannot cover some use case, custom getters can be defined |
| // using instances of this class. |
| // |
| // The signature of the `get` is always either: |
| // |
| // ```c++ |
| // static <ClassName> get(MLIRContext *context, <other-parameters>...) { |
| // <body>... |
| // } |
| // ``` |
| // |
| // or: |
| // |
| // ```c++ |
| // static <ClassName> get(MLIRContext *context, <parameters>...); |
| // ``` |
| // |
| // To define a custom getter, the parameter list and body should be passed |
| // in as separate template arguments to this class. The parameter list is a |
| // TableGen DAG with `ins` operation with named arguments, which has either: |
| // - string initializers ("Type":$name) to represent a typed parameter, or |
| // - CArg-typed initializers (CArg<"Type", "default">:$name) to represent a |
| // typed parameter that may have a default value. |
| // The type string is used verbatim to produce code and, therefore, must be a |
| // valid C++ type. It is used inside the C++ namespace of the parent Type's |
| // dialect; explicit namespace qualification like `::mlir` may be necessary if |
| // Types are not placed inside the `mlir` namespace. The default value string is |
| // used verbatim to produce code and must be a valid C++ initializer the given |
| // type. For example, the following signature specification |
| // |
| // ``` |
| // AttrOrTypeBuilder<(ins "int":$integerArg, CArg<"float", "3.0f">:$floatArg)> |
| // ``` |
| // |
| // has an integer parameter and a float parameter with a default value. |
| // |
| // If an empty string is passed in for `body`, then *only* the builder |
| // declaration will be generated; this provides a way to define complicated |
| // builders entirely in C++. If a `body` string is provided, the `Base::get` |
| // method should be invoked using `$_get`, e.g.: |
| // |
| // ``` |
| // AttrOrTypeBuilder<(ins "int":$integerArg, CArg<"float", "3.0f">:$floatArg), [{ |
| // return $_get($_ctxt, integerArg, floatArg); |
| // }]> |
| // ``` |
| // |
| // This is necessary because the `body` is also used to generate `getChecked` |
| // methods, which have a different underlying `Base::get*` call. |
| // |
| class AttrOrTypeBuilder<dag parameters, code bodyCode = "", |
| string returnTypeStr = ""> { |
| dag dagParams = parameters; |
| code body = bodyCode; |
| |
| // Change the return type of the builder. By default, it is the type of the |
| // attribute or type. |
| string returnType = returnTypeStr; |
| |
| // The context parameter can be inferred from one of the other parameters and |
| // is not implicitly added to the parameter list. |
| bit hasInferredContextParam = 0; |
| } |
| class AttrBuilder<dag parameters, code bodyCode = "", string returnType = ""> |
| : AttrOrTypeBuilder<parameters, bodyCode, returnType>; |
| class TypeBuilder<dag parameters, code bodyCode = "", string returnType = ""> |
| : AttrOrTypeBuilder<parameters, bodyCode, returnType>; |
| |
| // A class of AttrOrTypeBuilder that is able to infer the MLIRContext parameter |
| // from one of the other builder parameters. Instances of this builder do not |
| // have `MLIRContext *` implicitly added to the parameter list. |
| class AttrOrTypeBuilderWithInferredContext<dag parameters, code bodyCode = "", |
| string returnType = ""> |
| : TypeBuilder<parameters, bodyCode, returnType> { |
| let hasInferredContextParam = 1; |
| } |
| class AttrBuilderWithInferredContext<dag parameters, code bodyCode = "", |
| string returnType = ""> |
| : AttrOrTypeBuilderWithInferredContext<parameters, bodyCode, returnType>; |
| class TypeBuilderWithInferredContext<dag parameters, code bodyCode = "", |
| string returnType = ""> |
| : AttrOrTypeBuilderWithInferredContext<parameters, bodyCode, returnType>; |
| |
| //===----------------------------------------------------------------------===// |
| // Definitions |
| //===----------------------------------------------------------------------===// |
| |
| // Define a new attribute or type, named `name`, that inherits from the given |
| // C++ base class. |
| class AttrOrTypeDef<string valueType, string name, list<Trait> defTraits, |
| string baseCppClass> { |
| // The name of the C++ base class to use for this def. |
| string cppBaseClassName = baseCppClass; |
| |
| // Additional, longer human-readable description of what the def does. |
| string description = ""; |
| |
| // Name of storage class to generate or use. |
| string storageClass = name # valueType # "Storage"; |
| |
| // Namespace (withing dialect c++ namespace) in which the storage class |
| // resides. |
| string storageNamespace = "detail"; |
| |
| // Specify if the storage class is to be generated. |
| bit genStorageClass = 1; |
| |
| // Specify that the generated storage class has a constructor which is written |
| // in C++. |
| bit hasStorageCustomConstructor = 0; |
| |
| // The list of parameters for this type. Parameters will become both |
| // parameters to the get() method and storage class member variables. |
| // |
| // The format of this dag is: |
| // (ins |
| // "<c++ type>":$param1Name, |
| // "<c++ type>":$param2Name, |
| // AttrOrTypeParameter<"c++ type", "param description">:$param3Name) |
| // AttrOrTypeParameters (or more likely one of their subclasses) are required |
| // to add more information about the parameter, specifically: |
| // - Documentation |
| // - Code to allocate the parameter (if allocation is needed in the storage |
| // class constructor) |
| // |
| // For example: |
| // (ins "int":$width, |
| // ArrayRefParameter<"bool", "list of bools">:$yesNoArray) |
| // |
| // (ArrayRefParameter is a subclass of AttrOrTypeParameter which has |
| // allocation code for re-allocating ArrayRefs. It is defined below.) |
| dag parameters = (ins); |
| |
| // Custom builder methods. |
| // In addition to the custom builders provided here, and unless |
| // skipDefaultBuilders is set, a default builder is generated with the |
| // following signature: |
| // |
| // ```c++ |
| // static <ClassName> get(MLIRContext *, <parameters>); |
| // ``` |
| // |
| // Note that builders should only be provided when a def has parameters. |
| list<AttrOrTypeBuilder> builders = ?; |
| |
| // The list of traits attached to this def. |
| list<Trait> traits = defTraits; |
| |
| // Use the lowercased name as the keyword for parsing/printing. Specify only |
| // if you want tblgen to generate declarations and/or definitions of |
| // the printer/parser. If specified and the Attribute or Type contains |
| // parameters, `assemblyFormat` or `hasCustomAssemblyFormat` must also be |
| // specified. |
| string mnemonic = ?; |
| |
| // Custom assembly format. Requires 'mnemonic' to be specified. Cannot be |
| // specified at the same time as 'hasCustomAssemblyFormat'. The generated |
| // printer requires 'genAccessors' to be true. |
| string assemblyFormat = ?; |
| /// This field indicates that the attribute or type has a custom assembly format |
| /// implemented in C++. When set to `1` a `parse` and `print` method are generated |
| /// on the generated class. The attribute or type should implement these methods to |
| /// support the custom format. |
| bit hasCustomAssemblyFormat = 0; |
| |
| // If set, generate accessors for each parameter. |
| bit genAccessors = 1; |
| |
| // Avoid generating default get/getChecked functions. Custom get methods must |
| // be provided. |
| bit skipDefaultBuilders = 0; |
| |
| // Generate the verify and getChecked methods. |
| bit genVerifyDecl = 0; |
| |
| // Extra code to include in the class declaration. |
| code extraClassDeclaration = [{}]; |
| |
| // Additional code that will be added to the generated source file. The |
| // generated code is placed inside the class's C++ namespace. `$cppClass` is |
| // replaced by the class name. |
| code extraClassDefinition = [{}]; |
| } |
| |
| // Define a new attribute, named `name`, belonging to `dialect` that inherits |
| // from the given C++ base class. |
| class AttrDef<Dialect dialect, string name, list<Trait> traits = [], |
| string baseCppClass = "::mlir::Attribute"> |
| : DialectAttr<dialect, CPred<"">, /*descr*/"">, |
| AttrOrTypeDef<"Attr", name, traits, baseCppClass> { |
| // The name of the C++ Attribute class. |
| string cppClassName = name # "Attr"; |
| let storageType = dialect.cppNamespace # "::" # name # "Attr"; |
| |
| // The underlying C++ value type |
| let returnType = dialect.cppNamespace # "::" # cppClassName; |
| |
| // Make it possible to use such attributes as parameters for other attributes. |
| string cppType = dialect.cppNamespace # "::" # cppClassName; |
| |
| // The unique attribute name. |
| string attrName = dialect.name # "." # mnemonic; |
| |
| // The call expression to convert from the storage type to the return |
| // type. For example, an enum can be stored as an int but returned as an |
| // enum class. |
| // |
| // Format: $_self will be expanded to the attribute. |
| // |
| // For example, `$_self.getValue().getSExtValue()` for `IntegerAttr val` will |
| // expand to `getAttrOfType<IntegerAttr>("val").getValue().getSExtValue()`. |
| let convertFromStorage = "::llvm::cast<" # dialect.cppNamespace # |
| "::" # cppClassName # ">($_self)"; |
| |
| // The predicate for when this def is used as a constraint. |
| let predicate = CPred<"::llvm::isa<" # dialect.cppNamespace # |
| "::" # cppClassName # ">($_self)">; |
| } |
| |
| // Define a new type, named `name`, belonging to `dialect` that inherits from |
| // the given C++ base class. |
| class TypeDef<Dialect dialect, string name, list<Trait> traits = [], |
| string baseCppClass = "::mlir::Type"> |
| : DialectType<dialect, CPred<"">, /*descr*/"", name # "Type">, |
| AttrOrTypeDef<"Type", name, traits, baseCppClass> { |
| // Make it possible to use such type as parameters for other types. |
| string cppType = dialect.cppNamespace # "::" # cppClassName; |
| |
| // The unique type name. |
| string typeName = dialect.name # "." # mnemonic; |
| |
| // A constant builder provided when the type has no parameters. |
| let builderCall = !if(!empty(parameters), |
| "$_builder.getType<" # dialect.cppNamespace # |
| "::" # cppClassName # ">()", |
| ""); |
| // The predicate for when this def is used as a constraint. |
| let predicate = CPred<"::llvm::isa<" # dialect.cppNamespace # |
| "::" # cppClassName # ">($_self)">; |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Parameters |
| //===----------------------------------------------------------------------===// |
| |
| // 'Parameters' should be subclasses of this or simple strings (which is a |
| // shorthand for AttrOrTypeParameter<"C++Type">). |
| class AttrOrTypeParameter<string type, string desc, string accessorType = ""> { |
| // Custom memory allocation code for storage constructor. |
| code allocator = ?; |
| // Comparator used to compare two instances for equality. By default, it uses |
| // the C++ equality operator. |
| code comparator = ?; |
| // The C++ type of this parameter. |
| string cppType = type; |
| // The C++ type of the accessor for this parameter. |
| string cppAccessorType = !if(!empty(accessorType), type, accessorType); |
| // The C++ storage type of this parameter if it is a reference, e.g. |
| // `std::string` for `StringRef` or `SmallVector` for `ArrayRef`. |
| string cppStorageType = cppType; |
| // The C++ code to convert from the storage type to the parameter type. |
| string convertFromStorage = "$_self"; |
| // One-line human-readable description of the argument. |
| string summary = desc; |
| // The format string for the asm syntax (documentation only). |
| string syntax = ?; |
| // The default parameter parser is `::mlir::FieldParser<T>::parse($_parser)`, |
| // which returns `FailureOr<T>`. Specialize `FieldParser` to support parsing |
| // for your type. Or you can provide a customer printer. For attributes, |
| // "$_type" will be replaced with the required attribute type. |
| string parser = ?; |
| // The default parameter printer is `$_printer << $_self`. Overload the stream |
| // operator of `AsmPrinter` as necessary to print your type. Or you can |
| // provide a custom printer. |
| string printer = ?; |
| // Provide a default value for the parameter. Parameters with default values |
| // are considered optional. If a value was not parsed for the parameter, it |
| // will be set to the default value. Parameters equal to their default values |
| // are elided when printing. Equality is checked using the `comparator` field, |
| // which by default is the C++ equality operator. The current MLIR context is |
| // made available through `$_ctxt`, e.g., for constructing default values for |
| // attributes and types. |
| string defaultValue = ""; |
| } |
| class AttrParameter<string type, string desc, string accessorType = ""> |
| : AttrOrTypeParameter<type, desc, accessorType>; |
| class TypeParameter<string type, string desc, string accessorType = ""> |
| : AttrOrTypeParameter<type, desc, accessorType>; |
| |
| // An optional parameter. |
| class OptionalParameter<string type, string desc = ""> : |
| AttrOrTypeParameter<type, desc> { |
| let defaultValue = cppStorageType # "()"; |
| } |
| |
| // A parameter with a default value. |
| class DefaultValuedParameter<string type, string value, string desc = ""> : |
| AttrOrTypeParameter<type, desc> { |
| let defaultValue = value; |
| } |
| |
| // For StringRefs, which require allocation. |
| class StringRefParameter<string desc = "", string value = ""> : |
| AttrOrTypeParameter<"::llvm::StringRef", desc> { |
| let allocator = [{$_dst = $_allocator.copyInto($_self);}]; |
| let printer = [{$_printer.printString($_self);}]; |
| let cppStorageType = "std::string"; |
| let defaultValue = value; |
| } |
| |
| // For APFloats, which require comparison. |
| class APFloatParameter<string desc> : |
| AttrOrTypeParameter<"::llvm::APFloat", desc> { |
| let comparator = "$_lhs.bitwiseIsEqual($_rhs)"; |
| } |
| |
| // For standard ArrayRefs, which require allocation. |
| class ArrayRefParameter<string arrayOf, string desc = ""> : |
| AttrOrTypeParameter<"::llvm::ArrayRef<" # arrayOf # ">", desc> { |
| let allocator = [{$_dst = $_allocator.copyInto($_self);}]; |
| let cppStorageType = "::llvm::SmallVector<" # arrayOf # ">"; |
| } |
| |
| // Regular array parameters cannot be parsed when empty. This optional array |
| // parameter can be used with optional groups to be parsed when empty. |
| class OptionalArrayRefParameter<string arrayOf, string desc = ""> : |
| OptionalParameter<"::llvm::ArrayRef<" # arrayOf # ">", desc> { |
| let allocator = [{$_dst = $_allocator.copyInto($_self);}]; |
| let cppStorageType = "::llvm::SmallVector<" # arrayOf # ">"; |
| let comparator = cppType # "($_lhs) == " # cppType # "($_rhs)"; |
| } |
| |
| // For classes which require allocation and have their own allocateInto method. |
| class SelfAllocationParameter<string type, string desc> : |
| AttrOrTypeParameter<type, desc> { |
| let allocator = [{$_dst = $_self.allocateInto($_allocator);}]; |
| } |
| |
| // For ArrayRefs which contain things which allocate themselves. |
| class ArrayRefOfSelfAllocationParameter<string arrayOf, string desc> : |
| AttrOrTypeParameter<"::llvm::ArrayRef<" # arrayOf # ">", desc> { |
| let allocator = [{ |
| llvm::SmallVector<}] # arrayOf # [{, 4> tmpFields; |
| for (size_t i = 0, e = $_self.size(); i < e; ++i) |
| tmpFields.push_back($_self[i].allocateInto($_allocator)); |
| $_dst = $_allocator.copyInto(ArrayRef<}] # arrayOf # [{>(tmpFields)); |
| }]; |
| } |
| |
| // This is a special attribute parameter that represents the "self" type of the |
| // attribute. It is specially handled by the assembly format generator to derive |
| // its value from the optional trailing type after each attribute. |
| // |
| // By default, the self type parameter is optional and has a default value of |
| // `none`. If a derived type other than `::mlir::Type` is specified, the |
| // parameter loses its default value unless another one is specified by |
| // `typeBuilder`. |
| class AttributeSelfTypeParameter<string desc, |
| string derivedType = "::mlir::Type", |
| string typeBuilder = ""> : |
| AttrOrTypeParameter<derivedType, desc> { |
| let defaultValue = !if(!and(!empty(typeBuilder), |
| !eq(derivedType, "::mlir::Type")), |
| "::mlir::NoneType::get($_ctxt)", typeBuilder); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // ArrayOfAttr |
| //===----------------------------------------------------------------------===// |
| |
| /// This class defines an attribute that contains an array of elements. The |
| /// elements can be any type, but if they are attributes, the nested elements |
| /// are parsed and printed using the custom attribute syntax. |
| class ArrayOfAttr<Dialect dialect, string name, string attrMnemonic, |
| string eltName, list<Trait> traits = []> |
| : AttrDef<dialect, name, traits> { |
| let parameters = (ins OptionalArrayRefParameter<eltName>:$value); |
| let mnemonic = attrMnemonic; |
| let assemblyFormat = "`[` (`]`) : ($value^ `]`)?"; |
| |
| let returnType = "::llvm::ArrayRef<" # eltName # ">"; |
| let constBuilderCall = "$_builder.getAttr<" # name # "Attr>($0)"; |
| let convertFromStorage = "$_self.getValue()"; |
| |
| let extraClassDeclaration = [{ |
| auto begin() const { return getValue().begin(); } |
| auto end() const { return getValue().end(); } |
| bool empty() const { return getValue().empty(); } |
| size_t size() const { return getValue().size(); } |
| auto &front() const { return getValue().front(); } |
| auto &back() const { return getValue().back(); } |
| auto &operator[](size_t index) { return getValue()[index]; } |
| operator }] # returnType # [{() const { return getValue(); } |
| }]; |
| } |
| |
| #endif // ATTRTYPEBASE_TD |