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 @@ -2346,6 +2346,40 @@ modBuilder.setInsertionPointAfter(declareGlobalOp); } +template +static void createRegisterFunc(mlir::OpBuilder &modBuilder, + fir::FirOpBuilder &builder, mlir::Location loc, + fir::GlobalOp &globalOp, + mlir::acc::DataClause clause) { + std::stringstream registerFuncName; + registerFuncName << globalOp.getSymName().str() << "_acc_register"; + auto funcTy = mlir::FunctionType::get(modBuilder.getContext(), {}, {}); + mlir::func::FuncOp registerFuncOp = modBuilder.create( + loc, registerFuncName.str(), funcTy); + registerFuncOp.setVisibility(mlir::SymbolTable::Visibility::Private); + + builder.createBlock(®isterFuncOp.getRegion(), + registerFuncOp.getRegion().end(), {}, {}); + builder.setInsertionPointToEnd(®isterFuncOp.getRegion().back()); + + fir::AddrOfOp addrOp = builder.create( + loc, fir::ReferenceType::get(globalOp.getType()), globalOp.getSymbol()); + auto loadOp = builder.create(loc, addrOp.getResult()); + fir::BoxAddrOp boxAddrOp = builder.create(loc, loadOp); + addDeclareAttr(builder, boxAddrOp.getOperation(), clause); + + std::stringstream asFortran; + asFortran << Fortran::lower::mangle::demangleName(globalOp.getSymName()); + llvm::SmallVector bounds; + EntryOp entryOp = createDataEntryOp( + builder, loc, boxAddrOp.getResult(), asFortran, bounds, + /*structured=*/false, /*implicit=*/false, clause, boxAddrOp.getType()); + builder.create( + loc, mlir::ValueRange(entryOp.getAccPtr())); + builder.create(loc); + modBuilder.setInsertionPointAfter(registerFuncOp); +} + template static void genGlobalCtors(Fortran::lower::AbstractConverter &converter, mlir::OpBuilder &modBuilder, @@ -2374,6 +2408,8 @@ mlir::acc::DeclareEnterOp, ExitOp>( modBuilder, builder, operandLocation, globalOp, clause, /*implicit=*/true); + createRegisterFunc( + modBuilder, builder, operandLocation, globalOp, clause); } else { createDeclareGlobalOp( 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 @@ -236,6 +236,15 @@ ! CHECK: acc.terminator ! CHECK: } +! CHECK-LABEL: func.func private @_QMacc_declare_allocatable_testEdata1_acc_register() { +! CHECK: %[[GLOBAL_ADDR:.*]] = fir.address_of(@_QMacc_declare_allocatable_testEdata1) : !fir.ref>>> +! CHECK: %[[LOAD:.*]] = fir.load %[[GLOBAL_ADDR]] : !fir.ref>>> +! CHECK: %[[BOXADDR:.*]] = fir.box_addr %[[LOAD]] {acc.declare = #acc.declare} : (!fir.box>>) -> !fir.heap> +! CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOXADDR]] : !fir.heap>) -> !fir.heap> {name = "data1", structured = false} +! CHECK: acc.declare_enter dataOperands(%[[CREATE]] : !fir.heap>) +! CHECK: return +! CHECK: } + ! CHECK-LABEL: acc.global_dtor @_QMacc_declare_allocatable_testEdata1_acc_dtor { ! CHECK: %[[GLOBAL_ADDR:.*]] = fir.address_of(@_QMacc_declare_allocatable_testEdata1) {acc.declare = #acc.declare} : !fir.ref>>> ! CHECK: %[[DEVICEPTR:.*]] = acc.getdeviceptr varPtr(%[[GLOBAL_ADDR]] : !fir.ref>>>) -> !fir.ref>>> {dataClause = #acc, name = "data1", structured = false}