[mlir][memref] Clean up load/store documentation (#130569)

Remove references to the Affine dialect. The documentation is outdated.
Separate `affine.load/store` ops have been added.

Also add documentation for `nontemporal`.
This commit is contained in:
Matthias Springer 2025-03-13 09:42:14 +01:00 committed by GitHub
parent cb28ec6ccc
commit 59fd2878fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1184,40 +1184,23 @@ def LoadOp : MemRef_Op<"load",
DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>]> {
let summary = "load operation";
let description = [{
The `load` op reads an element from a memref specified by an index list. The
output of load is a new value with the same type as the elements of the
memref. The arity of indices is the rank of the memref (i.e., if the memref
loaded from is of rank 3, then 3 indices are required for the load following
the memref identifier).
The `load` op reads an element from a memref at the specified indices.
In an `affine.if` or `affine.for` body, the indices of a load are restricted
to SSA values bound to surrounding loop induction variables,
[symbols](Affine.md/#dimensions-and-symbols), results of a
constant operations, or the result of an
`affine.apply` operation that can in turn take as arguments all of the
aforementioned SSA values or the recursively result of such an
`affine.apply` operation.
The number of indices must match the rank of the memref. The indices must
be in-bounds: `0 <= idx < dim_size`
The single result of `memref.load` is a value with the same type as the
element type of the memref.
A set `nontemporal` attribute indicates that this load is not expected to
be reused in the cache. For details, refer to the
[https://llvm.org/docs/LangRef.html#load-instruction](LLVM load instruction).
Example:
```mlir
%1 = affine.apply affine_map<(d0, d1) -> (3*d0)> (%i, %j)
%2 = affine.apply affine_map<(d0, d1) -> (d1+1)> (%i, %j)
%12 = memref.load %A[%1, %2] : memref<8x?xi32, #layout, memspace0>
// Example of an indirect load (treated as non-affine)
%3 = affine.apply affine_map<(d0) -> (2*d0 + 1)>(%12)
%13 = memref.load %A[%3, %2] : memref<4x?xi32, #layout, memspace0>
%0 = memref.load %A[%a, %b] : memref<8x?xi32, #layout, memspace0>
```
**Context:** The `load` and `store` operations are specifically crafted to
fully resolve a reference to an element of a memref, and (in affine
`affine.if` and `affine.for` operations) the compiler can follow use-def
chains (e.g. through [`affine.apply`](Affine.md/#affineapply-affineapplyop)
operations) to precisely analyze references at compile-time using polyhedral
techniques. This is possible because of the
[restrictions on dimensions and symbols](Affine.md/#restrictions-on-dimensions-and-symbols)
in these contexts.
}];
let arguments = (ins Arg<AnyMemRef, "the reference to load from",
@ -1817,32 +1800,20 @@ def MemRef_StoreOp : MemRef_Op<"store",
DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>]> {
let summary = "store operation";
let description = [{
Store a value to a memref location given by indices. The value stored should
have the same type as the elemental type of the memref. The number of
arguments provided within brackets need to match the rank of the memref.
The `store` op stores an element into a memref at the specified indices.
The number of indices must match the rank of the memref. The indices must
be in-bounds: `0 <= idx < dim_size`
In an affine context, the indices of a store are restricted to SSA values
bound to surrounding loop induction variables,
[symbols](Affine.md/#restrictions-on-dimensions-and-symbols), results of a
`constant` operation, or the result of an
[`affine.apply`](Affine.md/#affineapply-affineapplyop) operation that can in
turn take as arguments all of the aforementioned SSA values or the
recursively result of such an `affine.apply` operation.
A set `nontemporal` attribute indicates that this store is not expected to
be reused in the cache. For details, refer to the
[https://llvm.org/docs/LangRef.html#store-instruction](LLVM store instruction).
Example:
```mlir
memref.store %100, %A[%1, 1023] : memref<4x?xf32, #layout, memspace0>
memref.store %val, %A[%a, %b] : memref<8x?xi32, #layout, memspace0>
```
**Context:** The `load` and `store` operations are specifically crafted to
fully resolve a reference to an element of a memref, and (in polyhedral
`affine.if` and `affine.for` operations) the compiler can follow use-def
chains (e.g. through [`affine.apply`](Affine.md/#affineapply-affineapplyop)
operations) to precisely analyze references at compile-time using polyhedral
techniques. This is possible because of the
[restrictions on dimensions and symbols](Affine.md/#restrictions-on-dimensions-and-symbols)
in these contexts.
}];
let arguments = (ins AnyType:$value,