Fair enough!
I’m trying to enable OpenACC conversions in Flang. I believe that the problem is tightly related to MLIR and/or can be solved with it.
A little bit of a background
OpenACC lowering to LLVM IR in MLIR is done in 2 phases:
OpenACCToLLVMConversion - as far as I understand, it converts a memref type in the operands to LLVM pointers. Actual operation conversions expect only memref or llvm pointer arguments: https://github.com/llvm/llvm-project/blob/main/mlir/lib/Conversion/OpenACCToLLVM/OpenACCToLLVM.cpp#L106-L135
OpenACCDialectLLVMIRTranslationInterface - converts actual operations to runtime call directly in LLVM IR
OpenMP lowering done in a similar way and it is already enabled in Flang, so I just try to mimic it here: WIP · unterumarmung/llvm-project@8e6249d · GitHub
And it seems that it should work fine, but the problem occurs when we actually try to convert an OpenACC operation.
I use this Fortran program as an example because OpenACC’s enter data lowering to LLVM IR should be fully supported in MLIR.
subroutine foo
integer :: a
a = 42
!$acc enter data copyin(a)
end subroutine foo
Which has the following FIR (build/bin/flang-new -fc1 -fopenacc -emit-mlir c.f90) before any conversion to LLVM IR whatsoever:
module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
func.func @_QPfoo() {
%0 = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFfooEa"}
%c42_i32 = arith.constant 42 : i32
fir.store %c42_i32 to %0 : !fir.ref<i32>
acc.enter_data copyin(%0 : !fir.ref<i32>)
return
}
}
As you can see, copyin in acc.enter_data accepts !fir.ref type which should be eliminated before we run OpenACCToLLVMConversion. This is should be done by AllocaOpConversion (basically converts fir.alloca to llvm.alloca) which is registered here: llvm-project/flang/lib/Optimizer/CodeGen/CodeGen.cpp at flang-openacc · unterumarmung/llvm-project · GitHub
Finally, when we try to run OpenACC conversion: llvm-project/mlir/lib/Conversion/OpenACCToLLVM/OpenACCToLLVM.cpp at flang-openacc · unterumarmung/llvm-project · GitHub
In the output I get this:
"llvm.func"() ({
%0 = "llvm.mlir.constant"() {value = 42 : i32} : () -> i32
%1 = "arith.constant"() {value = 42 : i32} : () -> i32
%2 = "llvm.mlir.constant"() {value = 1 : i64} : () -> i64
%3 = "llvm.alloca"(%2) {bindc_name = "a", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFfooEa"} : (i64) -> !llvm.ptr<i32>
%4 = "fir.alloca"() {bindc_name = "a", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFfooEa"} : () -> !fir.ref<i32>
"llvm.store"(%0, %3) : (i32, !llvm.ptr<i32>) -> ()
"fir.store"(%1, %4) : (i32, !fir.ref<i32>) -> ()
"acc.enter_data"(%4) {operand_segment_sizes = array<i32: 0, 0, 0, 0, 1, 0, 0, 0>} : (!fir.ref<i32>) -> ()
"func.return"() : () -> ()
}) {CConv = #llvm.cconv<ccc>, function_type = !llvm.func<void ()>, linkage = #llvm.linkage<external>, sym_name = "foo_"} : () -> ()
Which is weird - LLVM and FIR operations duplicated and acc.enter_data still accepts !fir.ref
Also, earlier I was getting <<<UNKNOWN SSA VALUE>>> in the last !fir.store and acc.enter_data.
What do you think the problem is? Is this MLIR-related or I accidentally violated some Flang-specific stuff?
I was thinking if tried to schedule the OpenACC conversions as later as possible the problem would be solved or, at least, become more clear. And, AFAIK, OpenACC conversions should be run as later as possible.
P. S. I’m sorry if something in my message is not clear - I’m very confused and tired..