We would like to add an omp.structured_region
operation to openmp dialect in MLIR. This represents any block of code within an OpenMP construct. The intended us of this operation is that within an OpenMP operation’s region, there would be a single omp.structured_region
operation and a terminator operation as shown below.
// Example with `omp.sections`
omp.sections {
omp.structured_region {
call @foo : () -> ()
}
omp.terminator
}
Motivation
This operation is especially more useful in operations that use omp.yield
as a terminator. For example, in the proposed canonical loop operation, this operation would help fix the arguments of the yield operation and it is not affected by branches in the region assosciated with the canonical loop. In cases where the yielded value has to be a compile time constant, this provides a mechanism to avoid complex static analysis for the constant value.
With the current implementation, we cannot put the SingleBlockImplicitTerminator
trait on the canonical loop operation below, because that would conflict with conditionals and loops in LLVM IR Dialect. Having an omp.structured_region
allows us to put those branches within the region to have a complie time constant yield.
omp.target {
%outer,%inner = omp.canonical_loop %iv1 : i32 in [0, %tripcount) {
omp.structured_region {
%inner = omp.canonical_loop %iv2 : i32 in [0, %tc) {
omp.structured_region {
%a = load %arrA[%iv1, %iv2] : memref<?x?xf32>
store %a, %arrB[%iv1, %iv2] : memref<?x?xf32>
}
omp.yield
}
}
omp.yield(%inner : !omp.cli)
}
%collapsed_loopinfo = omp.collapse(%outer, %inner)
omp.teams {
call @foo() : () -> ()
omp.distribute(%collapsed_loopinfo)
}
}