Changeset View
Changeset View
Standalone View
Standalone View
mlir/docs/Tutorials/Toy/Ch-7.md
Show First 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | |||||
provide a type that does exactly what we need, so we will need to define our | provide a type that does exactly what we need, so we will need to define our | ||||
own. We will simply define our `struct` as an unnamed container of a set of | own. We will simply define our `struct` as an unnamed container of a set of | ||||
element types. The name of the `struct` and its elements are only useful for the | element types. The name of the `struct` and its elements are only useful for the | ||||
AST of our `toy` compiler, so we don't need to encode it in the MLIR | AST of our `toy` compiler, so we don't need to encode it in the MLIR | ||||
representation. | representation. | ||||
### Defining the Type Class | ### Defining the Type Class | ||||
#### Reserving a Range of Type Kinds | |||||
Types in MLIR rely on having a unique `kind` value to ensure that casting checks | |||||
remain extremely efficient | |||||
([rationale](../../Rationale/Rationale.md#reserving-dialect-type-kinds)). For `toy`, this | |||||
means we need to explicitly reserve a static range of type `kind` values in the | |||||
symbol registry file | |||||
[DialectSymbolRegistry](https://github.com/llvm/llvm-project/blob/master/mlir/include/mlir/IR/DialectSymbolRegistry.def). | |||||
```c++ | |||||
DEFINE_SYM_KIND_RANGE(LINALG) // Linear Algebra Dialect | |||||
DEFINE_SYM_KIND_RANGE(TOY) // Toy language (tutorial) Dialect | |||||
// The following ranges are reserved for experimenting with MLIR dialects in a | |||||
// private context. | |||||
DEFINE_SYM_KIND_RANGE(PRIVATE_EXPERIMENTAL_0) | |||||
``` | |||||
These definitions will provide a range in the Type::Kind enum to use when | |||||
defining the derived types. | |||||
```c++ | |||||
/// Create a local enumeration with all of the types that are defined by Toy. | |||||
namespace ToyTypes { | |||||
enum Types { | |||||
Struct = mlir::Type::FIRST_TOY_TYPE, | |||||
}; | |||||
} // end namespace ToyTypes | |||||
``` | |||||
#### Defining the Type Class | #### Defining the Type Class | ||||
As mentioned in [chapter 2](Ch-2.md), [`Type`](../../LangRef.md#type-system) | As mentioned in [chapter 2](Ch-2.md), [`Type`](../../LangRef.md#type-system) | ||||
objects in MLIR are value-typed and rely on having an internal storage object | objects in MLIR are value-typed and rely on having an internal storage object | ||||
that holds the actual data for the type. The `Type` class in itself acts as a | that holds the actual data for the type. The `Type` class in itself acts as a | ||||
simple wrapper around an internal `TypeStorage` object that is uniqued within an | simple wrapper around an internal `TypeStorage` object that is uniqued within an | ||||
instance of an `MLIRContext`. When constructing a `Type`, we are internally just | instance of an `MLIRContext`. When constructing a `Type`, we are internally just | ||||
constructing and uniquing an instance of a storage class. | constructing and uniquing an instance of a storage class. | ||||
When defining a new `Type` that requires additional information beyond just the | When defining a new `Type` that contains parametric data (e.g. the `struct` | ||||
`kind` (e.g. the `struct` type, which requires additional information to hold | type, which requires additional information to hold the element types), we will | ||||
the element types), we will need to provide a derived storage class. The | need to provide a derived storage class. The `singleton` types that don't have | ||||
`primitive` types that don't have any additional data (e.g. the | any additional data (e.g. the [`index` type](../../LangRef.md#index-type)) don't | ||||
[`index` type](../../LangRef.md#index-type)) don't require a storage class. | require a storage class and use the default `TypeStorage`. | ||||
##### Defining the Storage Class | ##### Defining the Storage Class | ||||
Type storage objects contain all of the data necessary to construct and unique a | Type storage objects contain all of the data necessary to construct and unique a | ||||
type instance. Derived storage classes must inherit from the base | type instance. Derived storage classes must inherit from the base | ||||
`mlir::TypeStorage` and provide a set of aliases and hooks that will be used by | `mlir::TypeStorage` and provide a set of aliases and hooks that will be used by | ||||
the `MLIRContext` for uniquing. Below is the definition of the storage instance | the `MLIRContext` for uniquing. Below is the definition of the storage instance | ||||
for our `struct` type, with each of the necessary requirements detailed inline: | for our `struct` type, with each of the necessary requirements detailed inline: | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | public: | ||||
/// Create an instance of a `StructType` with the given element types. There | /// Create an instance of a `StructType` with the given element types. There | ||||
/// *must* be at least one element type. | /// *must* be at least one element type. | ||||
static StructType get(llvm::ArrayRef<mlir::Type> elementTypes) { | static StructType get(llvm::ArrayRef<mlir::Type> elementTypes) { | ||||
assert(!elementTypes.empty() && "expected at least 1 element type"); | assert(!elementTypes.empty() && "expected at least 1 element type"); | ||||
// Call into a helper 'get' method in 'TypeBase' to get a uniqued instance | // Call into a helper 'get' method in 'TypeBase' to get a uniqued instance | ||||
// of this type. The first parameter is the context to unique in. The | // of this type. The first parameter is the context to unique in. The | ||||
// parameters after the type kind are forwarded to the storage instance. | // parameters after are forwarded to the storage instance. | ||||
mlir::MLIRContext *ctx = elementTypes.front().getContext(); | mlir::MLIRContext *ctx = elementTypes.front().getContext(); | ||||
return Base::get(ctx, elementTypes); | return Base::get(ctx, elementTypes); | ||||
} | } | ||||
/// Returns the element types of this struct type. | /// Returns the element types of this struct type. | ||||
llvm::ArrayRef<mlir::Type> getElementTypes() { | llvm::ArrayRef<mlir::Type> getElementTypes() { | ||||
// 'getImpl' returns a pointer to the internal storage instance. | // 'getImpl' returns a pointer to the internal storage instance. | ||||
return getImpl()->elementTypes; | return getImpl()->elementTypes; | ||||
▲ Show 20 Lines • Show All 336 Lines • Show Last 20 Lines |