diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -2248,13 +2248,11 @@ } void genFIR(const Fortran::parser::OpenACCDeclarativeConstruct &accDecl) { - mlir::OpBuilder::InsertPoint insertPt = builder->saveInsertionPoint(); genOpenACCDeclarativeConstruct(*this, bridge.getSemanticsContext(), bridge.fctCtx(), getEval(), accDecl, accRoutineInfos); for (Fortran::lower::pft::Evaluation &e : getEval().getNestedEvaluations()) genFIR(e); - builder->restoreInsertionPoint(insertPt); } void genFIR(const Fortran::parser::OpenMPConstruct &omp) { diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -2730,6 +2730,15 @@ createEntryOperands, copyoutEntryOperands, deviceResidentEntryOperands; Fortran::lower::StatementContext stmtCtx; fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + + mlir::acc::DeclareOp declareOp; + auto parentOp = builder.getBlock()->getParentOp(); + if (mlir::isa(parentOp)) { + declareOp = mlir::dyn_cast( + *builder.getBlock()->getParentOp()); + builder.setInsertionPoint(declareOp.getOperation()); + } + for (const Fortran::parser::AccClause &clause : accClauseList.v) { if (const auto *copyClause = std::get_if(&clause.u)) { @@ -2817,13 +2826,24 @@ TODO(clauseLocation, "clause on declare directive"); } } - builder.create(loc, dataClauseOperands); - // Attach declare exit operation generation to function context. - fctCtx.attachCleanup([&builder, loc, dataClauseOperands, createEntryOperands, + if (declareOp) { + declareOp.getDataClauseOperandsMutable().append(dataClauseOperands); + builder.setInsertionPointToEnd(&declareOp.getRegion().back()); + } else { + declareOp = builder.create(loc, dataClauseOperands); + builder.createBlock(&declareOp.getRegion(), declareOp.getRegion().end(), {}, + {}); + builder.setInsertionPointToEnd(&declareOp.getRegion().back()); + } + fctCtx.attachCleanup([&builder, declareOp, loc, createEntryOperands, copyEntryOperands, copyoutEntryOperands, deviceResidentEntryOperands]() { - builder.create(loc, dataClauseOperands); + auto parentOp = builder.getBlock()->getParentOp(); + if (mlir::isa(parentOp)) { + builder.create(loc); + builder.setInsertionPointAfter(declareOp); + } genDataExitOperations( builder, createEntryOperands, /*structured=*/true, /*implicit=*/false); diff --git a/flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 b/flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 --- a/flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 +++ b/flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 @@ -24,12 +24,11 @@ ! ALL: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index) ! FIR: %[[COPYIN:.*]] = acc.copyin varPtr(%[[DECL]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = #acc, name = "a"} ! HLFIR: %[[COPYIN:.*]] = acc.copyin varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = #acc, name = "a"} -! ALL: acc.declare_enter dataOperands(%[[COPYIN]] : !fir.ref>) +! ALL: acc.declare dataOperands(%[[COPYIN]] : !fir.ref>) ! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (index, i32) { ! ALL: } -! ALL: acc.declare_exit dataOperands(%[[COPYIN]] : !fir.ref>) ! FIR: acc.copyout accPtr(%[[COPYIN]] : !fir.ref>) bounds(%[[BOUND]]) to varPtr(%[[DECL]] : !fir.ref>) {dataClause = #acc, name = "a"} ! HLFIR: acc.copyout accPtr(%[[COPYIN]] : !fir.ref>) bounds(%[[BOUND]]) to varPtr(%[[DECL]]#1 : !fir.ref>) {dataClause = #acc, name = "a"} @@ -52,12 +51,11 @@ ! ALL: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index) ! FIR: %[[CREATE:.*]] = acc.create varPtr(%[[DECL]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} ! HLFIR: %[[CREATE:.*]] = acc.create varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} -! ALL: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ref>) +! ALL: acc.declare dataOperands(%[[CREATE]] : !fir.ref>) ! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (index, i32) { ! ALL: } -! ALL: acc.declare_exit dataOperands(%[[CREATE]] : !fir.ref>) ! ALL: acc.delete accPtr(%[[CREATE]] : !fir.ref>) bounds(%[[BOUND]]) {dataClause = #acc, name = "a"} ! ALL: return @@ -78,9 +76,8 @@ ! ALL: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%[[C1]] : index) ! FIR: %[[PRESENT:.*]] = acc.present varPtr(%[[DECL]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} ! HLFIR: %[[PRESENT:.*]] = acc.present varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} -! ALL: acc.declare_enter dataOperands(%[[PRESENT]] : !fir.ref>) +! ALL: acc.declare dataOperands(%[[PRESENT]] : !fir.ref>) ! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) -! ALL: acc.declare_exit dataOperands(%[[PRESENT]] : !fir.ref>) subroutine acc_declare_copyin() integer :: a(100), b(10), i @@ -104,9 +101,8 @@ ! ALL: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%{{.*}} : index) ! FIR: %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[BDECL]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = #acc, name = "b"} ! HLFIR: %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[BDECL]]#1 : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = #acc, name = "b"} -! ALL: acc.declare_enter dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref>, !fir.ref>) +! ALL: acc.declare dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref>, !fir.ref>) ! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) -! ALL: acc.declare_exit dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref>, !fir.ref>) subroutine acc_declare_copyout() integer :: a(100), i @@ -123,9 +119,9 @@ ! HLFIR: %[[ADECL:.*]]:2 = hlfir.declare %[[A]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_copyoutEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) ! FIR: %[[CREATE:.*]] = acc.create varPtr(%[[ADECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {dataClause = #acc, name = "a"} ! HLFIR: %[[CREATE:.*]] = acc.create varPtr(%[[ADECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {dataClause = #acc, name = "a"} -! ALL: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ref>) +! ALL: acc.declare dataOperands(%[[CREATE]] : !fir.ref>) ! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) -! ALL: acc.declare_exit dataOperands(%[[CREATE]] : !fir.ref>) + ! FIR: acc.copyout accPtr(%[[CREATE]] : !fir.ref>) bounds(%{{.*}}) to varPtr(%[[ADECL]] : !fir.ref>) {name = "a"} ! HLFIR: acc.copyout accPtr(%[[CREATE]] : !fir.ref>) bounds(%{{.*}}) to varPtr(%[[ADECL]]#1 : !fir.ref>) {name = "a"} ! ALL: return @@ -145,9 +141,8 @@ ! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_deviceptrEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) ! FIR: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[DECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} ! HLFIR: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} -! ALL: acc.declare_enter dataOperands(%[[DEVICEPTR]] : !fir.ref>) +! ALL: acc.declare dataOperands(%[[DEVICEPTR]] : !fir.ref>) ! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) -! ALL: acc.declare_exit dataOperands(%[[DEVICEPTR]] : !fir.ref>) subroutine acc_declare_link(a) integer :: a(100), i @@ -164,9 +159,8 @@ ! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_linkEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) ! FIR: %[[LINK:.*]] = acc.declare_link varPtr(%[[DECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} ! HLFIR: %[[LINK:.*]] = acc.declare_link varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} -! ALL: acc.declare_enter dataOperands(%[[LINK]] : !fir.ref>) +! ALL: acc.declare dataOperands(%[[LINK]] : !fir.ref>) ! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) -! ALL: acc.declare_exit dataOperands(%[[LINK]] : !fir.ref>) subroutine acc_declare_device_resident(a) integer :: a(100), i @@ -183,9 +177,9 @@ ! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_device_residentEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) ! FIR: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[DECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} ! HLFIR: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} -! ALL: acc.declare_enter dataOperands(%[[DEVICERES]] : !fir.ref>) +! ALL: acc.declare dataOperands(%[[DEVICERES]] : !fir.ref>) ! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) -! ALL: acc.declare_exit dataOperands(%[[DEVICERES]] : !fir.ref>) + ! ALL: acc.delete accPtr(%[[DEVICERES]] : !fir.ref>) bounds(%{{.*}}) {dataClause = #acc, name = "a"} subroutine acc_declare_device_resident2() @@ -200,8 +194,8 @@ ! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_device_resident2Edataparam"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) ! FIR: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[DECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} ! HLFIR: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} -! ALL: acc.declare_enter dataOperands(%[[DEVICERES]] : !fir.ref>) -! ALL: acc.declare_exit dataOperands(%[[DEVICERES]] : !fir.ref>) +! ALL: acc.declare dataOperands(%[[DEVICERES]] : !fir.ref>) + ! ALL: acc.delete accPtr(%[[DEVICERES]] : !fir.ref>) bounds(%{{.*}}) {dataClause = #acc, name = "dataparam"} subroutine acc_declare_link2() @@ -216,7 +210,7 @@ ! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_link2Edataparam"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) ! FIR: %[[LINK:.*]] = acc.declare_link varPtr(%[[DECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} ! HLFIR: %[[LINK:.*]] = acc.declare_link varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} -! ALL: acc.declare_enter dataOperands(%[[LINK]] : !fir.ref>) +! ALL: acc.declare dataOperands(%[[LINK]] : !fir.ref>) subroutine acc_declare_deviceptr2() integer, parameter :: n = 100 @@ -230,7 +224,7 @@ ! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_deviceptr2Edataparam"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) ! FIR: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[DECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} ! HLFIR: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} -! ALL: acc.declare_enter dataOperands(%[[DEVICEPTR]] : !fir.ref>) +! ALL: acc.declare dataOperands(%[[DEVICEPTR]] : !fir.ref>) end module diff --git a/flang/test/Lower/OpenACC/acc-declare.f90 b/flang/test/Lower/OpenACC/acc-declare.f90 --- a/flang/test/Lower/OpenACC/acc-declare.f90 +++ b/flang/test/Lower/OpenACC/acc-declare.f90 @@ -19,12 +19,11 @@ ! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xi32> {acc.declare = #acc.declare, bindc_name = "a", uniq_name = "_QMacc_declareFacc_declare_copyEa"} ! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1 : index) startIdx(%c1 : index) ! CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[ALLOCA]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = #acc, name = "a"} -! CHECK: acc.declare_enter dataOperands(%[[COPYIN]] : !fir.ref>) - +! CHECK: acc.declare dataOperands(%[[COPYIN]] : !fir.ref>) { ! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (index, i32) { ! CHECK: } - -! CHECK: acc.declare_exit dataOperands(%[[COPYIN]] : !fir.ref>) +! CHECK: acc.terminator +! CHECK: } ! CHECK: acc.copyout accPtr(%[[COPYIN]] : !fir.ref>) bounds(%[[BOUND]]) to varPtr(%[[ALLOCA]] : !fir.ref>) {dataClause = #acc, name = "a"} ! CHECK: return @@ -43,12 +42,11 @@ ! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xi32> {acc.declare = #acc.declare, bindc_name = "a", uniq_name = "_QMacc_declareFacc_declare_createEa"} ! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1 : index) startIdx(%c1 : index) ! CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[ALLOCA]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} -! CHECK: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ref>) - +! CHECK: acc.declare dataOperands(%[[CREATE]] : !fir.ref>) ! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (index, i32) { ! CHECK: } - -! CHECK: acc.declare_exit dataOperands(%[[CREATE]] : !fir.ref>) +! CHECK: acc.terminator +! CHECK: } ! CHECK: acc.delete accPtr(%[[CREATE]] : !fir.ref>) bounds(%[[BOUND]]) {dataClause = #acc, name = "a"} ! CHECK: return @@ -65,9 +63,11 @@ ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "a"}) ! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%c1 : index) ! CHECK: %[[PRESENT:.*]] = acc.present varPtr(%[[ARG0]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} -! CHECK: acc.declare_enter dataOperands(%[[PRESENT]] : !fir.ref>) +! CHECK: acc.declare dataOperands(%[[PRESENT]] : !fir.ref>) { ! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) -! CHECK: acc.declare_exit dataOperands(%[[PRESENT]] : !fir.ref>) +! CHECK: acc.terminator +! CHECK: } +! CHECK: return subroutine acc_declare_copyin() integer :: a(100), b(10), i @@ -85,9 +85,11 @@ ! CHECK: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[A]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} ! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%{{.*}} : index) ! CHECK: %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[B]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = #acc, name = "b"} -! CHECK: acc.declare_enter dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref>, !fir.ref>) +! CHECK: acc.declare dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref>, !fir.ref>) { ! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) -! CHECK: acc.declare_exit dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref>, !fir.ref>) +! CHECK: acc.terminator +! CHECK: } +! CHECK: return subroutine acc_declare_copyout() integer :: a(100), i @@ -101,9 +103,10 @@ ! CHECK-LABEL: func.func @_QMacc_declarePacc_declare_copyout() ! CHECK: %[[A:.*]] = fir.alloca !fir.array<100xi32> {acc.declare = #acc.declare, bindc_name = "a", uniq_name = "_QMacc_declareFacc_declare_copyoutEa"} ! CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[A]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {dataClause = #acc, name = "a"} -! CHECK: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ref>) +! CHECK: acc.declare dataOperands(%[[CREATE]] : !fir.ref>) { ! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) -! CHECK: acc.declare_exit dataOperands(%[[CREATE]] : !fir.ref>) +! CHECK: acc.terminator +! CHECK: } ! CHECK: acc.copyout accPtr(%[[CREATE]] : !fir.ref>) bounds(%{{.*}}) to varPtr(%[[A]] : !fir.ref>) {name = "a"} ! CHECK: return @@ -119,9 +122,11 @@ ! CHECK-LABEL: func.func @_QMacc_declarePacc_declare_deviceptr( ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "a"}) { ! CHECK: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[ARG0]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} -! CHECK: acc.declare_enter dataOperands(%[[DEVICEPTR]] : !fir.ref>) +! CHECK: acc.declare dataOperands(%[[DEVICEPTR]] : !fir.ref>) ! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) -! CHECK: acc.declare_exit dataOperands(%[[DEVICEPTR]] : !fir.ref>) +! CHECK: acc.terminator +! CHECK: } +! CHECK: return subroutine acc_declare_link(a) integer :: a(100), i @@ -135,9 +140,11 @@ ! CHECK-LABEL: func.func @_QMacc_declarePacc_declare_link( ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "a"}) ! CHECK: %[[LINK:.*]] = acc.declare_link varPtr(%[[ARG0]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} -! CHECK: acc.declare_enter dataOperands(%[[LINK]] : !fir.ref>) +! CHECK: acc.declare dataOperands(%[[LINK]] : !fir.ref>) { ! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) -! CHECK: acc.declare_exit dataOperands(%[[LINK]] : !fir.ref>) +! CHECK: acc.terminator +! CHECK: } +! CHECK: return subroutine acc_declare_device_resident(a) integer :: a(100), i @@ -151,10 +158,12 @@ ! CHECK-LABEL: func.func @_QMacc_declarePacc_declare_device_resident( ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "a"}) ! CHECK: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[ARG0]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} -! CHECK: acc.declare_enter dataOperands(%[[DEVICERES]] : !fir.ref>) +! CHECK: acc.declare dataOperands(%[[DEVICERES]] : !fir.ref>) { ! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) -! CHECK: acc.declare_exit dataOperands(%[[DEVICERES]] : !fir.ref>) +! CHECK: acc.terminator +! CHECK: } ! CHECK: acc.delete accPtr(%[[DEVICERES]] : !fir.ref>) bounds(%{{.*}}) {dataClause = #acc, name = "a"} +! CHECK: return subroutine acc_declare_device_resident2() integer, parameter :: n = 100 @@ -165,9 +174,11 @@ ! CHECK-LABEL: func.func @_QMacc_declarePacc_declare_device_resident2() ! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32> {acc.declare = #acc.declare, bindc_name = "dataparam", uniq_name = "_QMacc_declareFacc_declare_device_resident2Edataparam"} ! CHECK: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[ALLOCA]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} -! CHECK: acc.declare_enter dataOperands(%[[DEVICERES]] : !fir.ref>) -! CHECK: acc.declare_exit dataOperands(%[[DEVICERES]] : !fir.ref>) +! CHECK: acc.declare dataOperands(%[[DEVICERES]] : !fir.ref>) { +! CHECK: acc.terminator +! CHECK: } ! CHECK: acc.delete accPtr(%[[DEVICERES]] : !fir.ref>) bounds(%{{.*}}) {dataClause = #acc, name = "dataparam"} +! CHECK: return subroutine acc_declare_link2() integer, parameter :: n = 100 @@ -178,7 +189,10 @@ ! CHECK-LABEL: func.func @_QMacc_declarePacc_declare_link2() ! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32> {acc.declare = #acc.declare, bindc_name = "dataparam", uniq_name = "_QMacc_declareFacc_declare_link2Edataparam"} ! CHECK: %[[LINK:.*]] = acc.declare_link varPtr(%[[ALLOCA]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} -! CHECK: acc.declare_enter dataOperands(%[[LINK]] : !fir.ref>) +! CHECK: acc.declare dataOperands(%[[LINK]] : !fir.ref>) { +! CHECK: acc.terminator +! CHECK: } +! CHECK: return subroutine acc_declare_deviceptr2() integer, parameter :: n = 100 @@ -189,7 +203,10 @@ ! CHECK-LABEL: func.func @_QMacc_declarePacc_declare_deviceptr2() ! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32> {acc.declare = #acc.declare, bindc_name = "dataparam", uniq_name = "_QMacc_declareFacc_declare_deviceptr2Edataparam"} ! CHECK: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[ALLOCA]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} -! CHECK: acc.declare_enter dataOperands(%[[DEVICEPTR]] : !fir.ref>) +! CHECK: acc.declare dataOperands(%[[DEVICEPTR]] : !fir.ref>) { +! CHECK: acc.terminator +! CHECK: } +! CHECK: return subroutine acc_declare_allocate() integer, allocatable :: a(:) @@ -239,6 +256,28 @@ ! CHECK: return ! CHECK: } + subroutine acc_declare_multiple_directive(a, b) + integer :: a(100), b(100), i + !$acc declare copy(a) + !$acc declare copyout(b) + + do i = 1, 100 + a(i) = i + end do + end subroutine + +! CHECK-LABEL: func.func @_QMacc_declarePacc_declare_multiple_directive( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref> {fir.bindc_name = "b"}) { +! CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[ARG0]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {dataClause = #acc, name = "a"} +! CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[ARG1]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {dataClause = #acc, name = "b"} +! CHECK: acc.declare dataOperands(%[[COPYIN]], %[[CREATE]] : !fir.ref>, !fir.ref>) { +! CHECK: %{{.*}}:{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (index, i32) { + +! CHECK: acc.terminator +! CHECK: } +! CHECK: acc.copyout accPtr(%[[CREATE]] : !fir.ref>) bounds(%{{.*}}) to varPtr(%[[ARG1]] : !fir.ref>) {name = "b"} +! CHECK: acc.copyout accPtr(%[[COPYIN]] : !fir.ref>) bounds(%{{.*}}) to varPtr(%[[ARG0]] : !fir.ref>) {dataClause = #acc, name = "a"} + end module module acc_declare_allocatable_test