From 849183e094741f645cf16b4bc3a33673c4864d71 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Fri, 3 Nov 2023 15:21:52 -0700 Subject: [PATCH 1/3] [flang][openacc] Support variable in equivalence in declare directive --- flang/lib/Lower/OpenACC.cpp | 86 ++++++++++++++----- .../test/Lower/OpenACC/HLFIR/acc-declare.f90 | 58 +++++++++++++ 2 files changed, 122 insertions(+), 22 deletions(-) diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 809fd3b3be7cf..7808e94ed7c73 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -27,6 +27,7 @@ #include "flang/Optimizer/Builder/Todo.h" #include "flang/Parser/parse-tree.h" #include "flang/Semantics/expression.h" +#include "flang/Semantics/scope.h" #include "flang/Semantics/tools.h" #include "llvm/Frontend/OpenACC/ACC.h.inc" @@ -2740,33 +2741,40 @@ static void genACC(Fortran::lower::AbstractConverter &converter, template -static void createDeclareGlobalOp(mlir::OpBuilder &modBuilder, - fir::FirOpBuilder &builder, - mlir::Location loc, fir::GlobalOp &globalOp, - mlir::acc::DataClause clause, bool implicit) { - std::stringstream declareGlobalName; - - if constexpr (std::is_same_v) - declareGlobalName << globalOp.getSymName().str() << "_acc_ctor"; - else if constexpr (std::is_same_v) - declareGlobalName << globalOp.getSymName().str() << "_acc_dtor"; - +static void +createDeclareGlobalOp(mlir::OpBuilder &modBuilder, fir::FirOpBuilder &builder, + mlir::Location loc, fir::GlobalOp globalOp, + mlir::acc::DataClause clause, + const std::string declareGlobalName, bool implicit, + std::optional &offset, mlir::Type aliasType, + std::stringstream &asFortran) { GlobalOp declareGlobalOp = - modBuilder.create(loc, declareGlobalName.str()); + modBuilder.create(loc, declareGlobalName); builder.createBlock(&declareGlobalOp.getRegion(), declareGlobalOp.getRegion().end(), {}, {}); builder.setInsertionPointToEnd(&declareGlobalOp.getRegion().back()); + mlir::Value entryAddr; fir::AddrOfOp addrOp = builder.create( loc, fir::ReferenceType::get(globalOp.getType()), globalOp.getSymbol()); - addDeclareAttr(builder, addrOp.getOperation(), clause); + entryAddr = addrOp.getResTy(); + // If the variable in the declare clause is part of an equivalence it has an + // offset. + if (offset) { + mlir::Type i8Ptr = builder.getRefType(builder.getI8Type()); + mlir::Value off = + builder.createIntegerConstant(loc, builder.getIndexType(), *offset); + mlir::Value aliasAddr = builder.create( + loc, i8Ptr, addrOp.getResTy(), mlir::ValueRange{off}); + entryAddr = + builder.createConvert(loc, fir::PointerType::get(aliasType), aliasAddr); + } + addDeclareAttr(builder, entryAddr.getDefiningOp(), clause); - std::stringstream asFortran; - asFortran << Fortran::lower::mangle::demangleName(globalOp.getSymName()); llvm::SmallVector bounds; EntryOp entryOp = createDataEntryOp( - builder, loc, addrOp.getResTy(), asFortran, bounds, - /*structured=*/false, implicit, clause, addrOp.getResTy().getType()); + builder, loc, entryAddr, asFortran, bounds, + /*structured=*/false, implicit, clause, entryAddr.getType()); builder.create(loc, mlir::ValueRange(entryOp.getAccPtr())); mlir::Value varPtr; if constexpr (std::is_same_v) { @@ -2904,8 +2912,39 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter, designator)) { std::string globalName = converter.mangleName(*name->symbol); fir::GlobalOp globalOp = builder.getNamedGlobal(globalName); - if (!globalOp) - llvm::report_fatal_error("could not retrieve global symbol"); + std::stringstream declareGlobalCtorName; + declareGlobalCtorName << globalName << "_acc_ctor"; + std::stringstream declareGlobalDtorName; + declareGlobalDtorName << globalName << "_acc_dtor"; + std::optional offset = std::nullopt; + mlir::Type aliasType; + + std::stringstream asFortran; + asFortran << name->symbol->name().ToString(); + + if (!globalOp) { + if (Fortran::semantics::FindEquivalenceSet(*name->symbol)) { + for (Fortran::semantics::EquivalenceObject eqObj : + *Fortran::semantics::FindEquivalenceSet( + *name->symbol)) { + std::string eqName = converter.mangleName(eqObj.symbol); + globalOp = builder.getNamedGlobal(eqName); + if (globalOp) + break; + } + + if (!globalOp) + llvm::report_fatal_error( + "could not retrieve global symbol"); + + offset = name->symbol->GetUltimate().offset(); + aliasType = converter.genType(name->symbol->GetUltimate()); + } else { + llvm::report_fatal_error( + "could not retrieve global symbol"); + } + } + addDeclareAttr(builder, globalOp.getOperation(), clause); auto crtPos = builder.saveInsertionPoint(); modBuilder.setInsertionPointAfter(globalOp); @@ -2915,7 +2954,8 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter, mlir::acc::CopyinOp, mlir::acc::DeclareEnterOp, ExitOp>( modBuilder, builder, operandLocation, globalOp, clause, - /*implicit=*/true); + declareGlobalCtorName.str(), /*implicit=*/true, offset, + aliasType, asFortran); createDeclareAllocFunc( modBuilder, builder, operandLocation, globalOp, clause); if constexpr (!std::is_same_v) @@ -2925,14 +2965,16 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter, createDeclareGlobalOp( modBuilder, builder, operandLocation, globalOp, clause, - /*implicit=*/false); + declareGlobalCtorName.str(), /*implicit=*/false, offset, + aliasType, asFortran); } if constexpr (!std::is_same_v) { createDeclareGlobalOp( modBuilder, builder, operandLocation, globalOp, clause, - /*implicit=*/false); + declareGlobalDtorName.str(), /*implicit=*/false, offset, + aliasType, asFortran); } builder.restoreInsertionPoint(crtPos); } diff --git a/flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 b/flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 index 0a45967ce82ef..6cca57a2504e2 100644 --- a/flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 +++ b/flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 @@ -258,3 +258,61 @@ module acc_declare_allocatable_test ! ALL: acc.delete accPtr(%[[DEVICEPTR]] : !fir.ref>>>) {dataClause = #acc, name = "data1", structured = false} ! ALL: acc.terminator ! ALL: } + + +module acc_declare_equivalent + integer, parameter :: n = 10 + real :: v1(n) + real :: v2(n) + equivalence(v1(1), v2(1)) + !$acc declare create(v2) +end module + +! ALL-LABEL: acc.global_ctor @_QMacc_declare_equivalentEv2_acc_ctor { +! ALL-DAG: %[[C0:.*]] = arith.constant 0 : index +! ALL-DAG: %[[ADDR:.*]] = fir.address_of(@_QMacc_declare_equivalentEv1) : !fir.ref> +! ALL: %[[COORD:.*]] = fir.coordinate_of %[[ADDR]], %[[C0]] : (!fir.ref>, index) -> !fir.ref +! ALL: %[[CONV:.*]] = fir.convert %[[COORD]] {acc.declare = #acc.declare} : (!fir.ref) -> !fir.ptr> +! ALL: %[[CREATE:.*]] = acc.create varPtr(%[[CONV]] : !fir.ptr>) -> !fir.ptr> {name = "v2", structured = false} +! ALL: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ptr>) +! ALL: acc.terminator +! ALL: } + +! ALL-LABEL: acc.global_dtor @_QMacc_declare_equivalentEv2_acc_dtor { +! ALL-DAG: %[[C0:.*]] = arith.constant 0 : index +! ALL-DAG: %[[ADDR:.*]] = fir.address_of(@_QMacc_declare_equivalentEv1) : !fir.ref> +! ALL: %[[COORD:.*]] = fir.coordinate_of %[[ADDR]], %[[C0]] : (!fir.ref>, index) -> !fir.ref +! ALL: %[[CONV:.*]] = fir.convert %[[COORD]] {acc.declare = #acc.declare} : (!fir.ref) -> !fir.ptr> +! ALL: %[[DEVICEPTR:.*]] = acc.getdeviceptr varPtr(%[[CONV]] : !fir.ptr>) -> !fir.ptr> {dataClause = #acc, name = "v2", structured = false} +! ALL: acc.declare_exit dataOperands(%[[DEVICEPTR]] : !fir.ptr>) +! ALL: acc.delete accPtr(%[[DEVICEPTR]] : !fir.ptr>) {dataClause = #acc, name = "v2", structured = false} +! ALL: acc.terminator +! ALL: } + +module acc_declare_equivalent2 + real :: v1(10) + real :: v2(5) + equivalence(v1(6), v2(1)) + !$acc declare create(v2) +end module + +! ALL-LABEL: acc.global_ctor @_QMacc_declare_equivalent2Ev2_acc_ctor { +! ALL-DAG: %[[C20:.*]] = arith.constant 20 : index +! ALL-DAG: %[[ADDR:.*]] = fir.address_of(@_QMacc_declare_equivalent2Ev1) : !fir.ref> +! ALL: %[[COORD:.*]] = fir.coordinate_of %[[ADDR]], %[[C20]] : (!fir.ref>, index) -> !fir.ref +! ALL: %[[CONV:.*]] = fir.convert %[[COORD]] {acc.declare = #acc.declare} : (!fir.ref) -> !fir.ptr> +! ALL: %[[CREATE:.*]] = acc.create varPtr(%[[CONV]] : !fir.ptr>) -> !fir.ptr> {name = "v2", structured = false} +! ALL: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ptr>) +! ALL: acc.terminator +! ALL: } + +! ALL-LABEL: acc.global_dtor @_QMacc_declare_equivalent2Ev2_acc_dtor { +! ALL-DAG: %[[C20:.*]] = arith.constant 20 : index +! ALL-DAG: %[[ADDR:.*]] = fir.address_of(@_QMacc_declare_equivalent2Ev1) : !fir.ref> +! ALL: %[[COORD:.*]] = fir.coordinate_of %[[ADDR]], %[[C20]] : (!fir.ref>, index) -> !fir.ref +! ALL: %[[CONV:.*]] = fir.convert %[[COORD]] {acc.declare = #acc.declare} : (!fir.ref) -> !fir.ptr> +! ALL: %[[DEVICEPTR:.*]] = acc.getdeviceptr varPtr(%[[CONV]] : !fir.ptr>) -> !fir.ptr> {dataClause = #acc, name = "v2", structured = false} +! ALL: acc.declare_exit dataOperands(%[[DEVICEPTR]] : !fir.ptr>) +! ALL: acc.delete accPtr(%[[DEVICEPTR]] : !fir.ptr>) {dataClause = #acc, name = "v2", structured = false} +! ALL: acc.terminator +! ALL: } From 575fa003fd8563a7e49319e953ab87e67f8c55bc Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Mon, 6 Nov 2023 09:28:16 -0800 Subject: [PATCH 2/3] Use the equivalence address --- flang/lib/Lower/OpenACC.cpp | 37 ++++----------- .../test/Lower/OpenACC/HLFIR/acc-declare.f90 | 46 +++++++------------ 2 files changed, 26 insertions(+), 57 deletions(-) diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 7808e94ed7c73..080db63976eb9 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -2746,7 +2746,6 @@ createDeclareGlobalOp(mlir::OpBuilder &modBuilder, fir::FirOpBuilder &builder, mlir::Location loc, fir::GlobalOp globalOp, mlir::acc::DataClause clause, const std::string declareGlobalName, bool implicit, - std::optional &offset, mlir::Type aliasType, std::stringstream &asFortran) { GlobalOp declareGlobalOp = modBuilder.create(loc, declareGlobalName); @@ -2757,24 +2756,12 @@ createDeclareGlobalOp(mlir::OpBuilder &modBuilder, fir::FirOpBuilder &builder, fir::AddrOfOp addrOp = builder.create( loc, fir::ReferenceType::get(globalOp.getType()), globalOp.getSymbol()); - entryAddr = addrOp.getResTy(); - // If the variable in the declare clause is part of an equivalence it has an - // offset. - if (offset) { - mlir::Type i8Ptr = builder.getRefType(builder.getI8Type()); - mlir::Value off = - builder.createIntegerConstant(loc, builder.getIndexType(), *offset); - mlir::Value aliasAddr = builder.create( - loc, i8Ptr, addrOp.getResTy(), mlir::ValueRange{off}); - entryAddr = - builder.createConvert(loc, fir::PointerType::get(aliasType), aliasAddr); - } - addDeclareAttr(builder, entryAddr.getDefiningOp(), clause); + addDeclareAttr(builder, addrOp, clause); llvm::SmallVector bounds; EntryOp entryOp = createDataEntryOp( - builder, loc, entryAddr, asFortran, bounds, - /*structured=*/false, implicit, clause, entryAddr.getType()); + builder, loc, addrOp.getResTy(), asFortran, bounds, + /*structured=*/false, implicit, clause, addrOp.getResTy().getType()); builder.create(loc, mlir::ValueRange(entryOp.getAccPtr())); mlir::Value varPtr; if constexpr (std::is_same_v) { @@ -2916,9 +2903,6 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter, declareGlobalCtorName << globalName << "_acc_ctor"; std::stringstream declareGlobalDtorName; declareGlobalDtorName << globalName << "_acc_dtor"; - std::optional offset = std::nullopt; - mlir::Type aliasType; - std::stringstream asFortran; asFortran << name->symbol->name().ToString(); @@ -2936,9 +2920,6 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter, if (!globalOp) llvm::report_fatal_error( "could not retrieve global symbol"); - - offset = name->symbol->GetUltimate().offset(); - aliasType = converter.genType(name->symbol->GetUltimate()); } else { llvm::report_fatal_error( "could not retrieve global symbol"); @@ -2954,8 +2935,8 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter, mlir::acc::CopyinOp, mlir::acc::DeclareEnterOp, ExitOp>( modBuilder, builder, operandLocation, globalOp, clause, - declareGlobalCtorName.str(), /*implicit=*/true, offset, - aliasType, asFortran); + declareGlobalCtorName.str(), /*implicit=*/true, + asFortran); createDeclareAllocFunc( modBuilder, builder, operandLocation, globalOp, clause); if constexpr (!std::is_same_v) @@ -2965,16 +2946,16 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter, createDeclareGlobalOp( modBuilder, builder, operandLocation, globalOp, clause, - declareGlobalCtorName.str(), /*implicit=*/false, offset, - aliasType, asFortran); + declareGlobalCtorName.str(), /*implicit=*/false, + asFortran); } if constexpr (!std::is_same_v) { createDeclareGlobalOp( modBuilder, builder, operandLocation, globalOp, clause, - declareGlobalDtorName.str(), /*implicit=*/false, offset, - aliasType, asFortran); + declareGlobalDtorName.str(), /*implicit=*/false, + asFortran); } builder.restoreInsertionPoint(crtPos); } diff --git a/flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 b/flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 index 6cca57a2504e2..6ebdd39802fef 100644 --- a/flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 +++ b/flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 @@ -269,25 +269,19 @@ module acc_declare_equivalent end module ! ALL-LABEL: acc.global_ctor @_QMacc_declare_equivalentEv2_acc_ctor { -! ALL-DAG: %[[C0:.*]] = arith.constant 0 : index -! ALL-DAG: %[[ADDR:.*]] = fir.address_of(@_QMacc_declare_equivalentEv1) : !fir.ref> -! ALL: %[[COORD:.*]] = fir.coordinate_of %[[ADDR]], %[[C0]] : (!fir.ref>, index) -> !fir.ref -! ALL: %[[CONV:.*]] = fir.convert %[[COORD]] {acc.declare = #acc.declare} : (!fir.ref) -> !fir.ptr> -! ALL: %[[CREATE:.*]] = acc.create varPtr(%[[CONV]] : !fir.ptr>) -> !fir.ptr> {name = "v2", structured = false} -! ALL: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ptr>) +! ALL: %[[ADDR:.*]] = fir.address_of(@_QMacc_declare_equivalentEv1) {acc.declare = #acc.declare} : !fir.ref> +! ALL: %[[CREATE:.*]] = acc.create varPtr(%[[ADDR]] : !fir.ref>) -> !fir.ref> {name = "v2", structured = false} +! ALL: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ref>) ! ALL: acc.terminator ! ALL: } -! ALL-LABEL: acc.global_dtor @_QMacc_declare_equivalentEv2_acc_dtor { -! ALL-DAG: %[[C0:.*]] = arith.constant 0 : index -! ALL-DAG: %[[ADDR:.*]] = fir.address_of(@_QMacc_declare_equivalentEv1) : !fir.ref> -! ALL: %[[COORD:.*]] = fir.coordinate_of %[[ADDR]], %[[C0]] : (!fir.ref>, index) -> !fir.ref -! ALL: %[[CONV:.*]] = fir.convert %[[COORD]] {acc.declare = #acc.declare} : (!fir.ref) -> !fir.ptr> -! ALL: %[[DEVICEPTR:.*]] = acc.getdeviceptr varPtr(%[[CONV]] : !fir.ptr>) -> !fir.ptr> {dataClause = #acc, name = "v2", structured = false} -! ALL: acc.declare_exit dataOperands(%[[DEVICEPTR]] : !fir.ptr>) -! ALL: acc.delete accPtr(%[[DEVICEPTR]] : !fir.ptr>) {dataClause = #acc, name = "v2", structured = false} -! ALL: acc.terminator -! ALL: } +! ALL-LABEL: acc.global_dtor @_QMacc_declare_equivalentEv2_acc_dtor { +! ALL: %[[ADDR:.*]] = fir.address_of(@_QMacc_declare_equivalentEv1) {acc.declare = #acc.declare} : !fir.ref> +! ALL: %[[DEVICEPTR:.*]] = acc.getdeviceptr varPtr(%[[ADDR]] : !fir.ref>) -> !fir.ref> {dataClause = #acc, name = "v2", structured = false} +! ALL: acc.declare_exit dataOperands(%[[DEVICEPTR]] : !fir.ref>) +! ALL: acc.delete accPtr(%[[DEVICEPTR]] : !fir.ref>) {dataClause = #acc, name = "v2", structured = false} +! ALL: acc.terminator +! ALL: } module acc_declare_equivalent2 real :: v1(10) @@ -297,22 +291,16 @@ module acc_declare_equivalent2 end module ! ALL-LABEL: acc.global_ctor @_QMacc_declare_equivalent2Ev2_acc_ctor { -! ALL-DAG: %[[C20:.*]] = arith.constant 20 : index -! ALL-DAG: %[[ADDR:.*]] = fir.address_of(@_QMacc_declare_equivalent2Ev1) : !fir.ref> -! ALL: %[[COORD:.*]] = fir.coordinate_of %[[ADDR]], %[[C20]] : (!fir.ref>, index) -> !fir.ref -! ALL: %[[CONV:.*]] = fir.convert %[[COORD]] {acc.declare = #acc.declare} : (!fir.ref) -> !fir.ptr> -! ALL: %[[CREATE:.*]] = acc.create varPtr(%[[CONV]] : !fir.ptr>) -> !fir.ptr> {name = "v2", structured = false} -! ALL: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ptr>) +! ALL: %[[ADDR:.*]] = fir.address_of(@_QMacc_declare_equivalent2Ev1) {acc.declare = #acc.declare} : !fir.ref> +! ALL: %[[CREATE:.*]] = acc.create varPtr(%[[ADDR]] : !fir.ref>) -> !fir.ref> {name = "v2", structured = false} +! ALL: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ref>) ! ALL: acc.terminator ! ALL: } ! ALL-LABEL: acc.global_dtor @_QMacc_declare_equivalent2Ev2_acc_dtor { -! ALL-DAG: %[[C20:.*]] = arith.constant 20 : index -! ALL-DAG: %[[ADDR:.*]] = fir.address_of(@_QMacc_declare_equivalent2Ev1) : !fir.ref> -! ALL: %[[COORD:.*]] = fir.coordinate_of %[[ADDR]], %[[C20]] : (!fir.ref>, index) -> !fir.ref -! ALL: %[[CONV:.*]] = fir.convert %[[COORD]] {acc.declare = #acc.declare} : (!fir.ref) -> !fir.ptr> -! ALL: %[[DEVICEPTR:.*]] = acc.getdeviceptr varPtr(%[[CONV]] : !fir.ptr>) -> !fir.ptr> {dataClause = #acc, name = "v2", structured = false} -! ALL: acc.declare_exit dataOperands(%[[DEVICEPTR]] : !fir.ptr>) -! ALL: acc.delete accPtr(%[[DEVICEPTR]] : !fir.ptr>) {dataClause = #acc, name = "v2", structured = false} +! ALL: %[[ADDR:.*]] = fir.address_of(@_QMacc_declare_equivalent2Ev1) {acc.declare = #acc.declare} : !fir.ref> +! ALL: %[[DEVICEPTR:.*]] = acc.getdeviceptr varPtr(%[[ADDR]] : !fir.ref>) -> !fir.ref> {dataClause = #acc, name = "v2", structured = false} +! ALL: acc.declare_exit dataOperands(%[[DEVICEPTR]] : !fir.ref>) +! ALL: acc.delete accPtr(%[[DEVICEPTR]] : !fir.ref>) {dataClause = #acc, name = "v2", structured = false} ! ALL: acc.terminator ! ALL: } From 5710d50c0228bca410279e93e2aed1efde388306 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Mon, 6 Nov 2023 09:40:50 -0800 Subject: [PATCH 3/3] clang-format --- flang/lib/Lower/OpenACC.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 080db63976eb9..875db135d15ad 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -2741,12 +2741,12 @@ static void genACC(Fortran::lower::AbstractConverter &converter, template -static void -createDeclareGlobalOp(mlir::OpBuilder &modBuilder, fir::FirOpBuilder &builder, - mlir::Location loc, fir::GlobalOp globalOp, - mlir::acc::DataClause clause, - const std::string declareGlobalName, bool implicit, - std::stringstream &asFortran) { +static void createDeclareGlobalOp(mlir::OpBuilder &modBuilder, + fir::FirOpBuilder &builder, + mlir::Location loc, fir::GlobalOp globalOp, + mlir::acc::DataClause clause, + const std::string declareGlobalName, + bool implicit, std::stringstream &asFortran) { GlobalOp declareGlobalOp = modBuilder.create(loc, declareGlobalName); builder.createBlock(&declareGlobalOp.getRegion(),