llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.05k stars 11.98k forks source link

[Flang][MLIR]question about affine optimization for Fortran program when using flang #58646

Open qelk123 opened 2 years ago

qelk123 commented 2 years ago

Hi all, I am trying to flang-affine-promotion pass to convert parts of my fir code to affine dialect.However,it failed when converting fir.do_loop because of error in fetching loop analysis in AffineFunctionAnalysis.I only saw a case using fir in the repo.Are here any cases writing in fortran that I can refer to? Thanks

llvmbot commented 2 years ago

@llvm/issue-subscribers-mlir-affine

kiranchandramohan commented 2 years ago

I think the affine dialect conversion in flang has not been maintained. To get it to work you might need a sequence of passes to run before affine conversion. The fir-dev branch of f18-llvm-project has an example https://github.com/flang-compiler/f18-llvm-project/blob/fir-dev/flang/test/Fir/arr-end-end.f90. Not sure whether all the passes that are required are present in llvm/flang and whether that example will work in llvm/flang.

A two year old presentation by the engineer who worked on this topic is available at https://slides.com/rajanwalia/deck.

qelk123 commented 2 years ago

I think the affine dialect conversion in flang has not been maintained. To get it to work you might need a sequence of passes to run before affine conversion. The fir-dev branch of f18-llvm-project has an example https://github.com/flang-compiler/f18-llvm-project/blob/fir-dev/flang/test/Fir/arr-end-end.f90. Not sure whether all the passes that are required are present in llvm/flang and whether that example will work in llvm/flang.

A two year old presentation by the engineer who worked on this topic is available at https://slides.com/rajanwalia/deck.

Unfortunately,some passes are missing in the llvm/flang when I want to reprodece the case.logs as follow:

tco: Unknown command line argument '--fir-loop-result-opt'.  Try: 'tco --help'
tco: Did you mean '--affine-loop-unroll'?
tco: Unknown command line argument '--simplify-affine-structures'.  Try: 'tco --help'
tco: Did you mean '--simplify-intrinsics'?
tco: Unknown command line argument '--memref-dataflow-opt'.  Try: 'tco --help'
tco: Did you mean '--fir-memref-dataflow-opt'?

when I simply delete these passes, I still can't promote fir due to the error: AffineLoopAnalysis: array coordinate is not a loop induction variable (not a block argument)

  %3:2 = fir.do_loop %arg1 = %c1 to %c60 step %c1 iter_args(%arg2 = %2) -> (index, i32) {
    %4 = fir.convert %arg2 : (i32) -> index
    %5 = fir.shape %c60 : (index) -> !fir.shape<1>
    %6 = fir.array_coor %arg0(%5) %4 : (!fir.ref<!fir.array<60xi32>>, !fir.shape<1>, index) -> !fir.ref<i32>
...

and after manually modify the fir code,I find the reason why the promotion failed is fir.array_coor use the index of %4 instead of %arg1.So I suspect it's because I didn't use --fir-loop-result-opt to eliminate the return value of the do_loop op.Is there any pass can substitute the original --fir-loop-result-opt and achieve the same modification?

kiranchandramohan commented 2 years ago

I don't think there is a substitute for fir-loop-result-opt. If you are interested and have relevant experience, you can try to upstream that pass from fir-dev of f18-llvm-project with suitable modifications.

qelk123 commented 2 years ago

I don't think there is a substitute for fir-loop-result-opt. If you are interested and have relevant experience, you can try to upstream that pass from fir-dev of f18-llvm-project with suitable modifications.

Thank you,I'll have a try.And there is another question,can I suppose fir-dev of f18-llvm-project is better developed even though the last commit was on 22 Apr?

kiranchandramohan commented 2 years ago

No, llvm/flang is the most developed version. fir-dev of f18-llvm-project has not been maintained for a few months now. It might have a few things that we chose not to upstream due to various reasons.

qelk123 commented 2 years ago

No, llvm/flang is the most developed version. fir-dev of f18-llvm-project has not been maintained for a few months now. It might have a few things that we chose not to upstream due to various reasons.

OK,I get it.Just now I tried to upstream the pass to llvm/flang.However that pass failed because there is usage to the result of DoLoopOp,the generated fir code beforefir-loop-result-opt is like:

%5:2 = fir.do_loop %arg3 = %2 to %3 step %c1 iter_args(%arg4 = %4) -> (index, i32) {
    %6 = fir.convert %arg4 : (i32) -> i64
    %7 = fir.convert %6 : (i64) -> index
    %8 = fir.shape_shift %c0, %c5 : (index, index) -> !fir.shapeshift<1>
    %9 = fir.array_coor %arg0(%8) %7 : (!fir.ref<!fir.array<5xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
    %10 = fir.load %9 : !fir.ref<i32>
    %11 = fir.convert %arg4 : (i32) -> i64
    %12 = fir.convert %11 : (i64) -> index
    %13 = fir.shape_shift %c0, %c5 : (index, index) -> !fir.shapeshift<1>
    ...
  }

since %6 is converted from %arg4,%arg4 can't be simply removed.I also notice that in this slide [https://slides.com/rajanwalia/deck](),the original fir that directly generated from .f90 is like:

func @_QPf1dc(%arg0: !fir.ref<!fir.array<5xi32>>
   %arg1: !fir.ref<!fir.array<5xi32>>,
   %arg2: !fir.ref<!fir.array<5xi32>>) {
   %c0 = constant 0 : index
   %c1 = constant 1 : index
   %c4 = constant 4 : index
   %0 = fir.alloca i32 {name = "i"}
   %1 = fir.alloca !fir.array<5xi32> {name = "t1"}
   %4 = fir.do_loop %arg3 = %c0 to %c4 step %c1
   iter_args(%arg4 = %2) -> (index) {
   %10 = fir.convert %arg3 : (index) -> i32
   fir.store %10 to %0 : !fir.ref<i32>
   %11 = fir.load %0 : !fir.ref<i32>
   ...

%10 is converted from %arg3 instead of %arg4,and since %arg4 is not used here,it can be removed during the pass.So it here any pass should I add before fir-loop-result-opt,during the frontend lowering for example.

kiranchandramohan commented 2 years ago

There might have been some changes required so that loop optimizations in llvm work properly. Could you check whether https://reviews.llvm.org/D132176 introduced %arg4?

cathieO commented 1 year ago

@qelk123 did you find a solution for this? I have just started looking into affine transformations for fortran codes and it looks like this change enables some llvm loop optimizations and breaks mlir loop optimizations. Have you found a workaround?