Skip to content

Commit c8b5f4c

Browse files
authored
[flang][openacc] Support array with dynamic extent in private recipe (#68624)
Add lowering support for array with dynamic extents for private recipe. The extents are passed as block arguments and used in the alloca operation. The shape also used this information for the hlfir.declare operation.
1 parent 14d0cd6 commit c8b5f4c

File tree

6 files changed

+86
-37
lines changed

6 files changed

+86
-37
lines changed

flang/lib/Lower/OpenACC.cpp

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -382,13 +382,23 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
382382
retVal = declareOp.getBase();
383383
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(
384384
refTy.getEleTy())) {
385-
if (seqTy.hasDynamicExtents())
386-
TODO(loc, "private recipe of array with dynamic extents");
387385
if (fir::isa_trivial(seqTy.getEleTy())) {
388-
auto alloca = builder.create<fir::AllocaOp>(loc, seqTy);
389-
auto shapeOp = genShapeOp(builder, seqTy, loc);
386+
mlir::Value shape;
387+
llvm::SmallVector<mlir::Value> extents;
388+
if (seqTy.hasDynamicExtents()) {
389+
// Extents are passed as block arguments. First argument is the
390+
// original value.
391+
for (unsigned i = 1; i < recipe.getInitRegion().getArguments().size();
392+
++i)
393+
extents.push_back(recipe.getInitRegion().getArgument(i));
394+
shape = builder.create<fir::ShapeOp>(loc, extents);
395+
} else {
396+
shape = genShapeOp(builder, seqTy, loc);
397+
}
398+
auto alloca = builder.create<fir::AllocaOp>(
399+
loc, seqTy, /*typeparams=*/mlir::ValueRange{}, extents);
390400
auto declareOp = builder.create<hlfir::DeclareOp>(
391-
loc, alloca, accPrivateInitName, shapeOp,
401+
loc, alloca, accPrivateInitName, shape,
392402
llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
393403
retVal = declareOp.getBase();
394404
}
@@ -418,8 +428,22 @@ Fortran::lower::createOrGetPrivateRecipe(mlir::OpBuilder &builder,
418428
mlir::OpBuilder modBuilder(mod.getBodyRegion());
419429
auto recipe =
420430
modBuilder.create<mlir::acc::PrivateRecipeOp>(loc, recipeName, ty);
431+
llvm::SmallVector<mlir::Type> argsTy{ty};
432+
llvm::SmallVector<mlir::Location> argsLoc{loc};
433+
if (auto refTy = mlir::dyn_cast_or_null<fir::ReferenceType>(ty)) {
434+
if (auto seqTy =
435+
mlir::dyn_cast_or_null<fir::SequenceType>(refTy.getEleTy())) {
436+
if (seqTy.hasDynamicExtents()) {
437+
mlir::Type idxTy = builder.getIndexType();
438+
for (unsigned i = 0; i < seqTy.getDimension(); ++i) {
439+
argsTy.push_back(idxTy);
440+
argsLoc.push_back(loc);
441+
}
442+
}
443+
}
444+
}
421445
builder.createBlock(&recipe.getInitRegion(), recipe.getInitRegion().end(),
422-
{ty}, {loc});
446+
argsTy, argsLoc);
423447
builder.setInsertionPointToEnd(&recipe.getInitRegion().back());
424448
genPrivateLikeInitRegion<mlir::acc::PrivateRecipeOp>(builder, recipe, ty,
425449
loc);
@@ -554,6 +578,29 @@ mlir::Type getTypeFromBounds(llvm::SmallVector<mlir::Value> &bounds,
554578
return ty;
555579
}
556580

581+
/// Check if the DataBoundsOp is a constant bound (lb and ub are constants or
582+
/// extent is a constant).
583+
bool isConstantBound(mlir::acc::DataBoundsOp &op) {
584+
if (op.getLowerbound() && fir::getIntIfConstant(op.getLowerbound()) &&
585+
op.getUpperbound() && fir::getIntIfConstant(op.getUpperbound()))
586+
return true;
587+
if (op.getExtent() && fir::getIntIfConstant(op.getExtent()))
588+
return true;
589+
return false;
590+
}
591+
592+
/// Return true iff all the bounds are expressed with constant values.
593+
bool areAllBoundConstant(llvm::SmallVector<mlir::Value> &bounds) {
594+
for (auto bound : bounds) {
595+
auto dataBound =
596+
mlir::dyn_cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp());
597+
assert(dataBound && "Must be DataBoundOp operation");
598+
if (!isConstantBound(dataBound))
599+
return false;
600+
}
601+
return true;
602+
}
603+
557604
template <typename RecipeOp>
558605
static void
559606
genPrivatizations(const Fortran::parser::AccObjectList &objectList,
@@ -683,29 +730,6 @@ static R getReductionInitValue(mlir::acc::ReductionOperator op, mlir::Type ty) {
683730
llvm_unreachable("OpenACC reduction unsupported type");
684731
}
685732

686-
/// Check if the DataBoundsOp is a constant bound (lb and ub are constants or
687-
/// extent is a constant).
688-
bool isConstantBound(mlir::acc::DataBoundsOp &op) {
689-
if (op.getLowerbound() && fir::getIntIfConstant(op.getLowerbound()) &&
690-
op.getUpperbound() && fir::getIntIfConstant(op.getUpperbound()))
691-
return true;
692-
if (op.getExtent() && fir::getIntIfConstant(op.getExtent()))
693-
return true;
694-
return false;
695-
}
696-
697-
/// Return true iff all the bounds are expressed with constant values.
698-
bool areAllBoundConstant(llvm::SmallVector<mlir::Value> &bounds) {
699-
for (auto bound : bounds) {
700-
auto dataBound =
701-
mlir::dyn_cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp());
702-
assert(dataBound && "Must be DataBoundOp operation");
703-
if (!isConstantBound(dataBound))
704-
return false;
705-
}
706-
return true;
707-
}
708-
709733
/// Return a constant with the initial value for the reduction operator and
710734
/// type combination.
711735
static mlir::Value getReductionInitValue(fir::FirOpBuilder &builder,

flang/test/Lower/OpenACC/acc-parallel-loop.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10xf32 : !fir.ref<!fir.array<10xf32>> init {
77
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10xf32>>):
8-
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10xf32>
98
! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
9+
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10xf32>
1010
! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
1111
! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10xf32>>
1212
! CHECK: } copy {

flang/test/Lower/OpenACC/acc-parallel.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10x10xf32 : !fir.ref<!fir.array<10x10xf32>> init {
77
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>):
8-
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32>
98
! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
9+
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32>
1010
! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10x10xf32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>)
1111
! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10x10xf32>>
1212
! CHECK: } copy {

flang/test/Lower/OpenACC/acc-private.f90

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s --check-prefixes=CHECK,FIR
44
! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s --check-prefixes=CHECK,HLFIR
55

6+
! CHECK-LABEL: acc.private.recipe @privatization_ref_UxUx2xi32 : !fir.ref<!fir.array<?x?x2xi32>> init {
7+
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<?x?x2xi32>>, %[[ARG1:.*]]: index, %[[ARG2:.*]]: index, %[[ARG3:.*]]: index):
8+
! HLFIR: %[[SHAPE:.*]] = fir.shape %[[ARG1]], %[[ARG2]], %[[ARG3]] : (index, index, index) -> !fir.shape<3>
9+
! HLFIR: %[[ALLOCA:.*]] = fir.alloca !fir.array<?x?x2xi32>, %[[ARG1]], %[[ARG2]], %[[ARG3]]
10+
! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<?x?x2xi32>>, !fir.shape<3>) -> (!fir.box<!fir.array<?x?x2xi32>>, !fir.ref<!fir.array<?x?x2xi32>>)
11+
! HLFIR: acc.yield %[[DECL]]#0 : !fir.box<!fir.array<?x?x2xi32>>
12+
! CHECK: }
13+
614
! CHECK-LABEL: acc.private.recipe @privatization_box_ptr_Uxi32 : !fir.box<!fir.ptr<!fir.array<?xi32>>> init {
715
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.ptr<!fir.array<?xi32>>>):
816
! HLFIR: %[[C0:.*]] = arith.constant 0 : index
@@ -35,8 +43,8 @@
3543

