[llvm-branch-commits] [mlir] 7fd1850 - [mlir] Update LLVM dialect type documentation
Alex Zinenko via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jan 12 13:42:36 PST 2021
Author: Alex Zinenko
Date: 2021-01-12T22:38:24+01:00
New Revision: 7fd18508134112edb93852c16923a74bfff99cd2
URL: https://github.com/llvm/llvm-project/commit/7fd18508134112edb93852c16923a74bfff99cd2
DIFF: https://github.com/llvm/llvm-project/commit/7fd18508134112edb93852c16923a74bfff99cd2.diff
LOG: [mlir] Update LLVM dialect type documentation
Recent commits reconfigured LLVM dialect types to use built-in types whenever
possible. Update the documentation accordingly.
Reviewed By: mehdi_amini
Differential Revision: https://reviews.llvm.org/D94485
Added:
Modified:
mlir/docs/Dialects/LLVM.md
Removed:
################################################################################
diff --git a/mlir/docs/Dialects/LLVM.md b/mlir/docs/Dialects/LLVM.md
index d232ffab148c..1b85091b0756 100644
--- a/mlir/docs/Dialects/LLVM.md
+++ b/mlir/docs/Dialects/LLVM.md
@@ -130,9 +130,9 @@ Examples:
%3 = llvm.mlir.constant(dense<1.0> : vector<4xf32>) : vector<4xf32>
```
-Note that constants use built-in types within the initializer definition: MLIR
-attributes are typed and the attributes used for constants require a built-in
-type.
+Note that constants list the type twice. This is an artifact of the LLVM dialect
+not using built-in types, which are used for typed MLIR attributes. The syntax
+will be reevaluated after considering composite constants.
### Globals
@@ -186,33 +186,47 @@ attribute.
## Types
-LLVM dialect defines a set of types that correspond to LLVM IR types. The
-dialect type system is _closed_: types from other dialects are not allowed
-within LLVM dialect aggregate types. This property allows for more concise
-custom syntax and ensures easy translation to LLVM IR.
-
-Similarly to other MLIR context-owned objects, the creation and manipulation of
-LLVM dialect types is thread-safe.
+LLVM dialect uses built-in types whenever possible and defines a set of
+complementary types, which correspond to the LLVM IR types that cannot be
+directly represented with built-in types. Similarly to other MLIR context-owned
+objects, the creation and manipulation of LLVM dialect types is thread-safe.
MLIR does not support module-scoped named type declarations, e.g. `%s = type
{i32, i32}` in LLVM IR. Instead, types must be fully specified at each use,
except for recursive types where only the first reference to a named type needs
-to be fully specified. MLIR type aliases are supported for top-level types, i.e.
-they cannot be used inside the type due to type system closedness.
+to be fully specified. MLIR [type aliases](LangRef.md#type-aliases) can be used
+to achieve more compact syntax.
The general syntax of LLVM dialect types is `!llvm.`, followed by a type kind
identifier (e.g., `ptr` for pointer or `struct` for structure) and by an
optional list of type parameters in angle brackets. The dialect follows MLIR
style for types with nested angle brackets and keyword specifiers rather than
-using
diff erent bracket styles to
diff erentiate types. Inside angle brackets,
-the `!llvm` prefix is omitted for brevity; thanks to closedness of the type
-system, all types are assumed to be defined in the LLVM dialect. For example,
-`!llvm.ptr<struct<packed, (i8, i32)>>` is a pointer to a packed structure type
-containing an 8-bit and a 32-bit integer.
+using
diff erent bracket styles to
diff erentiate types. Types inside the angle
+brackets may omit the `!llvm.` prefix for brevity: the parser first attempts to
+find a type (starting with `!` or a built-in type) and falls back to accepting a
+keyword. For example, `!llvm.ptr<!llvm.ptr<i32>>` and `!llvm.ptr<ptr<i32>>` are
+equivalent, with the latter being the canonical form, and denote a pointer to a
+pointer to a 32-bit integer.
+
+### Built-in Type Compatibility
+
+LLVM dialect accepts a subset of built-in types that are referred to as _LLVM
+dialect-compatible types_. The following types are compatible:
-### Simple Types
+- Signless integers - `iN` (`IntegerType`).
+- Floating point types - `bfloat`, `half`, `float`, `double` (`FloatType`).
+- 1D vectors of signless integers or floating point types - `vector<NxT>`
+ (`VectorType`).
-The following non-parametric types are supported.
+Note that only a subset of types that can be represented by a given class is
+compatible. For example, signed and unsigned integers are not compatible. LLVM
+provides a function, `bool LLVM::isCompatibleType(Type)`, that can be used as a
+compatibility check.
+
+### Additional Simple Types
+
+The following non-parametric types derived from the LLVM IR are available in the
+LLVM dialect:
- `!llvm.fp128` (`LLVMFP128Type`) - 128-bit floating-point value as per
IEEE-754-2008.
@@ -231,19 +245,10 @@ The following non-parametric types are supported.
These types represent a single value (or an absence thereof in case of `void`)
and correspond to their LLVM IR counterparts.
-### Parametric Types
-
-#### Integer Types
+### Additional Parametric Types
-Integer types are parametric in MLIR terminology, with their bitwidth being a
-type parameter. They are expressed as follows:
-
-```
- llvm-int-type ::= `!llvm.i` integer-literal
-```
-
-and represented internally as `LLVMIntegerType`. For example, `i1` is a 1-bit
-integer type (bool) and `i32` as a 32-bit integer type.
+These types are parameterized by the types they contain, e.g., the pointee or
+the element type, which can be either compatible built-in or LLVM dialect types.
#### Pointer Types
@@ -255,46 +260,26 @@ reconsidered if MLIR implements named address spaces. Their syntax is as
follows:
```
- llvm-ptr-type ::= `!llvm.ptr<` llvm-type (`,` integer-literal)? `>`
+ llvm-ptr-type ::= `!llvm.ptr<` type (`,` integer-literal)? `>`
```
where the optional integer literal corresponds to the memory space. Both cases
are represented by `LLVMPointerType` internally.
-#### Vector Types
-
-Vector types represent sequences of elements, typically when multiple data
-elements are processed by a single instruction (SIMD). Vectors are thought of as
-stored in registers and therefore vector elements can only be addressed through
-constant indices.
-
-Vector types are parameterized by the size, which may be either _fixed_ or a
-multiple of some fixed size in case of _scalable_ vectors, and the element type.
-Vectors cannot be nested and only 1D vectors are supported. Scalable vectors are
-still considered 1D. Their syntax is as follows:
-
-```
- llvm-vec-type ::= `vector<` (`?` `x`)? integer-literal `x` llvm-type `>`
-```
-
-Internally, fixed vector types are represented as `LLVMFixedVectorType` and
-scalable vector types are represented as `LLVMScalableVectorType`. Both classes
-derive`LLVMVectorType`.
-
#### Array Types
-Array types represent sequences of elements in memory. Unlike vectors, array
-elements can be addressed with a value unknown at compile time, and can be
-nested. Only 1D arrays are allowed though.
+Array types represent sequences of elements in memory. Array elements can be
+addressed with a value unknown at compile time, and can be nested. Only 1D
+arrays are allowed though.
Array types are parameterized by the fixed size and the element type.
-Syntactically, their representation is close to vectors:
+Syntactically, their representation is the following:
```
- llvm-array-type ::= `!llvm.array<` integer-literal `x` llvm-type `>`
+ llvm-array-type ::= `!llvm.array<` integer-literal `x` type `>`
```
-and are internally represented as `LLVMArrayType`.
+and they are internally represented as `LLVMArrayType`.
#### Function Types
@@ -306,15 +291,14 @@ functions (`LLVMFunctionType`) always have single result, which may be
`!llvm.void` if the function does not return anything. The syntax is as follows:
```
- llvm-func-type ::= `!llvm.func<` llvm-type `(` llvm-type-list (`,` `...`)?
- `)` `>`
+ llvm-func-type ::= `!llvm.func<` type `(` type-list (`,` `...`)? `)` `>`
```
For example,
```mlir
-!llvm.func<void ()> // a function with no arguments;
-!llvm.func<i32 (f32, i32)> // a function with two arguments and a result;
+!llvm.func<void ()> // a function with no arguments;
+!llvm.func<i32 (f32, i32)> // a function with two arguments and a result;
!llvm.func<void (i32, ...)> // a variadic function with at least one argument.
```
@@ -322,6 +306,59 @@ In the LLVM dialect, functions are not first-class objects and one cannot have a
value of function type. Instead, one can take the address of a function and
operate on pointers to functions.
+### Vector Types
+
+Vector types represent sequences of elements, typically when multiple data
+elements are processed by a single instruction (SIMD). Vectors are thought of as
+stored in registers and therefore vector elements can only be addressed through
+constant indices.
+
+Vector types are parameterized by the size, which may be either _fixed_ or a
+multiple of some fixed size in case of _scalable_ vectors, and the element type.
+Vectors cannot be nested and only 1D vectors are supported. Scalable vectors are
+still considered 1D.
+
+LLVM dialect uses built-in vector types for _fixed_-size vectors of built-in
+types, and provides additional types for fixed-sized vectors of LLVM dialect
+types (`LLVMFixedVectorType`) and scalable vectors of any types
+(`LLVMScalableVectorType`). These two additional types share the following
+syntax:
+
+```
+ llvm-vec-type ::= `!llvm.vec<` (`?` `x`)? integer-literal `x` type `>`
+```
+
+Note that the sets of element types supported by built-in and LLVM dialect
+vector types are mutually exclusive, e.g., the built-in vector type does not
+accept `!llvm.ptr<i32>` and the LLVM dialect fixed-width vector type does not
+accept `i32`.
+
+The following functions are provided to operate on any kind of the vector types
+compatible with the LLVM dialect:
+
+- `bool LLVM::isCompatibleVectorType(Type)` - checks whether a type is a
+ vector type compatible with the LLVM dialect;
+- `Type LLVM::getVectorElementType(Type)` - returns the element type of any
+ vector type compatible with the LLVM dialect;
+- `llvm::ElementCount LLVM::getVectorNumElements(Type)` - returns the number
+ of elements in any vector type compatible with the LLVM dialect;
+- `Type LLVM::getFixedVectorType(Type, unsigned)` - gets a fixed vector type
+ with the given element type and size; the resulting type is either a
+ built-in or an LLVM dialect vector type depending on which one supports the
+ given element type.
+
+#### Examples of Compatible Vector Types
+
+```mlir
+vector<42 x i32> // Vector of 42 32-bit integers.
+!llvm.vec<42 x ptr<i32>> // Vector of 42 pointers to 32-bit integers.
+!llvm.vec<? x 4 x i32> // Scalable vector of 32-bit integers with
+ // size divisible by 4.
+!llvm.array<2 x vector<2 x i32>> // Array of 2 vectors of 2 32-bit integers.
+!llvm.array<2 x vec<2 x ptr<i32>>> // Array of 2 vectors of 2 pointers to 32-bit
+ // integers.
+```
+
### Structure Types
The structure type is used to represent a collection of data members together in
@@ -362,10 +399,10 @@ The syntax for identified structure types is as follows.
```
llvm-ident-struct-type ::= `!llvm.struct<` string-literal, `opaque` `>`
| `!llvm.struct<` string-literal, `packed`?
- `(` llvm-type-or-ref-list `)` `>`
-llvm-type-or-ref-list ::= <maybe empty comma-separated list of llvm-type-or-ref>
-llvm-type-or-ref ::= <any llvm type>
- | `!llvm.struct<` string-literal >
+ `(` type-or-ref-list `)` `>`
+type-or-ref-list ::= <maybe empty comma-separated list of type-or-ref>
+type-or-ref ::= <any compatible type with optional !llvm.>
+ | `!llvm.`? `struct<` string-literal `>`
```
The body of the identified struct is printed in full unless the it is
@@ -389,9 +426,8 @@ Literal structures are uniqued according to the list of elements they contain,
and can optionally be packed. The syntax for such structs is as follows.
```
-llvm-literal-struct-type ::= `!llvm.struct<` `packed`? `(` llvm-type-list `)`
- `>`
-llvm-type-list ::= <maybe empty comma-separated list of llvm types w/o `!llvm`>
+llvm-literal-struct-type ::= `!llvm.struct<` `packed`? `(` type-list `)` `>`
+type-list ::= <maybe empty comma-separated list of types with optional !llvm.>
```
Literal structs cannot be recursive, but can contain other structs. Therefore,
More information about the llvm-branch-commits
mailing list