diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index ac1a1c00eb145..a11a2c824bf9e 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -2281,8 +2281,8 @@ static Op createComputeOp( mlir::Value selfCond; llvm::SmallVector waitOperands, attachEntryOperands, copyEntryOperands, copyinEntryOperands, copyoutEntryOperands, - createEntryOperands, dataClauseOperands, numGangs, numWorkers, - vectorLength, async; + createEntryOperands, nocreateEntryOperands, presentEntryOperands, + dataClauseOperands, numGangs, numWorkers, vectorLength, async; llvm::SmallVector numGangsDeviceTypes, numWorkersDeviceTypes, vectorLengthDeviceTypes, asyncDeviceTypes, asyncOnlyDeviceTypes, waitOperandsDeviceTypes, waitOnlyDeviceTypes; @@ -2457,19 +2457,25 @@ static Op createComputeOp( } else if (const auto *noCreateClause = std::get_if( &clause.u)) { + auto crtDataStart = dataClauseOperands.size(); genDataOperandOperations( noCreateClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_no_create, /*structured=*/true, /*implicit=*/false, async, asyncDeviceTypes, asyncOnlyDeviceTypes); + nocreateEntryOperands.append(dataClauseOperands.begin() + crtDataStart, + dataClauseOperands.end()); } else if (const auto *presentClause = std::get_if( &clause.u)) { + auto crtDataStart = dataClauseOperands.size(); genDataOperandOperations( presentClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_present, /*structured=*/true, /*implicit=*/false, async, asyncDeviceTypes, asyncOnlyDeviceTypes); + presentEntryOperands.append(dataClauseOperands.begin() + crtDataStart, + dataClauseOperands.end()); } else if (const auto *devicePtrClause = std::get_if( &clause.u)) { @@ -2634,6 +2640,10 @@ static Op createComputeOp( builder, attachEntryOperands, /*structured=*/true); genDataExitOperations( builder, createEntryOperands, /*structured=*/true); + genDataExitOperations( + builder, nocreateEntryOperands, /*structured=*/true); + genDataExitOperations( + builder, presentEntryOperands, /*structured=*/true); builder.restoreInsertionPoint(insPt); return computeOp; @@ -2648,7 +2658,8 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter, mlir::Value ifCond; llvm::SmallVector attachEntryOperands, createEntryOperands, copyEntryOperands, copyinEntryOperands, copyoutEntryOperands, - dataClauseOperands, waitOperands, async; + nocreateEntryOperands, presentEntryOperands, dataClauseOperands, + waitOperands, async; llvm::SmallVector asyncDeviceTypes, asyncOnlyDeviceTypes, waitOperandsDeviceTypes, waitOnlyDeviceTypes; llvm::SmallVector waitOperandsSegments; @@ -2745,19 +2756,25 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter, } else if (const auto *noCreateClause = std::get_if( &clause.u)) { + auto crtDataStart = dataClauseOperands.size(); genDataOperandOperations( noCreateClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_no_create, /*structured=*/true, /*implicit=*/false, async, asyncDeviceTypes, asyncOnlyDeviceTypes); + nocreateEntryOperands.append(dataClauseOperands.begin() + crtDataStart, + dataClauseOperands.end()); } else if (const auto *presentClause = std::get_if( &clause.u)) { + auto crtDataStart = dataClauseOperands.size(); genDataOperandOperations( presentClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_present, /*structured=*/true, /*implicit=*/false, async, asyncDeviceTypes, asyncOnlyDeviceTypes); + presentEntryOperands.append(dataClauseOperands.begin() + crtDataStart, + dataClauseOperands.end()); } else if (const auto *deviceptrClause = std::get_if( &clause.u)) { @@ -2837,6 +2854,10 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter, builder, attachEntryOperands, /*structured=*/true); genDataExitOperations( builder, createEntryOperands, /*structured=*/true); + genDataExitOperations( + builder, nocreateEntryOperands, /*structured=*/true); + genDataExitOperations( + builder, presentEntryOperands, /*structured=*/true); builder.restoreInsertionPoint(insPt); } @@ -3814,7 +3835,7 @@ genDeclareInFunction(Fortran::lower::AbstractConverter &converter, const Fortran::parser::AccClauseList &accClauseList) { llvm::SmallVector dataClauseOperands, copyEntryOperands, copyinEntryOperands, createEntryOperands, copyoutEntryOperands, - deviceResidentEntryOperands; + presentEntryOperands, deviceResidentEntryOperands; Fortran::lower::StatementContext stmtCtx; fir::FirOpBuilder &builder = converter.getFirOpBuilder(); @@ -3845,11 +3866,14 @@ genDeclareInFunction(Fortran::lower::AbstractConverter &converter, } else if (const auto *presentClause = std::get_if( &clause.u)) { + auto crtDataStart = dataClauseOperands.size(); genDeclareDataOperandOperations( + mlir::acc::DeleteOp>( presentClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_present, /*structured=*/true, /*implicit=*/false); + presentEntryOperands.append(dataClauseOperands.begin() + crtDataStart, + dataClauseOperands.end()); } else if (const auto *copyinClause = std::get_if(&clause.u)) { auto crtDataStart = dataClauseOperands.size(); @@ -3928,14 +3952,15 @@ genDeclareInFunction(Fortran::lower::AbstractConverter &converter, openAccCtx.attachCleanup([&builder, loc, createEntryOperands, copyEntryOperands, copyinEntryOperands, - copyoutEntryOperands, deviceResidentEntryOperands, - declareToken]() { + copyoutEntryOperands, presentEntryOperands, + deviceResidentEntryOperands, declareToken]() { llvm::SmallVector operands; operands.append(createEntryOperands); operands.append(deviceResidentEntryOperands); operands.append(copyEntryOperands); operands.append(copyinEntryOperands); operands.append(copyoutEntryOperands); + operands.append(presentEntryOperands); mlir::func::FuncOp funcOp = builder.getFunction(); auto ops = funcOp.getOps(); @@ -3957,6 +3982,8 @@ genDeclareInFunction(Fortran::lower::AbstractConverter &converter, builder, copyinEntryOperands, /*structured=*/true); genDataExitOperations( builder, copyoutEntryOperands, /*structured=*/true); + genDataExitOperations( + builder, presentEntryOperands, /*structured=*/true); }); } diff --git a/flang/test/Lower/OpenACC/acc-declare-unwrap-defaultbounds.f90 b/flang/test/Lower/OpenACC/acc-declare-unwrap-defaultbounds.f90 index 0b7c8664abd9f..065033431137d 100644 --- a/flang/test/Lower/OpenACC/acc-declare-unwrap-defaultbounds.f90 +++ b/flang/test/Lower/OpenACC/acc-declare-unwrap-defaultbounds.f90 @@ -65,8 +65,10 @@ subroutine acc_declare_present(a) ! CHECK-DAG: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) dummy_scope %{{[0-9]+}} {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_presentEa"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.ref>, !fir.ref>) ! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%[[C1]] : index) ! CHECK: %[[PRESENT:.*]] = acc.present varPtr(%[[DECL]]#0 : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} -! CHECK: acc.declare_enter dataOperands(%[[PRESENT]] : !fir.ref>) +! CHECK: %[[TOKEN:.*]] = acc.declare_enter dataOperands(%[[PRESENT]] : !fir.ref>) ! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) +! CHECK: acc.declare_exit token(%[[TOKEN]]) dataOperands(%[[PRESENT]] : !fir.ref>) +! CHECK: acc.delete accPtr(%[[PRESENT]] : !fir.ref>) bounds(%[[BOUND]]) {dataClause = #acc, name = "a"} subroutine acc_declare_copyin() integer :: a(100), b(10), i diff --git a/flang/test/Lower/OpenACC/acc-declare.f90 b/flang/test/Lower/OpenACC/acc-declare.f90 index 9f03bc3c2b481..8727c0722e474 100644 --- a/flang/test/Lower/OpenACC/acc-declare.f90 +++ b/flang/test/Lower/OpenACC/acc-declare.f90 @@ -59,8 +59,10 @@ subroutine acc_declare_present(a) ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "a"}) ! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) dummy_scope %{{[0-9]+}} {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_presentEa"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.ref>, !fir.ref>) ! CHECK: %[[PRESENT:.*]] = acc.present varPtr(%[[DECL]]#0 : !fir.ref>) -> !fir.ref> {name = "a"} -! CHECK: acc.declare_enter dataOperands(%[[PRESENT]] : !fir.ref>) +! CHECK: %[[TOKEN:.*]] = acc.declare_enter dataOperands(%[[PRESENT]] : !fir.ref>) ! CHECK: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) +! CHECK: acc.declare_exit token(%[[TOKEN]]) dataOperands(%[[PRESENT]] : !fir.ref>) +! CHECK: acc.delete accPtr(%[[PRESENT]] : !fir.ref>) {dataClause = #acc, name = "a"} subroutine acc_declare_copyin() integer :: a(100), b(10), i diff --git a/flang/test/Lower/OpenACC/acc-kernels-loop.f90 b/flang/test/Lower/OpenACC/acc-kernels-loop.f90 index 182b512f3931e..aa5d65afd57ec 100644 --- a/flang/test/Lower/OpenACC/acc-kernels-loop.f90 +++ b/flang/test/Lower/OpenACC/acc-kernels-loop.f90 @@ -393,6 +393,8 @@ subroutine acc_kernels_loop ! CHECK-NEXT: }{{$}} ! CHECK: acc.terminator ! CHECK-NEXT: }{{$}} +! CHECK: acc.delete accPtr(%[[NOCREATE_A]] : !fir.ref>) {dataClause = #acc, name = "a"} +! CHECK: acc.delete accPtr(%[[NOCREATE_B]] : !fir.ref>) {dataClause = #acc, name = "b"} !$acc kernels loop present(a, b) DO i = 1, n @@ -407,6 +409,8 @@ subroutine acc_kernels_loop ! CHECK-NEXT: }{{$}} ! CHECK: acc.terminator ! CHECK-NEXT: }{{$}} +! CHECK: acc.delete accPtr(%[[PRESENT_A]] : !fir.ref>) {dataClause = #acc, name = "a"} +! CHECK: acc.delete accPtr(%[[PRESENT_B]] : !fir.ref>) {dataClause = #acc, name = "b"} !$acc kernels loop deviceptr(a) deviceptr(b) DO i = 1, n diff --git a/flang/test/Lower/OpenACC/acc-kernels.f90 b/flang/test/Lower/OpenACC/acc-kernels.f90 index f25a9d411098b..b333bb981a79b 100644 --- a/flang/test/Lower/OpenACC/acc-kernels.f90 +++ b/flang/test/Lower/OpenACC/acc-kernels.f90 @@ -253,6 +253,9 @@ subroutine acc_kernels ! CHECK: acc.kernels dataOperands(%[[NO_CREATE_A]], %[[NO_CREATE_B]], %[[CREATE_C]] : !fir.ref>, !fir.ref>, !fir.ref>) { ! CHECK: acc.terminator ! CHECK-NEXT: }{{$}} +! CHECK: acc.delete accPtr(%[[CREATE_C]] : !fir.ref>) {dataClause = #acc, name = "c"} +! CHECK: acc.delete accPtr(%[[NO_CREATE_A]] : !fir.ref>) {dataClause = #acc, name = "a"} +! CHECK: acc.delete accPtr(%[[NO_CREATE_B]] : !fir.ref>) {dataClause = #acc, name = "b"} !$acc kernels present(a, b, c) !$acc end kernels @@ -263,6 +266,9 @@ subroutine acc_kernels ! CHECK: acc.kernels dataOperands(%[[PRESENT_A]], %[[PRESENT_B]], %[[PRESENT_C]] : !fir.ref>, !fir.ref>, !fir.ref>) { ! CHECK: acc.terminator ! CHECK-NEXT: }{{$}} +! CHECK: acc.delete accPtr(%[[PRESENT_A]] : !fir.ref>) {dataClause = #acc, name = "a"} +! CHECK: acc.delete accPtr(%[[PRESENT_B]] : !fir.ref>) {dataClause = #acc, name = "b"} +! CHECK: acc.delete accPtr(%[[PRESENT_C]] : !fir.ref>) {dataClause = #acc, name = "c"} !$acc kernels deviceptr(a) deviceptr(c) !$acc end kernels diff --git a/flang/test/Lower/OpenACC/acc-parallel-loop.f90 b/flang/test/Lower/OpenACC/acc-parallel-loop.f90 index 6f4409eaf5600..7a41da320b955 100644 --- a/flang/test/Lower/OpenACC/acc-parallel-loop.f90 +++ b/flang/test/Lower/OpenACC/acc-parallel-loop.f90 @@ -393,6 +393,8 @@ subroutine acc_parallel_loop ! CHECK-NEXT: }{{$}} ! CHECK: acc.yield ! CHECK-NEXT: }{{$}} +! CHECK: acc.delete accPtr(%[[NOCREATE_A]] : !fir.ref>) {dataClause = #acc, name = "a"} +! CHECK: acc.delete accPtr(%[[NOCREATE_B]] : !fir.ref>) {dataClause = #acc, name = "b"} !$acc parallel loop present(a, b) DO i = 1, n @@ -407,6 +409,8 @@ subroutine acc_parallel_loop ! CHECK-NEXT: }{{$}} ! CHECK: acc.yield ! CHECK-NEXT: }{{$}} +! CHECK: acc.delete accPtr(%[[PRESENT_A]] : !fir.ref>) {dataClause = #acc, name = "a"} +! CHECK: acc.delete accPtr(%[[PRESENT_B]] : !fir.ref>) {dataClause = #acc, name = "b"} !$acc parallel loop deviceptr(a) deviceptr(b) DO i = 1, n diff --git a/flang/test/Lower/OpenACC/acc-parallel.f90 b/flang/test/Lower/OpenACC/acc-parallel.f90 index 7a51be21e914d..e16c1b218878c 100644 --- a/flang/test/Lower/OpenACC/acc-parallel.f90 +++ b/flang/test/Lower/OpenACC/acc-parallel.f90 @@ -291,7 +291,8 @@ subroutine acc_parallel ! CHECK: acc.yield ! CHECK-NEXT: }{{$}} ! CHECK: acc.delete accPtr(%[[CREATE_C]] : !fir.ref>) {dataClause = #acc, name = "c"} - +! CHECK: acc.delete accPtr(%[[NO_CREATE_A]] : !fir.ref>) {dataClause = #acc, name = "a"} +! CHECK: acc.delete accPtr(%[[NO_CREATE_B]] : !fir.ref>) {dataClause = #acc, name = "b"} !$acc parallel present(a, b, c) !$acc end parallel @@ -302,6 +303,9 @@ subroutine acc_parallel ! CHECK: acc.parallel dataOperands(%[[PRESENT_A]], %[[PRESENT_B]], %[[PRESENT_C]] : !fir.ref>, !fir.ref>, !fir.ref>) { ! CHECK: acc.yield ! CHECK-NEXT: }{{$}} +! CHECK: acc.delete accPtr(%[[PRESENT_A]] : !fir.ref>) {dataClause = #acc, name = "a"} +! CHECK: acc.delete accPtr(%[[PRESENT_B]] : !fir.ref>) {dataClause = #acc, name = "b"} +! CHECK: acc.delete accPtr(%[[PRESENT_C]] : !fir.ref>) {dataClause = #acc, name = "c"} !$acc parallel deviceptr(a) deviceptr(c) !$acc end parallel diff --git a/flang/test/Lower/OpenACC/acc-serial-loop.f90 b/flang/test/Lower/OpenACC/acc-serial-loop.f90 index 66cde19ef09af..a94f0e8e8583e 100644 --- a/flang/test/Lower/OpenACC/acc-serial-loop.f90 +++ b/flang/test/Lower/OpenACC/acc-serial-loop.f90 @@ -334,6 +334,8 @@ subroutine acc_serial_loop ! CHECK-NEXT: }{{$}} ! CHECK: acc.yield ! CHECK-NEXT: }{{$}} +! CHECK: acc.delete accPtr(%[[NOCREATE_A]] : !fir.ref>) {dataClause = #acc, name = "a"} +! CHECK: acc.delete accPtr(%[[NOCREATE_B]] : !fir.ref>) {dataClause = #acc, name = "b"} !$acc serial loop present(a, b) DO i = 1, n @@ -348,6 +350,8 @@ subroutine acc_serial_loop ! CHECK-NEXT: }{{$}} ! CHECK: acc.yield ! CHECK-NEXT: }{{$}} +! CHECK: acc.delete accPtr(%[[PRESENT_A]] : !fir.ref>) {dataClause = #acc, name = "a"} +! CHECK: acc.delete accPtr(%[[PRESENT_B]] : !fir.ref>) {dataClause = #acc, name = "b"} !$acc serial loop deviceptr(a) deviceptr(b) DO i = 1, n diff --git a/flang/test/Lower/OpenACC/acc-serial.f90 b/flang/test/Lower/OpenACC/acc-serial.f90 index 88b801a82ee68..f2f73876af877 100644 --- a/flang/test/Lower/OpenACC/acc-serial.f90 +++ b/flang/test/Lower/OpenACC/acc-serial.f90 @@ -227,6 +227,9 @@ subroutine acc_serial ! CHECK: acc.serial dataOperands(%[[NO_CREATE_A]], %[[NO_CREATE_B]], %[[CREATE_C]] : !fir.ref>, !fir.ref>, !fir.ref>) { ! CHECK: acc.yield ! CHECK-NEXT: }{{$}} +! CHECK: acc.delete accPtr(%[[CREATE_C]] : !fir.ref>) {dataClause = #acc, name = "c"} +! CHECK: acc.delete accPtr(%[[NO_CREATE_A]] : !fir.ref>) {dataClause = #acc, name = "a"} +! CHECK: acc.delete accPtr(%[[NO_CREATE_B]] : !fir.ref>) {dataClause = #acc, name = "b"} !$acc serial present(a, b, c) !$acc end serial @@ -237,6 +240,9 @@ subroutine acc_serial ! CHECK: acc.serial dataOperands(%[[PRESENT_A]], %[[PRESENT_B]], %[[PRESENT_C]] : !fir.ref>, !fir.ref>, !fir.ref>) { ! CHECK: acc.yield ! CHECK-NEXT: }{{$}} +! CHECK: acc.delete accPtr(%[[PRESENT_A]] : !fir.ref>) {dataClause = #acc, name = "a"} +! CHECK: acc.delete accPtr(%[[PRESENT_B]] : !fir.ref>) {dataClause = #acc, name = "b"} +! CHECK: acc.delete accPtr(%[[PRESENT_C]] : !fir.ref>) {dataClause = #acc, name = "c"} !$acc serial deviceptr(a) deviceptr(c) !$acc end serial diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp index aaa3db22110ac..8f150cb33e6f3 100644 --- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp +++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp @@ -580,6 +580,7 @@ LogicalResult acc::DeleteOp::verify() { getDataClause() != acc::DataClause::acc_copyin && getDataClause() != acc::DataClause::acc_copyin_readonly && getDataClause() != acc::DataClause::acc_present && + getDataClause() != acc::DataClause::acc_no_create && getDataClause() != acc::DataClause::acc_declare_device_resident && getDataClause() != acc::DataClause::acc_declare_link) return emitError(