3644
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_50xf32 : !fir.ref<!fir.array<50xf32>> init {
3745
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<50xf32>>):
38-
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<50xf32>
3946
! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
47+
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<50xf32>
4048
! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<50xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<50xf32>>, !fir.ref<!fir.array<50xf32>>)
4149
! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<50xf32>>
4250
! CHECK: } copy {
@@ -55,8 +63,8 @@
5563

5664
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_100xf32 : !fir.ref<!fir.array<100xf32>> init {
5765
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xf32>>):
58-
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32>
5966
! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
67+
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32>
6068
! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
6169
! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xf32>>
6270
! CHECK: } copy {
@@ -87,16 +95,16 @@
8795

8896
! CHECK-LABEL: acc.private.recipe @privatization_ref_50xf32 : !fir.ref<!fir.array<50xf32>> init {
8997
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<50xf32>>):
90-
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<50xf32>
9198
! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
99+
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<50xf32>
92100
! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<50xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<50xf32>>, !fir.ref<!fir.array<50xf32>>)
93101
! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<50xf32>>
94102
! CHECK: }
95103

96104
! CHECK-LABEL: acc.private.recipe @privatization_ref_100xf32 : !fir.ref<!fir.array<100xf32>> init {
97105
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xf32>>):
98-
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32>
99106
! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
107+
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32>
100108
! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
101109
! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xf32>>
102110
! CHECK: }
@@ -251,3 +259,20 @@ subroutine acc_private_pointer_array(a, n)
251259
! HLFIR: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
252260
! HLFIR: %[[PRIVATE:.*]] = acc.private varPtr(%[[BOX_ADDR]] : !fir.ptr<!fir.array<?xi32>>) bounds(%{{.*}}) -> !fir.ptr<!fir.array<?xi32>> {name = "a"}
253261
! HLFIR: acc.parallel private(@privatization_box_ptr_Uxi32 -> %[[PRIVATE]] : !fir.ptr<!fir.array<?xi32>>)
262+
263+
subroutine acc_private_dynamic_extent(a, n)
264+
integer :: n, i
265+
integer :: a(n, n, 2)
266+
267+
!$acc parallel loop private(a)
268+
do i = 1, n
269+
a(i, i, 1) = i
270+
end do
271+
end subroutine
272+
273+
! CHECK-LABEL: func.func @_QPacc_private_dynamic_extent(
274+
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?x?x2xi32>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
275+
! HLFIR: %[[DECL_N:.*]]:2 = hlfir.declare %arg1 {uniq_name = "_QFacc_private_dynamic_extentEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
276+
! HLFIR: %[[DECL_A:.*]]:2 = hlfir.declare %[[ARG0]](%16) {uniq_name = "_QFacc_private_dynamic_extentEa"} : (!fir.ref<!fir.array<?x?x2xi32>>, !fir.shape<3>) -> (!fir.box<!fir.array<?x?x2xi32>>, !fir.ref<!fir.array<?x?x2xi32>>)
277+
! HLFIR: %[[PRIV:.*]] = acc.private varPtr(%[[DECL_A]]#1 : !fir.ref<!fir.array<?x?x2xi32>>) bounds(%{{.*}}, %{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<?x?x2xi32>> {name = "a"}
278+
! HLFIR: acc.parallel private(@privatization_ref_UxUx2xi32 -> %[[PRIV]] : !fir.ref<!fir.array<?x?x2xi32>>)

flang/test/Lower/OpenACC/acc-serial-loop.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10xf32 : !fir.ref<!fir.array<10xf32>> init {
77
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10xf32>>):
8-
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10xf32>
98
! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
9+
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10xf32>
1010
! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
1111
! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10xf32>>
1212
! CHECK: } copy {

flang/test/Lower/OpenACC/acc-serial.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10x10xf32 : !fir.ref<!fir.array<10x10xf32>> init {
77
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>):
8-
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32>
98
! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
9+
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32>
1010
! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10x10xf32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>)
1111
! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10x10xf32>>
1212
! CHECK: } copy {

0 commit comments

Comments
 (0)