I recently benchmarked adding:
- An optional type to
ptr, e.g.ptr<f32, 0>. - Extra verification code checking that the element type matched the type in the op.
- The
isOpaquemethod to theMemorySpaceAttrInterfacefor determining whether the memory space supports non opaque pointers. - A verifier to
!ptrenforcing theisOpaquemethod.
Note that 3. and 4. are necessary for maintaining LLVM semantics, for example:
// Emits an error.
ptr<f32, #llvm.address_space<#attr>>
I ran the same set of benchmarks from my last benchmarking comment and adding the above changes adds between 1.03x to 1.06x overhead wrt pre splitting the dialect.
Adding a getType method to MemorySpaceAttrInterface is another option, however, we would need to modify all other relevant address space attributes (like gpu) to potentially store the type, which at first glance seems overly complicated.
Other targets can benefit from typed pointers, for example EmitC or SPIR-V. However, most use cases can be solved without having a typed pointer. For example, most operations coming from memref will have the required information to deduce the pointer element type. Functions can have arg attributes indicating the element type and so on.
However, there is 1 potential use case where I think it’s not so trivial to recuperate the element information: pointers inside other types. For example:
func.func @createMemrefOfPtr() -> memref<10 x ptr> {...}
Getting the element type from the return type of @createMemrefOfPtr requires a more specific annotation.
I think two critical question are:
- If we were to add an optional type in
ptrwouldspirv.ptrdisappear? - Is the
1.06xslowdown acceptable for the LLVM path?