[mlir][openacc] Add reduction representation
Similarly to D150622 for private clause, the reduction is currently not
modeled in a good way. This patch is inspired by the reduction representation
in the omp dialect (D105358) and make a new representation for the reduction in
the OpenACC dialect.
A new operation is introduced to model the sequences of operation needed to
initialize a local reduction value and how to combine two values during the
reduction. The operation requires two mandatory regions.
1. The init region specifies how to initialize the local reduction
value. The region has an argument that contains the value of the
reduction accumulator at the start of the reduction. It is expected to
`acc.yield` the new value.
2. The reduction region contains a sequences of operations to combine two
values of the reduction type into one. It has two arguments and it is
expected to `acc.yield` the combined value.
Example:
```mlir
acc.reduction.recipe @reduction_add_i64 : i64 init reduction_operator<add> {
^bb0(%0: i64):
// init region contains a sequence of operations to initialize the local
// reduction value as specified in 2.5.15
%c0 = arith.constant 0 : i64
acc.yield %c0 : i64
} reduction {
^bb0(%0: i64, %1: i64)
// reduction region contains a sequence of operations to combine
// two values into one.
%2 = arith.addi %0, %1 : i64
acc.yield %2 : i64
}
// The reduction symbol is then used in the corresponding operation.
acc.parallel reduction(@reduction_add_i64 -> %a : i64) {
}
Reviewed By: razvanlupusoru, vzakhari
Differential Revision: https://reviews.llvm.org/D150818