From 38423349ce84c80a825477cc997fd071e248b2e0 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Mon, 15 May 2023 11:22:12 -0700 Subject: [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 --- flang/lib/Lower/OpenACC.cpp | 61 +++++++++++++++++++++++++++++- flang/test/Lower/OpenACC/acc-host-data.f90 | 50 ++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 flang/test/Lower/OpenACC/acc-host-data.f90 (limited to 'flang') 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 @@ -1153,6 +1153,64 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter, builder.restoreInsertionPoint(insPt); } +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 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(&clause.u)) { + genIfClause(converter, clauseLocation, ifClause, ifCond, stmtCtx); + } else if (const auto *useDevice = + std::get_if( + &clause.u)) { + genDataOperandOperations( + useDevice->v, converter, semanticsContext, stmtCtx, dataOperands, + mlir::acc::DataClause::acc_use_device, + /*structured=*/true); + } else if (std::get_if(&clause.u)) { + addIfPresentAttr = true; + } + } + + if (ifCond) { + if (auto cst = + mlir::dyn_cast(ifCond.getDefiningOp())) + if (auto boolAttr = cst.getValue().dyn_cast()) { + 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 operands; + llvm::SmallVector operandSegments; + addOperand(operands, operandSegments, ifCond); + addOperands(operands, operandSegments, dataOperands); + + auto hostDataOp = + createRegionOp( + builder, currentLocation, operands, operandSegments); + + if (addIfPresentAttr) + hostDataOp.setIfPresentAttr(builder.getUnitAttr()); +} + static void genACC(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semanticsContext, @@ -1181,7 +1239,8 @@ genACC(Fortran::lower::AbstractConverter &converter, createComputeOp( 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> + + !$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>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} +! CHECK: acc.host_data dataOperands(%[[DA]] : !fir.ref>) + + !$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>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} +! CHECK: acc.host_data dataOperands(%[[DA]] : !fir.ref>) { +! 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>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} +! CHECK: %[[LOAD_IFCOND:.*]] = fir.load %[[IFCOND]] : !fir.ref> +! CHECK: %[[IFCOND_I1:.*]] = fir.convert %[[LOAD_IFCOND]] : (!fir.logical<4>) -> i1 +! CHECK: acc.host_data if(%[[IFCOND_I1]]) dataOperands(%[[DA]] : !fir.ref>) + + !$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>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} +! CHECK: acc.host_data dataOperands(%[[DA]] : !fir.ref>) + + !$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 -- cgit v1.2.1