NexMing wrote:

> Can you provide an example of such mem2reg you would like to see happening? I 
> agree something needs to be done around fir.declare to allow mem2reg. I think 
> we should be able to implement the PromotableOpInterface for it so that at 
> least scalar case mem2reg would be possible, so I am interested to see if 
> that would cover the cases you are interested in.

Here is a simple example.
```
  func.func @_QPfoo(%arg0: !fir.ref<i32> {fir.bindc_name = "a"}) {
    %c0_i32 = arith.constant 0 : i32
    %0 = fir.dummy_scope : !fir.dscope
    %1 = fir.declare %arg0 dummy_scope %0 arg 1 {fortran_attrs = 
#fir.var_attrs<intent_inout>, uniq_name = "_QFfooEa"} : (!fir.ref<i32>, 
!fir.dscope) -> !fir.ref<i32>
    %2 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFfooEi"}
    %3 = fir.declare %2 {uniq_name = "_QFfooEi"} : (!fir.ref<i32>) -> 
!fir.ref<i32>
    fir.store %c0_i32 to %3 : !fir.ref<i32>
    %4 = fir.load %3 : !fir.ref<i32>
    fir.store %4 to %1 : !fir.ref<i32>
    return
  }
```
When it is lowered to the MLIR standard dialects, it becomes the following:
```
  func.func @_QPfoo(%arg0: !fir.ref<i32> {fir.bindc_name = "a"}) {
    %c0_i32 = arith.constant 0 : i32
    %0 = fir.dummy_scope : !fir.dscope
    %1 = fir.declare %arg0 dummy_scope %0 arg 1 {fortran_attrs = 
#fir.var_attrs<intent_inout>, uniq_name = "_QFfooEa"} : (!fir.ref<i32>, 
!fir.dscope) -> !fir.ref<i32>
    %2 = builtin.unrealized_conversion_cast %1 : !fir.ref<i32> to memref<i32, 
strided<[], offset: ?>>
    %alloca = memref.alloca() {bindc_name = "i", in_type = i32, uniq_name = 
"_QFfooEi"} : memref<i32>
    %cast = memref.cast %alloca : memref<i32> to memref<i32, strided<[], 
offset: ?>>
    %3 = builtin.unrealized_conversion_cast %cast : memref<i32, strided<[], 
offset: ?>> to !fir.ref<i32>
    %4 = fir.declare %3 {uniq_name = "_QFfooEi"} : (!fir.ref<i32>) -> 
!fir.ref<i32>
    %5 = builtin.unrealized_conversion_cast %4 : !fir.ref<i32> to memref<i32, 
strided<[], offset: ?>>
    memref.store %c0_i32, %5[] : memref<i32, strided<[], offset: ?>>
    %6 = memref.load %5[] : memref<i32, strided<[], offset: ?>>
    memref.store %6, %2[] : memref<i32, strided<[], offset: ?>>
    return
  }
```
I want the `memref.alloca` here to be eliminated, but the presence of 
`fir.declare` prevents the `mem2reg` optimization.
As you said, we can try implementing `PromotableOpInterface` to see whether it 
can resolve this issue.

Additionally, the `fir-memref-dataflow-opt` pass can also optimize it, but I’ve 
found that this pass is not robust enough (I encountered bugs in my tests), and 
I prefer extending or implementing this in the MLIR standard dialects—it’s more 
general.

https://github.com/llvm/llvm-project/pull/168703
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to