summaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorValentin Clement <clementval@gmail.com>2023-05-15 11:22:12 -0700
committerValentin Clement <clementval@gmail.com>2023-05-15 11:22:39 -0700
commit38423349ce84c80a825477cc997fd071e248b2e0 (patch)
tree860f6e81fa0ec47307234373ae258541503f40cd /flang
parent6c7acc6409cb13c7df264a3d07e2ff2b6119fc40 (diff)
downloadllvm-38423349ce84c80a825477cc997fd071e248b2e0.tar.gz
[flang][openacc] Lower host_data construct
Lower host_data construct to the acc.host_data operation. Depends on D150289 Reviewed By: razvanlupusoru, jeanPerier Differential Revision: https://reviews.llvm.org/D150290
Diffstat (limited to 'flang')
-rw-r--r--flang/lib/Lower/OpenACC.cpp61
-rw-r--r--flang/test/Lower/OpenACC/acc-host-data.f9050
2 files changed, 110 insertions, 1 deletions
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index fb6b71466021..cc2113c230b4 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -1154,6 +1154,64 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter,
}
static void
+genACCHostDataOp(Fortran::lower::AbstractConverter &converter,
+ mlir::Location currentLocation,
+ Fortran::semantics::SemanticsContext &semanticsContext,
+ Fortran::lower::StatementContext &stmtCtx,
+ const Fortran::parser::AccClauseList &accClauseList) {
+ mlir::Value ifCond;
+ llvm::SmallVector<mlir::Value> dataOperands;
+ bool addIfPresentAttr = false;
+
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+
+ for (const Fortran::parser::AccClause &clause : accClauseList.v) {
+ mlir::Location clauseLocation = converter.genLocation(clause.source);
+ if (const auto *ifClause =
+ std::get_if<Fortran::parser::AccClause::If>(&clause.u)) {
+ genIfClause(converter, clauseLocation, ifClause, ifCond, stmtCtx);
+ } else if (const auto *useDevice =
+ std::get_if<Fortran::parser::AccClause::UseDevice>(
+ &clause.u)) {
+ genDataOperandOperations<mlir::acc::UseDeviceOp>(
+ useDevice->v, converter, semanticsContext, stmtCtx, dataOperands,
+ mlir::acc::DataClause::acc_use_device,
+ /*structured=*/true);
+ } else if (std::get_if<Fortran::parser::AccClause::IfPresent>(&clause.u)) {
+ addIfPresentAttr = true;
+ }
+ }
+
+ if (ifCond) {
+ if (auto cst =
+ mlir::dyn_cast<mlir::arith::ConstantOp>(ifCond.getDefiningOp()))
+ if (auto boolAttr = cst.getValue().dyn_cast<mlir::BoolAttr>()) {
+ if (boolAttr.getValue()) {
+ // get rid of the if condition if it is always true.
+ ifCond = mlir::Value();
+ } else {
+ // Do not generate the acc.host_data op if the if condition is always
+ // false.
+ return;
+ }
+ }
+ }
+
+ // Prepare the operand segment size attribute and the operands value range.
+ llvm::SmallVector<mlir::Value> operands;
+ llvm::SmallVector<int32_t> operandSegments;
+ addOperand(operands, operandSegments, ifCond);
+ addOperands(operands, operandSegments, dataOperands);
+
+ auto hostDataOp =
+ createRegionOp<mlir::acc::HostDataOp, mlir::acc::TerminatorOp>(
+ builder, currentLocation, operands, operandSegments);
+
+ if (addIfPresentAttr)
+ hostDataOp.setIfPresentAttr(builder.getUnitAttr());
+}
+
+static void
genACC(Fortran::lower::AbstractConverter &converter,
Fortran::semantics::SemanticsContext &semanticsContext,
Fortran::lower::pft::Evaluation &eval,
@@ -1181,7 +1239,8 @@ genACC(Fortran::lower::AbstractConverter &converter,
createComputeOp<mlir::acc::KernelsOp>(
converter, currentLocation, semanticsContext, stmtCtx, accClauseList);
} else if (blockDirective.v == llvm::acc::ACCD_host_data) {
- TODO(currentLocation, "host_data construct lowering");
+ genACCHostDataOp(converter, currentLocation, semanticsContext, stmtCtx,
+ accClauseList);
}
}
diff --git a/flang/test/Lower/OpenACC/acc-host-data.f90 b/flang/test/Lower/OpenACC/acc-host-data.f90
new file mode 100644
index 000000000000..492da53075ae
--- /dev/null
+++ b/flang/test/Lower/OpenACC/acc-host-data.f90
@@ -0,0 +1,50 @@
+! This test checks lowering of OpenACC host_data directive.
+
+! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s
+
+subroutine acc_host_data()
+ real, dimension(10) :: a
+ logical :: ifCondition = .TRUE.
+
+! CHECK: %[[A:.*]] = fir.alloca !fir.array<10xf32> {bindc_name = "a", uniq_name = "_QFacc_host_dataEa"}
+! CHECK: %[[IFCOND:.*]] = fir.address_of(@_QFacc_host_dataEifcondition) : !fir.ref<!fir.logical<4>>
+
+ !$acc host_data use_device(a)
+ !$acc end host_data
+
+! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%{{.*}} : index)
+! CHECK: %[[DA:.*]] = acc.use_device varPtr(%[[A]] : !fir.ref<!fir.array<10xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
+! CHECK: acc.host_data dataOperands(%[[DA]] : !fir.ref<!fir.array<10xf32>>)
+
+ !$acc host_data use_device(a) if_present
+ !$acc end host_data
+
+! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%{{.*}} : index)
+! CHECK: %[[DA:.*]] = acc.use_device varPtr(%[[A]] : !fir.ref<!fir.array<10xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
+! CHECK: acc.host_data dataOperands(%[[DA]] : !fir.ref<!fir.array<10xf32>>) {
+! CHECK: } attributes {ifPresent}
+
+ !$acc host_data use_device(a) if(ifCondition)
+ !$acc end host_data
+
+! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%{{.*}} : index)
+! CHECK: %[[DA:.*]] = acc.use_device varPtr(%[[A]] : !fir.ref<!fir.array<10xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
+! CHECK: %[[LOAD_IFCOND:.*]] = fir.load %[[IFCOND]] : !fir.ref<!fir.logical<4>>
+! CHECK: %[[IFCOND_I1:.*]] = fir.convert %[[LOAD_IFCOND]] : (!fir.logical<4>) -> i1
+! CHECK: acc.host_data if(%[[IFCOND_I1]]) dataOperands(%[[DA]] : !fir.ref<!fir.array<10xf32>>)
+
+ !$acc host_data use_device(a) if(.true.)
+ !$acc end host_data
+
+! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%{{.*}} : index)
+! CHECK: %[[DA:.*]] = acc.use_device varPtr(%[[A]] : !fir.ref<!fir.array<10xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
+! CHECK: acc.host_data dataOperands(%[[DA]] : !fir.ref<!fir.array<10xf32>>)
+
+ !$acc host_data use_device(a) if(.false.)
+ a = 1.0
+ !$acc end host_data
+
+! CHECK-NOT: acc.host_data
+! CHECK: fir.do_loop
+
+end subroutine