as far as I understand, Memref stands for a piece of memory which can be heap memory or stack memory.
Is there register-level representation in MLIR or known reference work?
register-level might includes:
mov instruction
register allocate
…
if there is no reference work,
could you please suggest how to represents register allocate, op, type by MLIR?
thank you for reviewing this issue and share your insight.
In general, values of most first-class types such as vectors, integers, and floats can be seen as registers.
Overall it’s not recommended to deal with register semantics in SSA (that includes mlir and llvm ir), and it’s better to leave it to the backend to handle during the register allocation step.
To give you the next example, the MLIR Toy dialect defined a struct. The struct fields could be seen as registers and the struct could be seen as a register bank.
you are right, it should be role of backend.
my first idea is to make simular pipeline in backend to handle registers
bufferization for register
register allocation
others…
do you think it is reasonable?
compared RegisterBank struct, which one is more suitable?
could you please give me some advices?
def MovImmOp:
ins RegBank : dst, IntegerType: src
imagine there are 20 GPRs, how to know which register is used or how register allocation works based on this definition?
by the way, my first idea is to define single register type.
similar with memref dialect, alloca op is defined to manage registers
how do you think about this?
In general, registers can be modeled as memory. The specific modeling will be architecture- and task-specific. It can be one indexable “register file” type as suggested above, with indices potentially being more complex than just numbers (e.g., one can have rax/rsp/r42 instead of numbers for x86). It can also be one type per specific register, especially when some operations/instructions can only work with very specific registers. And anything in between.
It is a good idea to introduce an interface for such types, something similar to what is defined in MemorySlotInterfaces.td.
I generally wouldn’t expect these operations to operate on SSA values, except maybe for immediates that may be modeled as constants. So a load from memory would look something like lowlevel_asm.load_vector : (!lowlevel_asm.rax) -> !lowlevel_asm.zmm where %rax contains the memory address and %zmm will contain the loaded values.