Representing "main" with a `char**` argument at a level above the LLVM dialect

I ran into a problem of not being able to represent the equivalent of C int main(int argc, char **argv) or LLVM declare @main(i8, i8**) function signature in MLIR at any level above the LLVM dialect. The only pointer-like standard type is memref, which decomposes to {i8*, i8*, i64} for memref<i8> and an even bigger structure for memref<?xi8>.

I see two potential directions to supporting something like this (which also applies to other needs of interfacing with C, e.g., in string functions):

  • introduce a pointer type at ±standard level, and provide casting capabilities between memrefs and pointers;
  • repurpose memref<type> as pointer equivalent instead of the current allocated/aligned/offset we currently have; the handling of 0d memrefs is already a special case in most transformations because they don’t contain size and stride arrays, so it is not as big of a change.

In both cases, we can consider a limited form of pointers that only serve for interfacing with LLVM and C, and where MLIR code is not supposed to perform address calculations on these pointers, in order to maintain the fixed structure of address calculation we have thanks to memrefs.

cc @wsmoses

Can you describe more the use cases that this is intended to serve?

We don’t even have a “string” dialect, so I don’t understand what one would usefully do today in MLIR at any level above the LLVM dialect for processing the arguments to main.