[Mlir-commits] [mlir] [MLIR][OpenMP] Add omp.loop_nest operation (PR #87083)
Sergio Afonso
llvmlistbot at llvm.org
Wed Apr 10 07:02:35 PDT 2024
skatrak wrote:
> > > What is the mechanism we now have to avoid code appearing between loop_nest and the wrapper operation?
> >
> >
> > The `LoopWrapperInterface` (in the follow-up PR: #87232) defines an `isWrapper()` method that checks that the operation region only contains a single block with a single wrapper or `omp.loop_nest` and a terminator. Then, the wrapper op's verifier can be updated to make sure this is the case (e.g. [#87239](https://github.com/llvm/llvm-project/pull/87239/files#diff-a897370ad8f5ad37e8c1adb3c145c2304aaa38da3227bc1d02ac701ee8dc0754), [#87253](https://github.com/llvm/llvm-project/pull/87253/files#diff-a897370ad8f5ad37e8c1adb3c145c2304aaa38da3227bc1d02ac701ee8dc0754), [#87365](https://github.com/llvm/llvm-project/pull/87365/files#diff-a897370ad8f5ad37e8c1adb3c145c2304aaa38da3227bc1d02ac701ee8dc0754)).
>
> Would the code motion passes still end up moving the operation and then subsequently the verifier errors out? Have you tried out a code sinking or hoisting pass to see what is the behaviour?
I'm currently working on making `omp.wsloop` a wrapper, so I was able to make a small test to check this. I've noticed that CSE works as expected and doesn't try to insert anything inside of the wrapper, and the inlining pass seems to skip trying to inline anything inside of the loop nest region. Maybe you can suggest better ways to test this, but this is what I've tried so far:
```mlir
// cat test.mlir
func.func private @bar(i32) -> ()
func.func @foo(%arg0 : i32) -> () {
func.call @bar(%arg0) : (i32) -> ()
return
}
func.func @test_cse(%x : i32) -> () {
%c1_0 = arith.constant 1 : i32
%x_plus_1_0 = arith.addi %x, %c1_0 : i32
func.call @foo(%x_plus_1_0) : (i32) -> ()
%c2_0 = arith.constant 2 : i32
%x_plus_2_0 = arith.addi %x, %c2_0 : i32
omp.wsloop {
omp.loop_nest (%i) : i32 = (%x) to (%x_plus_2_0) step (%c1_0) {
%c2_1 = arith.constant 2 : i32
%x_plus_2_1 = arith.addi %x, %c2_1 : i32
func.call @foo(%x_plus_2_1) : (i32) -> ()
omp.yield
}
omp.terminator
}
return
}
// mlir-opt test.mlir -inline -cse -o -
func.func private @bar(i32)
func.func @foo(%arg0: i32) {
call @bar(%arg0) : (i32) -> ()
return
}
func.func @test_cse(%arg0: i32) {
%c2_i32 = arith.constant 2 : i32
%c1_i32 = arith.constant 1 : i32
%0 = arith.addi %arg0, %c1_i32 : i32
call @bar(%0) : (i32) -> ()
%1 = arith.addi %arg0, %c2_i32 : i32
omp.wsloop {
omp.loop_nest (%arg1) : i32 = (%arg0) to (%1) step (%c1_i32) {
func.call @foo(%1) : (i32) -> ()
omp.yield
}
omp.terminator
}
return
}
```
> For omp.wsloop where will collapse be represented? In the loop_nest operation?
Yes, so it will be possible to represent `collapse` for any loop construct, composite or otherwise (support would also need MLIR to LLVM IR translation implemented for that case). The way it's represented is the same as it's currently done for `omp.wsloop`, by having multiple IVs and range/step variables.
https://github.com/llvm/llvm-project/pull/87083
More information about the Mlir-commits
mailing list