aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flang/include/flang/Lower/OpenACC.h6
-rw-r--r--flang/lib/Lower/OpenACC.cpp50
-rw-r--r--flang/test/Lower/OpenACC/acc-reduction.f9035
3 files changed, 66 insertions, 25 deletions
diff --git a/flang/include/flang/Lower/OpenACC.h b/flang/include/flang/Lower/OpenACC.h
index f9b4c1f..6424e6b 100644
--- a/flang/include/flang/Lower/OpenACC.h
+++ b/flang/include/flang/Lower/OpenACC.h
@@ -16,6 +16,8 @@
#include "mlir/Dialect/OpenACC/OpenACC.h"
namespace llvm {
+template <typename T, unsigned N>
+class SmallVector;
class StringRef;
}
@@ -23,6 +25,7 @@ namespace mlir {
class Location;
class Type;
class OpBuilder;
+class Value;
} // namespace mlir
namespace fir {
@@ -64,7 +67,8 @@ mlir::acc::PrivateRecipeOp createOrGetPrivateRecipe(mlir::OpBuilder &,
/// exist yet.
mlir::acc::ReductionRecipeOp
createOrGetReductionRecipe(fir::FirOpBuilder &, llvm::StringRef, mlir::Location,
- mlir::Type, mlir::acc::ReductionOperator);
+ mlir::Type, mlir::acc::ReductionOperator,
+ llvm::SmallVector<mlir::Value> &);
/// Get a acc.firstprivate.recipe op for the given type or create it if it does
/// not exist yet.
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index f94c1de..e1332f1 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -680,9 +680,24 @@ static R getReductionInitValue(mlir::acc::ReductionOperator op, mlir::Type ty) {
llvm_unreachable("OpenACC reduction unsupported type");
}
-static mlir::Value genReductionInitValue(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Type ty,
- mlir::acc::ReductionOperator op) {
+/// Determine if the bounds represent a dynamic shape.
+bool hasDynamicShape(llvm::SmallVector<mlir::Value> &bounds) {
+ if (bounds.empty())
+ return false;
+ for (auto b : bounds) {
+ auto op = mlir::dyn_cast<mlir::acc::DataBoundsOp>(b.getDefiningOp());
+ if (((op.getLowerbound() && !fir::getIntIfConstant(op.getLowerbound())) ||
+ (op.getUpperbound() && !fir::getIntIfConstant(op.getUpperbound()))) &&
+ op.getExtent() && !fir::getIntIfConstant(op.getExtent()))
+ return true;
+ }
+ return false;
+}
+
+static mlir::Value
+genReductionInitValue(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Type ty, mlir::acc::ReductionOperator op,
+ llvm::SmallVector<mlir::Value> &bounds) {
if (op == mlir::acc::ReductionOperator::AccLand ||
op == mlir::acc::ReductionOperator::AccLor ||
op == mlir::acc::ReductionOperator::AccEqv ||
@@ -861,7 +876,8 @@ static mlir::Value genCombiner(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::acc::ReductionRecipeOp Fortran::lower::createOrGetReductionRecipe(
fir::FirOpBuilder &builder, llvm::StringRef recipeName, mlir::Location loc,
- mlir::Type ty, mlir::acc::ReductionOperator op) {
+ mlir::Type ty, mlir::acc::ReductionOperator op,
+ llvm::SmallVector<mlir::Value> &bounds) {
mlir::ModuleOp mod =
builder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>();
if (auto recipe = mod.lookupSymbol<mlir::acc::ReductionRecipeOp>(recipeName))
@@ -874,7 +890,7 @@ mlir::acc::ReductionRecipeOp Fortran::lower::createOrGetReductionRecipe(
builder.createBlock(&recipe.getInitRegion(), recipe.getInitRegion().end(),
{ty}, {loc});
builder.setInsertionPointToEnd(&recipe.getInitRegion().back());
- mlir::Value initValue = genReductionInitValue(builder, loc, ty, op);
+ mlir::Value initValue = genReductionInitValue(builder, loc, ty, op, bounds);
builder.create<mlir::acc::YieldOp>(loc, initValue);
builder.createBlock(&recipe.getCombinerRegion(),
@@ -888,20 +904,6 @@ mlir::acc::ReductionRecipeOp Fortran::lower::createOrGetReductionRecipe(
return recipe;
}
-/// Determine if the bounds represent a dynamic shape.
-bool hasDynamicShape(llvm::SmallVector<mlir::Value> &bounds) {
- if (bounds.empty())
- return false;
- for (auto b : bounds) {
- auto op = mlir::dyn_cast<mlir::acc::DataBoundsOp>(b.getDefiningOp());
- if (((op.getLowerbound() && !fir::getIntIfConstant(op.getLowerbound())) ||
- (op.getUpperbound() && !fir::getIntIfConstant(op.getUpperbound()))) &&
- op.getExtent() && !fir::getIntIfConstant(op.getExtent()))
- return true;
- }
- return false;
-}
-
static void
genReductions(const Fortran::parser::AccObjectListWithReduction &objectList,
Fortran::lower::AbstractConverter &converter,
@@ -935,19 +937,19 @@ genReductions(const Fortran::parser::AccObjectListWithReduction &objectList,
!bounds.empty()))
TODO(operandLocation, "reduction with unsupported type");
+ mlir::Type retTy = getTypeFromBounds(bounds, baseAddr.getType());
auto op = createDataEntryOp<mlir::acc::ReductionOp>(
builder, operandLocation, baseAddr, asFortran, bounds,
- /*structured=*/true, mlir::acc::DataClause::acc_reduction,
- baseAddr.getType());
+ /*structured=*/true, mlir::acc::DataClause::acc_reduction, retTy);
mlir::Type ty = fir::unwrapRefType(op.getAccPtr().getType());
if (!fir::isa_trivial(ty))
- ty = baseAddr.getType();
+ ty = retTy;
std::string recipeName = fir::getTypeAsString(
ty, converter.getKindMap(),
("reduction_" + stringifyReductionOperator(mlirOp)).str());
mlir::acc::ReductionRecipeOp recipe =
- Fortran::lower::createOrGetReductionRecipe(builder, recipeName,
- operandLocation, ty, mlirOp);
+ Fortran::lower::createOrGetReductionRecipe(
+ builder, recipeName, operandLocation, ty, mlirOp, bounds);
reductionRecipes.push_back(mlir::SymbolRefAttr::get(
builder.getContext(), recipe.getSymName().str()));
reductionOperands.push_back(op.getAccPtr());
diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90
index b84d2fa..ae900c0 100644
--- a/flang/test/Lower/OpenACC/acc-reduction.f90
+++ b/flang/test/Lower/OpenACC/acc-reduction.f90
@@ -2,6 +2,26 @@
! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s
+! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_10xi32 : !fir.ref<!fir.array<10xi32>> reduction_operator <add> init {
+! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10xi32>>):
+! CHECK: %[[CST:.*]] = arith.constant dense<0> : vector<10xi32>
+! CHECK: acc.yield %[[CST]] : vector<10xi32>
+! CHECK: } combiner {
+! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<10xi32>>, %[[ARG1:.*]]: !fir.ref<!fir.array<10xi32>>):
+! CHECK: %[[LB:.*]] = arith.constant 0 : index
+! CHECK: %[[UB:.*]] = arith.constant 9 : index
+! CHECK: %[[STEP:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[IV:.*]] = %[[LB]] to %[[UB]] step %[[STEP]] {
+! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[ARG0]], %[[IV]] : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[COORD2:.*]] = fir.coordinate_of %[[ARG1]], %[[IV]] : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[LOAD1:.*]] = fir.load %[[COORD1]] : !fir.ref<i32>
+! CHECK: %[[LOAD2:.*]] = fir.load %[[COORD2]] : !fir.ref<i32>
+! CHECK: %[[COMBINED:.*]] = arith.addi %[[LOAD1]], %[[LOAD2]] : i32
+! CHECK: fir.store %[[COMBINED]] to %[[COORD1]] : !fir.ref<i32>
+! CHECK: }
+! CHECK: acc.yield %[[ARG0]] : !fir.ref<!fir.array<10xi32>>
+! CHECK: }
+
! CHECK-LABEL: acc.reduction.recipe @reduction_mul_z32 : !fir.complex<4> reduction_operator <mul> init {
! CHECK: ^bb0(%{{.*}}: !fir.complex<4>):
! CHECK: %[[REAL:.*]] = arith.constant 1.000000e+00 : f32
@@ -804,3 +824,18 @@ end subroutine
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
! CHECK: %[[RED:.*]] = acc.reduction varPtr(%[[BOX_ADDR]] : !fir.ptr<i32>) -> !fir.ptr<i32> {name = "i"}
! CHECK: acc.parallel reduction(@reduction_add_i32 -> %[[RED]] : !fir.ptr<i32>)
+
+subroutine acc_reduction_add_static_slice(a)
+ integer :: a(100)
+ !$acc parallel reduction(+:a(11:20))
+ !$acc end parallel
+end subroutine
+
+! CHECK-LABEL: func.func @_QPacc_reduction_add_static_slice(
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "a"})
+! CHECK: %[[C1:.*]] = arith.constant 1 : index
+! CHECK: %[[LB:.*]] = arith.constant 10 : index
+! CHECK: %[[UB:.*]] = arith.constant 19 : index
+! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index)
+! CHECK: %[[RED:.*]] = acc.reduction varPtr(%[[ARG0]] : !fir.ref<!fir.array<100xi32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<10xi32>> {name = "a(11:20)"}
+! CHECK: acc.parallel reduction(@reduction_add_ref_10xi32 -> %[[RED]] : !fir.ref<!fir.array<10xi32>>)