[flang-commits] [flang] 897e69d - [flang][openacc] Support array slices when creating private recipe
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Thu Jul 6 14:08:28 PDT 2023
Author: Valentin Clement
Date: 2023-07-06T14:08:18-07:00
New Revision: 897e69dd83dee3e41da6edc30354cc95d3042700
URL: https://github.com/llvm/llvm-project/commit/897e69dd83dee3e41da6edc30354cc95d3042700
DIFF: https://github.com/llvm/llvm-project/commit/897e69dd83dee3e41da6edc30354cc95d3042700.diff
LOG: [flang][openacc] Support array slices when creating private recipe
The return type of the recipe must match the array slice provided by
the user. This patch enhance the recipe creation to take into account
the constant slices.
Depends on D154259
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D154648
Added:
Modified:
flang/lib/Lower/OpenACC.cpp
flang/test/Lower/OpenACC/acc-private.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index f6cef04e8445e9..7354aa28d4ad2b 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -350,12 +350,15 @@ template <typename Op>
static Op createDataEntryOp(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value baseAddr, std::stringstream &name,
mlir::SmallVector<mlir::Value> bounds,
- bool structured, mlir::acc::DataClause dataClause) {
+ bool structured, mlir::acc::DataClause dataClause,
+ mlir::Type retTy) {
mlir::Value varPtrPtr;
- if (auto boxTy = baseAddr.getType().dyn_cast<fir::BaseBoxType>())
+ if (auto boxTy = baseAddr.getType().dyn_cast<fir::BaseBoxType>()) {
baseAddr = builder.create<fir::BoxAddrOp>(loc, baseAddr);
+ retTy = baseAddr.getType();
+ }
- Op op = builder.create<Op>(loc, baseAddr.getType(), baseAddr);
+ Op op = builder.create<Op>(loc, retTy, baseAddr);
op.setNameAttr(builder.getStringAttr(name.str()));
op.setStructured(structured);
op.setDataClause(dataClause);
@@ -388,7 +391,8 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList,
converter, builder, semanticsContext, stmtCtx, accObject,
operandLocation, asFortran, bounds);
Op op = createDataEntryOp<Op>(builder, operandLocation, baseAddr, asFortran,
- bounds, structured, dataClause);
+ bounds, structured, dataClause,
+ baseAddr.getType());
dataOperands.push_back(op.getAccPtr());
}
}
@@ -474,6 +478,41 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(
return recipe;
}
+/// Rebuild the array type from the acc.bounds operation with constant
+/// lowerbound/upperbound or extent.
+mlir::Type getTypeFromBounds(llvm::SmallVector<mlir::Value> &bounds,
+ mlir::Type ty) {
+ auto seqTy =
+ mlir::dyn_cast_or_null<fir::SequenceType>(fir::unwrapRefType(ty));
+ if (!bounds.empty() && seqTy) {
+ llvm::SmallVector<int64_t> shape;
+ for (auto b : bounds) {
+ auto boundsOp =
+ mlir::dyn_cast<mlir::acc::DataBoundsOp>(b.getDefiningOp());
+ if (boundsOp.getLowerbound() &&
+ fir::getIntIfConstant(boundsOp.getLowerbound()) &&
+ boundsOp.getUpperbound() &&
+ fir::getIntIfConstant(boundsOp.getUpperbound())) {
+ int64_t ext = *fir::getIntIfConstant(boundsOp.getUpperbound()) -
+ *fir::getIntIfConstant(boundsOp.getLowerbound()) + 1;
+ shape.push_back(ext);
+ } else if (boundsOp.getExtent() &&
+ fir::getIntIfConstant(boundsOp.getExtent())) {
+ shape.push_back(*fir::getIntIfConstant(boundsOp.getExtent()));
+ } else {
+ return ty; // TODO: handle dynamic shaped array slice.
+ }
+ }
+ if (shape.empty() || shape.size() != bounds.size())
+ return ty;
+ auto newSeqTy = fir::SequenceType::get(shape, seqTy.getEleTy());
+ if (mlir::isa<fir::ReferenceType>(ty))
+ return fir::ReferenceType::get(newSeqTy);
+ return newSeqTy;
+ }
+ return ty;
+}
+
template <typename RecipeOp>
static void
genPrivatizations(const Fortran::parser::AccObjectList &objectList,
@@ -493,13 +532,14 @@ genPrivatizations(const Fortran::parser::AccObjectList &objectList,
RecipeOp recipe;
if constexpr (std::is_same_v<RecipeOp, mlir::acc::PrivateRecipeOp>) {
- std::string recipeName = fir::getTypeAsString(
- baseAddr.getType(), converter.getKindMap(), "privatization");
- recipe = Fortran::lower::createOrGetPrivateRecipe(
- builder, recipeName, operandLocation, baseAddr.getType());
+ mlir::Type retTy = getTypeFromBounds(bounds, baseAddr.getType());
+ std::string recipeName =
+ fir::getTypeAsString(retTy, converter.getKindMap(), "privatization");
+ recipe = Fortran::lower::createOrGetPrivateRecipe(builder, recipeName,
+ operandLocation, retTy);
auto op = createDataEntryOp<mlir::acc::PrivateOp>(
builder, operandLocation, baseAddr, asFortran, bounds, true,
- mlir::acc::DataClause::acc_private);
+ mlir::acc::DataClause::acc_private, retTy);
dataOperands.push_back(op.getAccPtr());
} else {
std::string recipeName = fir::getTypeAsString(
@@ -508,7 +548,7 @@ genPrivatizations(const Fortran::parser::AccObjectList &objectList,
builder, recipeName, operandLocation, baseAddr.getType());
auto op = createDataEntryOp<mlir::acc::FirstprivateOp>(
builder, operandLocation, baseAddr, asFortran, bounds, true,
- mlir::acc::DataClause::acc_firstprivate);
+ mlir::acc::DataClause::acc_firstprivate, baseAddr.getType());
dataOperands.push_back(op.getAccPtr());
}
privatizations.push_back(mlir::SymbolRefAttr::get(
@@ -766,7 +806,8 @@ genReductions(const Fortran::parser::AccObjectListWithReduction &objectList,
auto op = createDataEntryOp<mlir::acc::ReductionOp>(
builder, operandLocation, baseAddr, asFortran, bounds,
- /*structured=*/true, mlir::acc::DataClause::acc_reduction);
+ /*structured=*/true, mlir::acc::DataClause::acc_reduction,
+ baseAddr.getType());
mlir::Type ty = fir::unwrapRefType(op.getAccPtr().getType());
if (!fir::isa_trivial(ty))
ty = baseAddr.getType();
diff --git a/flang/test/Lower/OpenACC/acc-private.f90 b/flang/test/Lower/OpenACC/acc-private.f90
index fc806a26c8562b..ecee86585522f5 100644
--- a/flang/test/Lower/OpenACC/acc-private.f90
+++ b/flang/test/Lower/OpenACC/acc-private.f90
@@ -2,6 +2,12 @@
! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s
+! CHECK-LABEL: acc.private.recipe @privatization_ref_50xf32 : !fir.ref<!fir.array<50xf32>> init {
+! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<50xf32>>):
+! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<50xf32>
+! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<!fir.array<50xf32>>
+! CHECK: }
+
! CHECK-LABEL: acc.private.recipe @privatization_ref_100xf32 : !fir.ref<!fir.array<100xf32>> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xf32>>):
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32>
@@ -44,5 +50,20 @@ program acc_private
! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index)
! CHECK: %[[B_PRIVATE:.*]] = acc.private varPtr(%[[B]] : !fir.ref<!fir.array<100xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<100xf32>> {name = "b"}
! CHECK: acc.loop private(@privatization_ref_100xf32 -> %[[B_PRIVATE]] : !fir.ref<!fir.array<100xf32>>) {
+! CHECK: acc.yield
+
+ !$acc loop private(b(1:50))
+ DO i = 1, n
+ c = i
+ a(i) = b(i) + c
+ END DO
+
+! CHECK: %[[C1:.*]] = arith.constant 1 : index
+! CHECK: %[[LB:.*]] = arith.constant 0 : index
+! CHECK: %[[UB:.*]] = arith.constant 49 : index
+! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index)
+! CHECK: %[[B_PRIVATE:.*]] = acc.private varPtr(%[[B]] : !fir.ref<!fir.array<100xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<50xf32>> {name = "b(1:50)"}
+! CHECK: acc.loop private(@privatization_ref_50xf32 -> %[[B_PRIVATE]] : !fir.ref<!fir.array<50xf32>>)
+
end program
More information about the flang-commits
mailing list