//===- BuiltinTypes.td - Builtin type 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_TYPES
#define BUILTIN_TYPES

include "mlir/IR/BuiltinDialect.td"
include "mlir/IR/BuiltinTypeInterfaces.td"
include "mlir/IR/SubElementInterfaces.td"

// TODO: Currently the types defined in this file are prefixed with `Builtin_`.
// This is to differentiate the types 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 types.
class Builtin_Type<string name, list<Trait> traits = [],
                   string baseCppClass = "::mlir::Type">
    : TypeDef<Builtin_Dialect, name, traits, baseCppClass> {
  let mnemonic = ?;
}

//===----------------------------------------------------------------------===//
// ComplexType
//===----------------------------------------------------------------------===//

def Builtin_Complex : Builtin_Type<"Complex"> {
  let summary = "Complex number with a parameterized element type";
  let description = [{
    Syntax:

    ```
    complex-type ::= `complex` `<` type `>`
    ```

    The value of `complex` type represents a complex number with a parameterized
    element type, which is composed of a real and imaginary value of that
    element type. The element must be a floating point or integer scalar type.

    Examples:

    ```mlir
    complex<f32>
    complex<i32>
    ```
  }];
  let parameters = (ins "Type":$elementType);
  let builders = [
    TypeBuilderWithInferredContext<(ins "Type":$elementType), [{
      return $_get(elementType.getContext(), elementType);
    }]>
  ];
  let skipDefaultBuilders = 1;
  let genVerifyDecl = 1;
}

//===----------------------------------------------------------------------===//
// FloatType
//===----------------------------------------------------------------------===//

// Base class for Builtin dialect float types.
class Builtin_FloatType<string name>
    : Builtin_Type<name, /*traits=*/[], "::mlir::FloatType"> {
  let extraClassDeclaration = [{
    static }] # name # [{Type get(MLIRContext *context);
  }];
}

//===----------------------------------------------------------------------===//
// BFloat16Type

def Builtin_BFloat16 : Builtin_FloatType<"BFloat16"> {
  let summary = "bfloat16 floating-point type";
}

//===----------------------------------------------------------------------===//
// Float16Type

def Builtin_Float16 : Builtin_FloatType<"Float16"> {
  let summary = "16-bit floating-point type";
}

//===----------------------------------------------------------------------===//
// Float32Type

def Builtin_Float32 : Builtin_FloatType<"Float32"> {
  let summary = "32-bit floating-point type";
}

//===----------------------------------------------------------------------===//
// Float64Type

def Builtin_Float64 : Builtin_FloatType<"Float64"> {
  let summary = "64-bit floating-point type";
}

//===----------------------------------------------------------------------===//
// Float80Type

def Builtin_Float80 : Builtin_FloatType<"Float80"> {
  let summary = "80-bit floating-point type";
}

//===----------------------------------------------------------------------===//
// Float128Type

def Builtin_Float128 : Builtin_FloatType<"Float128"> {
  let summary = "128-bit floating-point type";
}

//===----------------------------------------------------------------------===//
// FunctionType
//===----------------------------------------------------------------------===//

def Builtin_Function : Builtin_Type<"Function", [
    DeclareTypeInterfaceMethods<SubElementTypeInterface>
  ]> {
  let summary = "Map from a list of inputs to a list of results";
  let description = [{
    Syntax:

    ```
    // Function types may have multiple results.
    function-result-type ::= type-list-parens | non-function-type
    function-type ::= type-list-parens `->` function-result-type
    ```

    The function type can be thought of as a function signature. It consists of
    a list of formal parameter types and a list of formal result types.
  }];
  let parameters = (ins "ArrayRef<Type>":$inputs, "ArrayRef<Type>":$results);
  let builders = [
    TypeBuilder<(ins CArg<"TypeRange">:$inputs, CArg<"TypeRange">:$results), [{
      return $_get($_ctxt, inputs, results);
    }]>
  ];
  let skipDefaultBuilders = 1;
  let genStorageClass = 0;
  let extraClassDeclaration = [{
    /// Input types.
    unsigned getNumInputs() const;
    Type getInput(unsigned i) const { return getInputs()[i]; }

    /// Result types.
    unsigned getNumResults() const;
    Type getResult(unsigned i) const { return getResults()[i]; }

    /// Returns a new function type with the specified arguments and results
    /// inserted.
    FunctionType getWithArgsAndResults(ArrayRef<unsigned> argIndices,
                                       TypeRange argTypes,
                                       ArrayRef<unsigned> resultIndices,
                                       TypeRange resultTypes);

    /// Returns a new function type without the specified arguments and results.
    FunctionType getWithoutArgsAndResults(ArrayRef<unsigned> argIndices,
                                          ArrayRef<unsigned> resultIndices);
  }];
}

