This is a frequently requested feature. I’d like to extend memref to support arbitrary element types, and we now have sufficient infrastructure support to do so.
The extension can be implemented as follows. In addition to the types that are currently supported, memref can support element types that implement the newly added
MemRefElementTypeInterface, which provides functionality necessary for memref to reason about the type. Given the current use, this functionality provides the size and alignment requirements of the element type. The default implementation of the interface queries the
DataLayout interfaces to obtain size and alignment information. An interface separate from
DataLayoutTypeInterface allows types to explicitly opt into being supported as memref element types and enables independent evolution of the two interfaces.
Will this feature support something like memref of memref (e.g.
MemrefElementTypeInterface, yes, it’s not much different from other types.
This looks great to have. I recall this topic was discussed on another thread in more detail several months ago – as to what information we really expect from types that want to be memref element types. (You had a detailed post there but I don’t recall the thread title.)
As far as I understand, there is no way currently to have something memref-like or tensor-like for custom types, so I’d be highly interested in this extension, too. @ftynse Are you actively working on this? If yes, is there a repository with the current status?
This has been implemented.
Conversion to LLVM will also require the element type to implement DataLayoutTypeInterface if it needs to lower
memref.alloc with this element type.
@ftynse Is there any documentation or example on this extension? For example, a memref for a struct(
struct node* foo = ...; lowering to
memref<struct<...>>). I am translating the AST to MLIR and I want to be able to use memref as a pointer. It would be great if memref can be easily extend as a pointer.
btw, How can struct with different data layout be represented in MLIR?
Here’s the interface https://github.com/llvm/llvm-project/blob/8b76aea8d8b1b71f6220bc2845abc749f18a19b7/mlir/include/mlir/IR/BuiltinTypeInterfaces.td#L23 a type needs to implement. It’s essentially a promise by the type that it is something that is intended to be stored in memory.
That being said, I strongly believe that memref is not a pointer. It is too complex for cases where only a pointer is needed. If your use case needs a pointer, use a pointer type. The opaque pointer from the LLVM dialect can do the trick. Otherwise, introduce a type that is parameterized by another type and a memory space, and that will be a pointer. I think there may be room for a “typed pointer” dialect upstream, but that would need an RFC.
As for the struct, depending on the layout specification, it may be either possible to reuse the LLVM dialect struct type (in which the layout is decided by the data-layout properties of elements) or introduce a similar new type where the layout is specified by an attribute that parameterizes the type.
Opaque pointer from the LLVM dialect is indeed a better choice. May be I can lower high-level pointer type into
memref(for tensor) and llvm Opaque pointer(for other types, like
struct)? It does seem a bit odd to lower pointer types separately.