Skip to content

Commit

Permalink
[flang][openacc] Populate init and copy region of firstprivate recipe…
Browse files Browse the repository at this point in the history
… for simple type

Similiar to D154259 for private recipe, this patch makes use of the same code
for the init region of the firstprivate recipe and populate the copy region for
trivial types and arrays.

Reviewed By: razvanlupusoru

Differential Revision: https://reviews.llvm.org/D154657
  • Loading branch information
clementval committed Jul 12, 2023
1 parent bcba20b commit 67c8110
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 26 deletions.
76 changes: 59 additions & 17 deletions flang/lib/Lower/OpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,24 @@ static void genDataExitOperations(fir::FirOpBuilder &builder,
}
}

template <typename RecipeOp>
static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
mlir::Type ty, mlir::Location loc) {
mlir::Value retVal = recipe.getInitRegion().front().getArgument(0);
if (auto refTy = mlir::dyn_cast_or_null<fir::ReferenceType>(ty)) {
if (fir::isa_trivial(refTy.getEleTy()))
retVal = builder.create<fir::AllocaOp>(loc, refTy.getEleTy());
else if (auto seqTy =
mlir::dyn_cast_or_null<fir::SequenceType>(refTy.getEleTy())) {
if (seqTy.hasDynamicExtents())
TODO(loc, "private recipe of array with dynamic extents");
if (fir::isa_trivial(seqTy.getEleTy()))
retVal = builder.create<fir::AllocaOp>(loc, seqTy);
}
}
builder.create<mlir::acc::YieldOp>(loc, retVal);
}

