Skip to content

[MLIR][Doc] Remove LLVM dialect typed pointer documentation #71246

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 17 additions & 39 deletions mlir/docs/Dialects/LLVM.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ style for types with nested angle brackets and keyword specifiers rather than
using different bracket styles to differentiate 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.
keyword. For example, `!llvm.struct<(!llvm.ptr, f32)>` and
`!llvm.struct<(ptr, f32)>` are equivalent, with the latter being the canonical
form, and denote a struct containing a pointer and a float.

### Built-in Type Compatibility

Expand All @@ -232,8 +232,8 @@ compatibility check.

Each LLVM IR type corresponds to *exactly one* MLIR type, either built-in or
LLVM dialect type. For example, because `i32` is LLVM-compatible, there is no
`!llvm.i32` type. However, `!llvm.ptr<T>` is defined in the LLVM dialect as
there is no corresponding built-in type.
`!llvm.i32` type. However, `!llvm.struct<(T, ...)>` is defined in the LLVM
dialect as there is no corresponding built-in type.

### Additional Simple Types

Expand Down Expand Up @@ -263,24 +263,19 @@ the element type, which can be either compatible built-in or LLVM dialect types.

Pointer types specify an address in memory.

Both opaque and type-parameterized pointer types are supported.
[Opaque pointers](https://llvm.org/docs/OpaquePointers.html) do not indicate the
type of the data pointed to, and are intended to simplify LLVM IR by encoding
behavior relevant to the pointee type into operations rather than into types.
Non-opaque pointer types carry the pointee type as a type parameter. Both kinds
of pointers may be additionally parameterized by an address space. The address
space is an integer, but this choice may be reconsidered if MLIR implements
named address spaces. The syntax of pointer types is as follows:
Pointers are [opaque](https://llvm.org/docs/OpaquePointers.html), i.e., do not
indicate the type of the data pointed to, and are intended to simplify LLVM IR
by encoding behavior relevant to the pointee type into operations rather than
into types. Pointers can optionally be parametrized with an address space. The
address space is an integer, but this choice may be reconsidered if MLIR
implements named address spaces. The syntax of pointer types is as follows:

```
llvm-ptr-type ::= `!llvm.ptr` (`<` integer-literal `>`)?
| `!llvm.ptr<` type (`,` integer-literal)? `>`
```

where the former case is the opaque pointer type and the latter case is the
non-opaque pointer type; the optional group containing the integer literal
corresponds to the memory space. All cases are represented by `LLVMPointerType`
internally.
where the optional group containing the integer literal corresponds to the
address space. All cases are represented by `LLVMPointerType` internally.

#### Array Types

Expand Down Expand Up @@ -346,7 +341,7 @@ syntax:

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 `!llvm.ptr` 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
Expand All @@ -367,12 +362,11 @@ compatible with the LLVM dialect:

```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<42 x ptr> // Vector of 42 pointers.
!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.
!llvm.array<2 x vec<2 x ptr>> // Array of 2 vectors of 2 pointers.
```

### Structure Types
Expand Down Expand Up @@ -421,21 +415,6 @@ 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
transitively contained in the same struct. In the latter case, only the
identifier is printed. For example, the structure containing the pointer to
itself is represented as `!llvm.struct<"A", (ptr<"A">)>`, and the structure `A`
containing two pointers to the structure `B` containing a pointer to the
structure `A` is represented as `!llvm.struct<"A", (ptr<"B", (ptr<"A">)>,
ptr<"B", (ptr<"A">))>`. Note that the structure `B` is "unrolled" for both
elements. _A structure with the same name but different body is a syntax error._
**The user must ensure structure name uniqueness across all modules processed in
a given MLIR context.** Structure names are arbitrary string literals and may
include, e.g., spaces and keywords.

Identified structs may be _opaque_. In this case, the body is unknown but the
structure type is considered _initialized_ and is valid in the IR.

#### Literal Structure Types

Literal structures are uniqued according to the list of elements they contain,
Expand All @@ -460,11 +439,10 @@ elements provided.
!llvm.struct<packed (i8, i32)> // packed struct
!llvm.struct<"a"> // recursive reference, only allowed within
// another struct, NOT allowed at top level
!llvm.struct<"a", ptr<struct<"a">>> // supported example of recursive reference
!llvm.struct<"a", ()> // empty, named (necessary to differentiate from
// recursive reference)
!llvm.struct<"a", opaque> // opaque, named
!llvm.struct<"a", (i32)> // named
!llvm.struct<"a", (i32, ptr)> // named
!llvm.struct<"a", packed (i8, i32)> // named, packed
```

Expand Down
18 changes: 9 additions & 9 deletions mlir/docs/SPIRVToLLVMDialectConversion.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ A SPIR-V pointer also takes a Storage Class. At the moment, conversion does

SPIR-V Dialect | LLVM Dialect
:-------------------------------------------: | :-------------------------:
`!spirv.ptr< <element-type>, <storage-class> >` | `!llvm.ptr<<element-type>>`
`!spirv.ptr< <element-type>, <storage-class> >` | `!llvm.ptr`

### Array types

Expand Down Expand Up @@ -443,7 +443,7 @@ order to go through the pointer.
%i = ...
%var = ...
%0 = llvm.mlir.constant(0 : i32) : i32
%el = llvm.getelementptr %var[%0, %i, %i] : (!llvm.ptr<struct<packed (f32, array<4 x f32>)>>, i32, i32, i32)
%el = llvm.getelementptr %var[%0, %i, %i] : (!llvm.ptr, i32, i32, i32), !llvm.struct<packed (f32, array<4 x f32>)>
```

#### `spirv.Load` and `spirv.Store`
Expand All @@ -453,16 +453,16 @@ These ops are converted to their LLVM counterparts: `llvm.load` and
following cases, based on the value of the attribute:

* **Aligned**: alignment is passed on to LLVM op builder, for example: `mlir
// llvm.store %ptr, %val {alignment = 4 : i64} : !llvm.ptr<f32> spirv.Store
// llvm.store %ptr, %val {alignment = 4 : i64} : !llvm.ptr spirv.Store
"Function" %ptr, %val ["Aligned", 4] : f32`
* **None**: same case as if there is no memory access attribute.

* **Nontemporal**: set `nontemporal` flag, for example: `mlir // %res =
llvm.load %ptr {nontemporal} : !llvm.ptr<f32> %res = spirv.Load "Function"
llvm.load %ptr {nontemporal} : !llvm.ptr %res = spirv.Load "Function"
%ptr ["Nontemporal"] : f32`

* **Volatile**: mark the op as `volatile`, for example: `mlir // %res =
llvm.load volatile %ptr : !llvm.ptr<f32> %res = spirv.Load "Function" %ptr
llvm.load volatile %ptr : !llvm.ptr f32> %res = spirv.Load "Function" %ptr
["Volatile"] : f32` Otherwise the conversion fails as other cases
(`MakePointerAvailable`, `MakePointerVisible`, `NonPrivatePointer`) are not
supported yet.
Expand Down Expand Up @@ -491,7 +491,7 @@ spirv.module Logical GLSL450 {
module {
llvm.mlir.global private @struct() : !llvm.struct<packed (f32, [10 x f32])>
llvm.func @func() {
%0 = llvm.mlir.addressof @struct : !llvm.ptr<struct<packed (f32, [10 x f32])>>
%0 = llvm.mlir.addressof @struct : !llvm.ptr
llvm.return
}
}
Expand Down Expand Up @@ -535,13 +535,13 @@ Also, at the moment initialization is only possible via `spirv.Constant`.
```mlir
// Conversion of VariableOp without initialization
%size = llvm.mlir.constant(1 : i32) : i32
%res = spirv.Variable : !spirv.ptr<vector<3xf32>, Function> => %res = llvm.alloca %size x vector<3xf32> : (i32) -> !llvm.ptr<vec<3 x f32>>
%res = spirv.Variable : !spirv.ptr<vector<3xf32>, Function> => %res = llvm.alloca %size x vector<3xf32> : (i32) -> !llvm.ptr

// Conversion of VariableOp with initialization
%c = llvm.mlir.constant(0 : i64) : i64
%c = spirv.Constant 0 : i64 %size = llvm.mlir.constant(1 : i32) : i32
%res = spirv.Variable init(%c) : !spirv.ptr<i64, Function> => %res = llvm.alloca %[[SIZE]] x i64 : (i32) -> !llvm.ptr<i64>
llvm.store %c, %res : !llvm.ptr<i64>
%res = spirv.Variable init(%c) : !spirv.ptr<i64, Function> => %res = llvm.alloca %[[SIZE]] x i64 : (i32) -> !llvm.ptr
llvm.store %c, %res : i64, !llvm.ptr
```

Note that simple conversion to `alloca` may not be sufficient if the code has
Expand Down
Loading