//===----------------------------------------------------------------------===//
// IndexType
//===----------------------------------------------------------------------===//

def Builtin_Index : Builtin_Type<"Index"> {
  let summary = "Integer-like type with unknown platform-dependent bit width";
  let description = [{
    Syntax:

    ```
    // Target word-sized integer.
    index-type ::= `index`
    ```

    The index type is a signless integer whose size is equal to the natural
    machine word of the target ( [rationale](https://mlir.llvm.org/docs/Rationale/Rationale/#integer-signedness-semantics) )
    and is used by the affine constructs in MLIR.

    **Rationale:** integers of platform-specific bit widths are practical to
    express sizes, dimensionalities and subscripts.
  }];
  let extraClassDeclaration = [{
    static IndexType get(MLIRContext *context);

    /// Storage bit width used for IndexType by internal compiler data
    /// structures.
    static constexpr unsigned kInternalStorageBitWidth = 64;
  }];
}

//===----------------------------------------------------------------------===//
// IntegerType
//===----------------------------------------------------------------------===//

def Builtin_Integer : Builtin_Type<"Integer"> {
  let summary = "Integer type with arbitrary precision up to a fixed limit";
  let description = [{
    Syntax:

    ```
    // Sized integers like i1, i4, i8, i16, i32.
    signed-integer-type ::= `si` [1-9][0-9]*
    unsigned-integer-type ::= `ui` [1-9][0-9]*
    signless-integer-type ::= `i` [1-9][0-9]*
    integer-type ::= signed-integer-type |
                     unsigned-integer-type |
                     signless-integer-type
    ```

    Integer types have a designated bit width and may optionally have signedness
    semantics.

    **Rationale:** low precision integers (like `i2`, `i4` etc) are useful for
    low-precision inference chips, and arbitrary precision integers are useful
    for hardware synthesis (where a 13 bit multiplier is a lot cheaper/smaller
    than a 16 bit one).
  }];
  let parameters = (ins "unsigned":$width, "SignednessSemantics":$signedness);
  let builders = [
    TypeBuilder<(ins "unsigned":$width,
                     CArg<"SignednessSemantics", "Signless">:$signedness)>
  ];

  // IntegerType uses a special storage class that compacts parameters to save
  // memory.
  let genStorageClass = 0;
  let skipDefaultBuilders = 1;
  let genVerifyDecl = 1;
  let extraClassDeclaration = [{
    /// Signedness semantics.
    enum SignednessSemantics : uint32_t {
      Signless, /// No signedness semantics
      Signed,   /// Signed integer
      Unsigned, /// Unsigned integer
    };

    /// Return true if this is a signless integer type.
    bool isSignless() const { return getSignedness() == Signless; }
    /// Return true if this is a signed integer type.
    bool isSigned() const { return getSignedness() == Signed; }
    /// Return true if this is an unsigned integer type.
    bool isUnsigned() const { return getSignedness() == Unsigned; }

    /// Get or create a new IntegerType with the same signedness as `this` and a
    /// bitwidth scaled by `scale`.
    /// Return null if the scaled element type cannot be represented.
    IntegerType scaleElementBitwidth(unsigned scale);

    /// Integer representation maximal bitwidth.
    /// Note: This is aligned with the maximum width of llvm::IntegerType.
    static constexpr unsigned kMaxWidth = (1 << 24) - 1;
  }];
}

//===----------------------------------------------------------------------===//
// MemRefType
//===----------------------------------------------------------------------===//

def Builtin_MemRef : Builtin_Type<"MemRef", [
    DeclareTypeInterfaceMethods<SubElementTypeInterface>
  ], "BaseMemRefType"> {
  let summary = "Shaped reference to a region of memory";
  let description = [{
    Syntax:

    ```
    memref-type ::= `memref` `<` dimension-list-ranked type
                    (`,` layout-specification)? (`,` memory-space)? `>`

    stride-list ::= `[` (dimension (`,` dimension)*)? `]`
    strided-layout ::= `offset:` dimension `,` `strides: ` stride-list
    layout-specification ::= semi-affine-map | strided-layout | attribute-value
    memory-space ::= attribute-value
    ```

    A `memref` type is a reference to a region of memory (similar to a buffer
    pointer, but more powerful). The buffer pointed to by a memref can be
    allocated, aliased and deallocated. A memref can be used to read and write
    data from/to the memory region which it references. Memref types use the
    same shape specifier as tensor types. Note that `memref<f32>`,
    `memref<0 x f32>`, `memref<1 x 0 x f32>`, and `memref<0 x 1 x f32>` are all
    different types.

    A `memref` is allowed to have an unknown rank (e.g. `memref<*xf32>`). The
    purpose of unranked memrefs is to allow external library functions to
    receive memref arguments of any rank without versioning the functions based
    on the rank. Other uses of this type are disallowed or will have undefined
    behavior.

    Are accepted as elements:

    - built-in integer types;
    - built-in index type;
    - built-in floating point types;
    - built-in vector types with elements of the above types;
    - another memref type;
    - any other type implementing `MemRefElementTypeInterface`.

    ##### Codegen of Unranked Memref

    Using unranked memref in codegen besides the case mentioned above is highly
    discouraged. Codegen is concerned with generating loop nests and specialized
    instructions for high-performance, unranked memref is concerned with hiding
    the rank and thus, the number of enclosing loops required to iterate over
    the data. However, if there is a need to code-gen unranked memref, one
    possible path is to cast into a static ranked type based on the dynamic
    rank. Another possible path is to emit a single while loop conditioned on a
    linear index and perform delinearization of the linear index to a dynamic
    array containing the (unranked) indices. While this is possible, it is
    expected to not be a good idea to perform this during codegen as the cost
    of the translations is expected to be prohibitive and optimizations at this
    level are not expected to be worthwhile. If expressiveness is the main
    concern, irrespective of performance, passing unranked memrefs to an
    external C++ library and implementing rank-agnostic logic there is expected
    to be significantly simpler.

    Unranked memrefs may provide expressiveness gains in the future and help
    bridge the gap with unranked tensors. Unranked memrefs will not be expected
    to be exposed to codegen but one may query the rank of an unranked memref
    (a special op will be needed for this purpose) and perform a switch and cast
    to a ranked memref as a prerequisite to codegen.

    Example:

    ```mlir
    // With static ranks, we need a function for each possible argument type
    %A = alloc() : memref<16x32xf32>
    %B = alloc() : memref<16x32x64xf32>
    call @helper_2D(%A) : (memref<16x32xf32>)->()
    call @helper_3D(%B) : (memref<16x32x64xf32>)->()

    // With unknown rank, the functions can be unified under one unranked type
    %A = alloc() : memref<16x32xf32>
    %B = alloc() : memref<16x32x64xf32>
    // Remove rank info
    %A_u = memref_cast %A : memref<16x32xf32> -> memref<*xf32>
    %B_u = memref_cast %B : memref<16x32x64xf32> -> memref<*xf32>
    // call same function with dynamic ranks
    call @helper(%A_u) : (memref<*xf32>)->()
    call @helper(%B_u) : (memref<*xf32>)->()
    ```

    The core syntax and representation of a layout specification is a
    [semi-affine map](Affine.md/#semi-affine-maps). Additionally,
    syntactic sugar is supported to make certain layout specifications more
    intuitive to read. For the moment, a `memref` supports parsing a strided
    form which is converted to a semi-affine map automatically.

    The memory space of a memref is specified by a target-specific attribute.
    It might be an integer value, string, dictionary or custom dialect attribute.
    The empty memory space (attribute is None) is target specific.

    The notionally dynamic value of a memref value includes the address of the
    buffer allocated, as well as the symbols referred to by the shape, layout
    map, and index maps.

    Examples of memref static type

    ```mlir
    // Identity index/layout map
    #identity = affine_map<(d0, d1) -> (d0, d1)>

    // Column major layout.
    #col_major = affine_map<(d0, d1, d2) -> (d2, d1, d0)>

    // A 2-d tiled layout with tiles of size 128 x 256.
    #tiled_2d_128x256 = affine_map<(d0, d1) -> (d0 div 128, d1 div 256, d0 mod 128, d1 mod 256)>

    // A tiled data layout with non-constant tile sizes.
    #tiled_dynamic = affine_map<(d0, d1)[s0, s1] -> (d0 floordiv s0, d1 floordiv s1,
                                 d0 mod s0, d1 mod s1)>

    // A layout that yields a padding on two at either end of the minor dimension.
    #padded = affine_map<(d0, d1) -> (d0, (d1 + 2) floordiv 2, (d1 + 2) mod 2)>


    // The dimension list "16x32" defines the following 2D index space:
    //
    //   { (i, j) : 0 <= i < 16, 0 <= j < 32 }
    //
    memref<16x32xf32, #identity>

    // The dimension list "16x4x?" defines the following 3D index space:
    //
    //   { (i, j, k) : 0 <= i < 16, 0 <= j < 4, 0 <= k < N }
    //
    // where N is a symbol which represents the runtime value of the size of
    // the third dimension.
    //
    // %N here binds to the size of the third dimension.
    %A = alloc(%N) : memref<16x4x?xf32, #col_major>

    // A 2-d dynamic shaped memref that also has a dynamically sized tiled
    // layout. The memref index space is of size %M x %N, while %B1 and %B2
    // bind to the symbols s0, s1 respectively of the layout map #tiled_dynamic.
    // Data tiles of size %B1 x %B2 in the logical space will be stored
    // contiguously in memory. The allocation size will be
    // (%M ceildiv %B1) * %B1 * (%N ceildiv %B2) * %B2 f32 elements.
    %T = alloc(%M, %N) [%B1, %B2] : memref<?x?xf32, #tiled_dynamic>

    // A memref that has a two-element padding at either end. The allocation
    // size will fit 16 * 64 float elements of data.
    %P = alloc() : memref<16x64xf32, #padded>

    // Affine map with symbol 's0' used as offset for the first dimension.
    #imapS = affine_map<(d0, d1) [s0] -> (d0 + s0, d1)>
    // Allocate memref and bind the following symbols:
    // '%n' is bound to the dynamic second dimension of the memref type.
    // '%o' is bound to the symbol 's0' in the affine map of the memref type.
    %n = ...
    %o = ...
    %A = alloc (%n)[%o] : <16x?xf32, #imapS>
    ```

    ##### Index Space

    A memref dimension list defines an index space within which the memref can
    be indexed to access data.

    ##### Index

    Data is accessed through a memref type using a multidimensional index into
    the multidimensional index space defined by the memref's dimension list.

    Examples

    ```mlir
    // Allocates a memref with 2D index space:
    //   { (i, j) : 0 <= i < 16, 0 <= j < 32 }
    %A = alloc() : memref<16x32xf32, #imapA>

    // Loads data from memref '%A' using a 2D index: (%i, %j)
    %v = load %A[%i, %j] : memref<16x32xf32, #imapA>
    ```

    ##### Index Map

    An index map is a one-to-one
    [semi-affine map](Affine.md/#semi-affine-maps) that transforms a
    multidimensional index from one index space to another. For example, the
    following figure shows an index map which maps a 2-dimensional index from a
    2x2 index space to a 3x3 index space, using symbols `S0` and `S1` as
    offsets.

    ![Index Map Example](/includes/img/index-map.svg)

    The number of domain dimensions and range dimensions of an index map can be
    different, but must match the number of dimensions of the input and output
    index spaces on which the map operates. The index space is always
    non-negative and integral. In addition, an index map must specify the size
    of each of its range dimensions onto which it maps. Index map symbols must
    be listed in order with symbols for dynamic dimension sizes first, followed
    by other required symbols.

    ##### Layout Map

    A layout map is a [semi-affine map](Affine.md/#semi-affine-maps)
    which encodes logical to physical index space mapping, by mapping input
    dimensions to their ordering from most-major (slowest varying) to most-minor
    (fastest varying). Therefore, an identity layout map corresponds to a
    row-major layout. Identity layout maps do not contribute to the MemRef type
    identification and are discarded on construction. That is, a type with an
    explicit identity map is `memref<?x?xf32, (i,j)->(i,j)>` is strictly the
    same as the one without layout maps, `memref<?x?xf32>`.

    Layout map examples:

    ```mlir
    // MxN matrix stored in row major layout in memory:
    #layout_map_row_major = (i, j) -> (i, j)

    // MxN matrix stored in column major layout in memory:
    #layout_map_col_major = (i, j) -> (j, i)

    // MxN matrix stored in a 2-d blocked/tiled layout with 64x64 tiles.
    #layout_tiled = (i, j) -> (i floordiv 64, j floordiv 64, i mod 64, j mod 64)
    ```

    ##### Strided MemRef

    A memref may specify a strided layout as part of its type. A stride
    specification is a list of integer values that are either static or `?`
    (dynamic case).
    Strides encode the distance, in number of elements, in (linear) memory
    between successive entries along a particular dimension. A stride
    specification is syntactic sugar for an equivalent strided memref
    representation with a *single* semi-affine map.

    For example, `memref<42x16xf32, offset: 33, strides: [1, 64]>` specifies a
    non-contiguous memory region of `42` by `16` `f32` elements such that:

    1.  the minimal size of the enclosing memory region must be
        `33 + 42 * 1 + 16 * 64 = 1066` elements;
    2.  the address calculation for accessing element `(i, j)` computes
        `33 + i + 64 * j`
    3.  the distance between two consecutive elements along the inner dimension
        is `1` element and the distance between two consecutive elements along
        the outer dimension is `64` elements.

    This corresponds to a column major view of the memory region and is
    internally represented as the type
    `memref<42x16xf32, (i, j) -> (33 + i + 64 * j)>`.

    The specification of strides must not alias: given an n-D strided memref,
    indices `(i1, ..., in)` and `(j1, ..., jn)` may not refer to the same memory
    address unless `i1 == j1, ..., in == jn`.

    Strided memrefs represent a view abstraction over preallocated data. They
    are constructed with special ops, yet to be introduced. Strided memrefs are
    a special subclass of memrefs with generic semi-affine map and correspond to
    a normalized memref descriptor when lowering to LLVM.
  }];
  let parameters = (ins
    ArrayRefParameter<"int64_t">:$shape,
    "Type":$elementType,
    "MemRefLayoutAttrInterface":$layout,
    "Attribute":$memorySpace
  );
  let builders = [
    TypeBuilderWithInferredContext<(ins
      "ArrayRef<int64_t>":$shape, "Type":$elementType,
      CArg<"MemRefLayoutAttrInterface", "{}">:$layout,
      CArg<"Attribute", "{}">:$memorySpace)>,
    TypeBuilderWithInferredContext<(ins
      "ArrayRef<int64_t>":$shape, "Type":$elementType,
      CArg<"AffineMap">:$map,
      CArg<"Attribute", "{}">:$memorySpace)>,
    /// [deprecated] `Attribute`-based form should be used instead.
    TypeBuilderWithInferredContext<(ins
      "ArrayRef<int64_t>":$shape, "Type":$elementType,
      "AffineMap":$map,
      "unsigned":$memorySpaceInd)>
  ];
  let extraClassDeclaration = [{
    /// This is a builder type that keeps local references to arguments.
    /// Arguments that are passed into the builder must outlive the builder.
    class Builder;

    /// [deprecated] Returns the memory space in old raw integer representation.
    /// New `Attribute getMemorySpace()` method should be used instead.
    unsigned getMemorySpaceAsInt() const;

    // TODO: merge these two special values in a single one used everywhere.
    // Unfortunately, uses of `-1` have crept deep into the codebase now and are
    // hard to track.
    static int64_t getDynamicStrideOrOffset() {
      return ShapedType::kDynamicStrideOrOffset;
    }
  }];
  let skipDefaultBuilders = 1;
  let genVerifyDecl = 1;
}

//===----------------------------------------------------------------------===//
// NoneType
//===----------------------------------------------------------------------===//

def Builtin_None : Builtin_Type<"None"> {
  let summary = "A unit type";
  let description = [{
    NoneType is a unit type, i.e. a type with exactly one possible value, where
    its value does not have a defined dynamic representation.
  }];
  let extraClassDeclaration = [{
    static NoneType get(MLIRContext *context);
  }];
}

//===----------------------------------------------------------------------===//
// OpaqueType
//===----------------------------------------------------------------------===//

def Builtin_Opaque : Builtin_Type<"Opaque"> {
  let summary = "Type of a non-registered dialect";
  let description = [{
    Syntax:

    ```
    opaque-type ::= `opaque` `<` type `>`
    ```

    Opaque types represent types of non-registered dialects. These are types
    represented in their raw string form, and can only usefully be tested for
    type equality.

    Examples:

    ```mlir
    opaque<"llvm", "struct<(i32, float)>">
    opaque<"pdl", "value">
    ```
  }];
  let parameters = (ins
    "StringAttr":$dialectNamespace,
    StringRefParameter<"">:$typeData
  );

  let builders = [
    TypeBuilderWithInferredContext<(ins
      "StringAttr":$dialectNamespace, CArg<"StringRef", "{}">:$typeData
    ), [{
      return $_get(dialectNamespace.getContext(), dialectNamespace, typeData);
    }]>
  ];
  let skipDefaultBuilders = 1;
  let genVerifyDecl = 1;
}

//===----------------------------------------------------------------------===//
// RankedTensorType
//===----------------------------------------------------------------------===//

def Builtin_RankedTensor : Builtin_Type<"RankedTensor", [
    DeclareTypeInterfaceMethods<SubElementTypeInterface>
  ], "TensorType"> {
  let summary = "Multi-dimensional array with a fixed number of dimensions";
  let description = [{
    Syntax:

    ```
    tensor-type ::= `tensor` `<` dimension-list type (`,` encoding)? `>`
    dimension-list ::= (dimension `x`)*
    dimension ::= `?` | decimal-literal
    encoding ::= attribute-value
    ```

    Values with tensor type represents aggregate N-dimensional data values, and
    have a known element type and a fixed rank with a list of dimensions. Each
    dimension may be a static non-negative decimal constant or be dynamically
    determined (indicated by `?`).

    The runtime representation of the MLIR tensor type is intentionally
    abstracted - you cannot control layout or get a pointer to the data. For
    low level buffer access, MLIR has a [`memref` type](#memref-type). This
    abstracted runtime representation holds both the tensor data values as well
    as information about the (potentially dynamic) shape of the tensor. The
    [`dim` operation](MemRef.md/#memrefdim-mlirmemrefdimop) returns the size of a
    dimension from a value of tensor type.

    The `encoding` attribute provides additional information on the tensor.
    An empty attribute denotes a straightforward tensor without any specific
    structure. But particular properties, like sparsity or other specific
    characteristics of the data of the tensor can be encoded through this
    attribute. The semantics are defined by a type and attribute interface
    and must be respected by all passes that operate on tensor types.
    TODO: provide this interface, and document it further.

    Note: hexadecimal integer literals are not allowed in tensor type
    declarations to avoid confusion between `0xf32` and `0 x f32`. Zero sizes
    are allowed in tensors and treated as other sizes, e.g.,
    `tensor<0 x 1 x i32>` and `tensor<1 x 0 x i32>` are different types. Since
    zero sizes are not allowed in some other types, such tensors should be
    optimized away before lowering tensors to vectors.

    Examples:

    ```mlir
    // Known rank but unknown dimensions.
    tensor<? x ? x ? x ? x f32>

    // Partially known dimensions.
    tensor<? x ? x 13 x ? x f32>

    // Full static shape.
    tensor<17 x 4 x 13 x 4 x f32>

    // Tensor with rank zero. Represents a scalar.
    tensor<f32>

    // Zero-element dimensions are allowed.
    tensor<0 x 42 x f32>

    // Zero-element tensor of f32 type (hexadecimal literals not allowed here).
    tensor<0xf32>

    // Tensor with an encoding attribute (where #ENCODING is a named alias).
    tensor<?x?xf64, #ENCODING>
    ```
  }];
  let parameters = (ins
    ArrayRefParameter<"int64_t">:$shape,
    "Type":$elementType,
    "Attribute":$encoding
  );

  let builders = [
    TypeBuilderWithInferredContext<(ins
      "ArrayRef<int64_t>":$shape,
      "Type":$elementType,
      CArg<"Attribute", "{}">:$encoding
    ), [{
      return $_get(elementType.getContext(), shape, elementType, encoding);
    }]>
  ];
  let extraClassDeclaration = [{
    /// This is a builder type that keeps local references to arguments.
    /// Arguments that are passed into the builder must outlive the builder.
    class Builder;
  }];
  let skipDefaultBuilders = 1;
  let genVerifyDecl = 1;
}

//===----------------------------------------------------------------------===//
// TupleType
//===----------------------------------------------------------------------===//

def Builtin_Tuple : Builtin_Type<"Tuple", [
    DeclareTypeInterfaceMethods<SubElementTypeInterface>
  ]> {
  let summary = "Fixed-sized collection of other types";
  let description = [{
    Syntax:

    ```
    tuple-type ::= `tuple` `<` (type ( `,` type)*)? `>`
    ```

    The value of `tuple` type represents a fixed-size collection of elements,
    where each element may be of a different type.

    **Rationale:** Though this type is first class in the type system, MLIR
    provides no standard operations for operating on `tuple` types
    ([rationale](Rationale/Rationale/#tuple-types)).

    Examples:

    ```mlir
    // Empty tuple.
    tuple<>

    // Single element
    tuple<f32>

    // Many elements.
    tuple<i32, f32, tensor<i1>, i5>
    ```
  }];
  let parameters = (ins "ArrayRef<Type>":$types);
  let builders = [
    TypeBuilder<(ins "TypeRange":$elementTypes), [{
      return $_get($_ctxt, elementTypes);
    }]>,
    TypeBuilder<(ins), [{
      return $_get($_ctxt, TypeRange());
    }]>
  ];
  let skipDefaultBuilders = 1;
  let genStorageClass = 0;
  let extraClassDeclaration = [{
    /// Accumulate the types contained in this tuple and tuples nested within
    /// it. Note that this only flattens nested tuples, not any other container
    /// type, e.g. a tuple<i32, tensor<i32>, tuple<f32, tuple<i64>>> is
    /// flattened to (i32, tensor<i32>, f32, i64)
    void getFlattenedTypes(SmallVectorImpl<Type> &types);

    /// Return the number of held types.
    size_t size() const;

    /// Iterate over the held elements.
    using iterator = ArrayRef<Type>::iterator;
    iterator begin() const { return getTypes().begin(); }
    iterator end() const { return getTypes().end(); }

    /// Return the element type at index 'index'.
    Type getType(size_t index) const {
      assert(index < size() && "invalid index for tuple type");
      return getTypes()[index];
    }
  }];
}

//===----------------------------------------------------------------------===//
// UnrankedMemRefType
//===----------------------------------------------------------------------===//

def Builtin_UnrankedMemRef : Builtin_Type<"UnrankedMemRef", [
    DeclareTypeInterfaceMethods<SubElementTypeInterface>
  ], "BaseMemRefType"> {
  let summary = "Shaped reference, with unknown rank, to a region of memory";
  let description = [{
    Syntax:

    ```
    unranked-memref-type ::= `memref` `<*x` type (`,` memory-space)? `>`
    memory-space ::= attribute-value
    ```

    A `memref` type with an unknown rank (e.g. `memref<*xf32>`). The purpose of
    unranked memrefs is to allow external library functions to receive memref
    arguments of any rank without versioning the functions based on the rank.
    Other uses of this type are disallowed or will have undefined behavior.

    See [MemRefType](#builtin_memref-memreftype) for more information on
    memref types.

    Examples:

    ```mlir
    memref<*f32>

    // An unranked memref with a memory space of 10.
    memref<*f32, 10>
    ```
  }];
  let parameters = (ins "Type":$elementType, "Attribute":$memorySpace);

  let builders = [
    TypeBuilderWithInferredContext<(ins "Type":$elementType,
                                        "Attribute":$memorySpace), [{
      // Drop default memory space value and replace it with empty attribute.
      Attribute nonDefaultMemorySpace = skipDefaultMemorySpace(memorySpace);
      return $_get(elementType.getContext(), elementType, nonDefaultMemorySpace);
    }]>,
    /// [deprecated] `Attribute`-based form should be used instead.
    TypeBuilderWithInferredContext<(ins "Type":$elementType,
                                        "unsigned":$memorySpace), [{
      // Convert deprecated integer-like memory space to Attribute.
      Attribute memorySpaceAttr =
          wrapIntegerMemorySpace(memorySpace, elementType.getContext());
      return UnrankedMemRefType::get(elementType, memorySpaceAttr);
    }]>
  ];
  let extraClassDeclaration = [{
    ArrayRef<int64_t> getShape() const { return llvm::None; }

    /// [deprecated] Returns the memory space in old raw integer representation.
    /// New `Attribute getMemorySpace()` method should be used instead.
    unsigned getMemorySpaceAsInt() const;
  }];
  let skipDefaultBuilders = 1;
  let genVerifyDecl = 1;
}

//===----------------------------------------------------------------------===//
// UnrankedTensorType
//===----------------------------------------------------------------------===//

def Builtin_UnrankedTensor : Builtin_Type<"UnrankedTensor", [
    DeclareTypeInterfaceMethods<SubElementTypeInterface>
  ], "TensorType"> {
  let summary = "Multi-dimensional array with unknown dimensions";
  let description = [{
    Syntax:

    ```
    tensor-type ::= `tensor` `<` `*` `x` type `>`
    ```

    An unranked tensor is a type of tensor in which the set of dimensions have
    unknown rank. See [RankedTensorType](#builtin_rankedtensor-rankedtensortype)
    for more information on tensor types.

    Examples:

    ```mlir
    tensor<*f32>
    ```
  }];
  let parameters = (ins "Type":$elementType);

  let builders = [
    TypeBuilderWithInferredContext<(ins "Type":$elementType), [{
      return $_get(elementType.getContext(), elementType);
    }]>
  ];
  let extraClassDeclaration = [{
    ArrayRef<int64_t> getShape() const { return llvm::None; }
  }];
  let skipDefaultBuilders = 1;
  let genVerifyDecl = 1;
}

//===----------------------------------------------------------------------===//
// VectorType
//===----------------------------------------------------------------------===//

def Builtin_Vector : Builtin_Type<"Vector", [
    DeclareTypeInterfaceMethods<SubElementTypeInterface>
  ], "ShapedType"> {
  let summary = "Multi-dimensional SIMD vector type";
  let description = [{
    Syntax:

    ```
    vector-type ::= `vector` `<` static-dimension-list vector-element-type `>`
    vector-element-type ::= float-type | integer-type | index-type

    static-dimension-list ::= (decimal-literal `x`)*
    ```

    The vector type represents a SIMD style vector, used by target-specific
    operation sets like AVX. While the most common use is for 1D vectors (e.g.
    vector<16 x f32>) we also support multidimensional registers on targets that
    support them (like TPUs).

    Vector shapes must be positive decimal integers. 0D vectors are allowed by
    omitting the dimension: `vector<f32>`.

    Note: hexadecimal integer literals are not allowed in vector type
    declarations, `vector<0x42xi32>` is invalid because it is interpreted as a
    2D vector with shape `(0, 42)` and zero shapes are not allowed.

    Examples:

    ```mlir
    vector<3x42xi32>
    ```
  }];
  let parameters = (ins
    ArrayRefParameter<"int64_t">:$shape,
    "Type":$elementType
  );

  let builders = [
    TypeBuilderWithInferredContext<(ins
      "ArrayRef<int64_t>":$shape, "Type":$elementType
    ), [{
      return $_get(elementType.getContext(), shape, elementType);
    }]>
  ];
  let extraClassDeclaration = [{
    /// This is a builder type that keeps local references to arguments.
    /// Arguments that are passed into the builder must outlive the builder.
    class Builder;

    /// Returns true of the given type can be used as an element of a vector
    /// type. In particular, vectors can consist of integer, index, or float
    /// primitives.
    static bool isValidElementType(Type t) {
      return t.isa<IntegerType, IndexType, FloatType>();
    }

    /// Get or create a new VectorType with the same shape as `this` and an
    /// element type of bitwidth scaled by `scale`.
    /// Return null if the scaled element type cannot be represented.
    VectorType scaleElementBitwidth(unsigned scale);
  }];
  let skipDefaultBuilders = 1;
  let genVerifyDecl = 1;
}

#endif // BUILTIN_TYPES