mlir::acc::PrivateRecipeOp
Fortran::lower::createOrGetPrivateRecipe(mlir::OpBuilder &builder,
llvm::StringRef recipeName,
Expand All @@ -432,20 +450,8 @@ Fortran::lower::createOrGetPrivateRecipe(mlir::OpBuilder &builder,
builder.createBlock(&recipe.getInitRegion(), recipe.getInitRegion().end(),
{ty}, {loc});
builder.setInsertionPointToEnd(&recipe.getInitRegion().back());

mlir::Value retVal = recipe.getInitRegion().front().getArgument(0);
if (auto refTy = mlir::dyn_cast_or_null<fir::ReferenceType>(ty)) {
if (fir::isa_trivial(refTy.getEleTy()))
retVal = builder.create<fir::AllocaOp>(loc, refTy.getEleTy());
else if (auto seqTy =
mlir::dyn_cast_or_null<fir::SequenceType>(refTy.getEleTy())) {
if (seqTy.hasDynamicExtents())
TODO(loc, "private recipe of array with dynamic extents");
if (fir::isa_trivial(seqTy.getEleTy()))
retVal = builder.create<fir::AllocaOp>(loc, seqTy);
}
}
builder.create<mlir::acc::YieldOp>(loc, retVal);
genPrivateLikeInitRegion<mlir::acc::PrivateRecipeOp>(builder, recipe, ty,
loc);
builder.restoreInsertionPoint(crtPos);
return recipe;
}
Expand All @@ -466,15 +472,51 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(
builder.createBlock(&recipe.getInitRegion(), recipe.getInitRegion().end(),
{ty}, {loc});
builder.setInsertionPointToEnd(&recipe.getInitRegion().back());
builder.create<mlir::acc::YieldOp>(
loc, recipe.getInitRegion().front().getArgument(0));
genPrivateLikeInitRegion<mlir::acc::FirstprivateRecipeOp>(builder, recipe, ty,
loc);

// Add empty copy region for firstprivate. TODO add copy sequence.
builder.createBlock(&recipe.getCopyRegion(), recipe.getCopyRegion().end(),
{ty, ty}, {loc, loc});

builder.setInsertionPointToEnd(&recipe.getCopyRegion().back());
if (auto refTy = mlir::dyn_cast_or_null<fir::ReferenceType>(ty)) {
if (fir::isa_trivial(refTy.getEleTy())) {
mlir::Value initValue = builder.create<fir::LoadOp>(
loc, recipe.getCopyRegion().front().getArgument(0));
builder.create<fir::StoreOp>(
loc, initValue, recipe.getCopyRegion().front().getArgument(1));
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(
refTy.getEleTy())) {
if (seqTy.hasDynamicExtents())
TODO(loc, "private recipe of array with dynamic extents");
mlir::Type idxTy = builder.getIndexType();
mlir::Type refTy = fir::ReferenceType::get(seqTy.getEleTy());
mlir::Value arraySrc = recipe.getCopyRegion().front().getArgument(0);
mlir::Value arrayDst = recipe.getCopyRegion().front().getArgument(1);
llvm::SmallVector<fir::DoLoopOp> loops;
llvm::SmallVector<mlir::Value> ivs;
for (auto ext : llvm::reverse(seqTy.getShape())) {
auto lb = builder.create<mlir::arith::ConstantOp>(
loc, idxTy, builder.getIntegerAttr(idxTy, 0));
auto ub = builder.create<mlir::arith::ConstantOp>(
loc, idxTy, builder.getIntegerAttr(idxTy, ext - 1));
auto step = builder.create<mlir::arith::ConstantOp>(
loc, idxTy, builder.getIntegerAttr(idxTy, 1));
auto loop = builder.create<fir::DoLoopOp>(loc, lb, ub, step,
/*unordered=*/false);
builder.setInsertionPointToStart(loop.getBody());
loops.push_back(loop);
ivs.push_back(loop.getInductionVar());
}
auto addr1 = builder.create<fir::CoordinateOp>(loc, refTy, arraySrc, ivs);
auto addr2 = builder.create<fir::CoordinateOp>(loc, refTy, arrayDst, ivs);
auto loadedValue = builder.create<fir::LoadOp>(loc, addr1);
builder.create<fir::StoreOp>(loc, loadedValue, addr2);
builder.setInsertionPointAfter(loops[0]);
}
}
builder.create<mlir::acc::TerminatorOp>(loc);

builder.restoreInsertionPoint(crtPos);
return recipe;
}
Expand Down
16 changes: 13 additions & 3 deletions flang/test/Lower/OpenACC/acc-parallel-loop.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,20 @@
! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s

! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10xf32 : !fir.ref<!fir.array<10xf32>> init {
! CHECK: ^bb0(%arg0: !fir.ref<!fir.array<10xf32>>):
! CHECK: acc.yield %arg0 : !fir.ref<!fir.array<10xf32>>
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10xf32>>):
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10xf32>
! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<!fir.array<10xf32>>
! CHECK: } copy {
! CHECK: ^bb0(%arg0: !fir.ref<!fir.array<10xf32>>, %arg1: !fir.ref<!fir.array<10xf32>>):
! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.array<10xf32>>, %[[DST:.*]]: !fir.ref<!fir.array<10xf32>>):
! CHECK: %[[LB0:.*]] = arith.constant 0 : index
! CHECK: %[[UB0:.*]] = arith.constant 9 : index
! CHECK: %[[STEP0:.*]] = arith.constant 1 : index
! CHECK: fir.do_loop %[[IV0:.*]] = %[[LB0]] to %[[UB0]] step %[[STEP0]] {
! CHECK: %[[COORD0:.*]] = fir.coordinate_of %[[SRC]], %[[IV0]] : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[DST]], %[[IV0]] : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
! CHECK: %[[LOAD:.*]] = fir.load %[[COORD0]] : !fir.ref<f32>
! CHECK: fir.store %[[LOAD]] to %[[COORD1]] : !fir.ref<f32>
! CHECK: }
! CHECK: acc.terminator
! CHECK: }

Expand Down
5 changes: 3 additions & 2 deletions flang/test/Lower/OpenACC/acc-parallel.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s

! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10x10xf32 : !fir.ref<!fir.array<10x10xf32>> init {
! CHECK: ^bb0(%arg0: !fir.ref<!fir.array<10x10xf32>>):
! CHECK: acc.yield %arg0 : !fir.ref<!fir.array<10x10xf32>>
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>):
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32>
! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<!fir.array<10x10xf32>>
! CHECK: } copy {
! CHECK: ^bb0(%arg0: !fir.ref<!fir.array<10x10xf32>>, %arg1: !fir.ref<!fir.array<10x10xf32>>):
! CHECK: acc.terminator
Expand Down
51 changes: 51 additions & 0 deletions flang/test/Lower/OpenACC/acc-private.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,35 @@

! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s

! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_100xf32 : !fir.ref<!fir.array<100xf32>> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xf32>>):
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32>
! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<!fir.array<100xf32>>
! CHECK: } copy {
! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.array<100xf32>>, %[[DST:.*]]: !fir.ref<!fir.array<100xf32>>):
! CHECK: %[[LB0:.*]] = arith.constant 0 : index
! CHECK: %[[UB0:.*]] = arith.constant 99 : index
! CHECK: %[[STEP1:.*]] = arith.constant 1 : index
! CHECK: fir.do_loop %[[IV0:.*]] = %c0 to %c99 step %c1 {
! CHECK: %[[COORD0:.*]] = fir.coordinate_of %[[SRC]], %[[IV0]] : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[DST]], %[[IV0]] : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
! CHECK: %[[VALUE:.*]] = fir.load %[[COORD0]] : !fir.ref<f32>
! CHECK: fir.store %[[VALUE]] to %[[COORD1]] : !fir.ref<f32>
! CHECK: }
! CHECK: acc.terminator
! CHECK: }

! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i32 : !fir.ref<i32> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<i32>
! CHECK: } copy {
! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<i32>, %[[DST:.*]]: !fir.ref<i32>):
! CHECK: %[[VALUE:.*]] = fir.load %[[SRC]] : !fir.ref<i32>
! CHECK: fir.store %[[VALUE]] to %[[DST]] : !fir.ref<i32>
! CHECK: acc.terminator
! CHECK: }

! 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>
Expand Down Expand Up @@ -65,5 +94,27 @@ program acc_private
! 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>>)

!$acc parallel loop firstprivate(c)
DO i = 1, n
c = i
a(i) = b(i) + c
END DO

! CHECK: %[[FP_C:.*]] = acc.firstprivate varPtr(%[[C]] : !fir.ref<i32>) -> !fir.ref<i32> {name = "c"}
! CHECK: acc.parallel firstprivate(@firstprivatization_ref_i32 -> %[[FP_C]] : !fir.ref<i32>)
! CHECK: acc.yield

!$acc parallel loop firstprivate(b)
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.subi %{{.*}}, %[[C1]] : index
! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index)
! CHECK: %[[FP_B:.*]] = acc.firstprivate varPtr(%[[B]] : !fir.ref<!fir.array<100xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<100xf32>> {name = "b"}
! CHECK: acc.parallel firstprivate(@firstprivatization_ref_100xf32 -> %[[FP_B]] : !fir.ref<!fir.array<100xf32>>)

end program
5 changes: 3 additions & 2 deletions flang/test/Lower/OpenACC/acc-serial-loop.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s

! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10xf32 : !fir.ref<!fir.array<10xf32>> init {
! CHECK: ^bb0(%arg0: !fir.ref<!fir.array<10xf32>>):
! CHECK: acc.yield %arg0 : !fir.ref<!fir.array<10xf32>>
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10xf32>>):
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10xf32>
! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<!fir.array<10xf32>>
! CHECK: } copy {
! CHECK: ^bb0(%arg0: !fir.ref<!fir.array<10xf32>>, %arg1: !fir.ref<!fir.array<10xf32>>):
! CHECK: acc.terminator
Expand Down
5 changes: 3 additions & 2 deletions flang/test/Lower/OpenACC/acc-serial.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s

! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10x10xf32 : !fir.ref<!fir.array<10x10xf32>> init {
! CHECK: ^bb0(%arg0: !fir.ref<!fir.array<10x10xf32>>):
! CHECK: acc.yield %arg0 : !fir.ref<!fir.array<10x10xf32>>
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>):
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32>
! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<!fir.array<10x10xf32>>
! CHECK: } copy {
! CHECK: ^bb0(%arg0: !fir.ref<!fir.array<10x10xf32>>, %arg1: !fir.ref<!fir.array<10x10xf32>>):
! CHECK: acc.terminator
Expand Down

0 comments on commit 67c8110

Please sign in to comment.