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 @@ -31,6 +31,9 @@ // Special value for * passed in device_type or gang clauses. static constexpr std::int64_t starCst = -1; +static unsigned routineCounter = 0; +static constexpr llvm::StringRef accRoutinePrefix = "acc_routine_"; + /// Generate the acc.bounds operation from the descriptor information. static llvm::SmallVector genBoundsOpsFromBox(fir::FirOpBuilder &builder, mlir::Location loc, @@ -2721,6 +2724,32 @@ llvm_unreachable("unsupported declarative directive"); } +static void +genACC(Fortran::lower::AbstractConverter &converter, + Fortran::lower::pft::Evaluation &eval, + const Fortran::parser::OpenACCRoutineConstruct &routineConstruct) { + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + mlir::Location loc = converter.genLocation(routineConstruct.source); + std::optional name = + std::get>(routineConstruct.t); + const auto &clauses = + std::get(routineConstruct.t); + if (name) + TODO(loc, "acc routine with name"); + if (!clauses.v.empty()) + TODO(loc, "acc routine with clauses"); + + mlir::func::FuncOp func = builder.getFunction(); + mlir::ModuleOp mod = builder.getModule(); + mlir::OpBuilder modBuilder(mod.getBodyRegion()); + std::stringstream routineOpName; + routineOpName << accRoutinePrefix.str() << routineCounter++; + modBuilder.create( + loc, routineOpName.str(), func.getName(), mlir::StringAttr{}, + mlir::UnitAttr{}, mlir::UnitAttr{}, mlir::UnitAttr{}, mlir::UnitAttr{}, + mlir::UnitAttr{}, mlir::UnitAttr{}, mlir::IntegerAttr{}); +} + void Fortran::lower::genOpenACCConstruct( Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semanticsContext, @@ -2774,8 +2803,7 @@ }, [&](const Fortran::parser::OpenACCRoutineConstruct &routineConstruct) { - TODO(converter.genLocation(routineConstruct.source), - "OpenACC Routine construct not lowered yet!"); + genACC(converter, eval, routineConstruct); }, }, accDeclConstruct.u); diff --git a/flang/test/Lower/OpenACC/Todo/acc-routine.f90 b/flang/test/Lower/OpenACC/Todo/acc-routine.f90 deleted file mode 100644 --- a/flang/test/Lower/OpenACC/Todo/acc-routine.f90 +++ /dev/null @@ -1,12 +0,0 @@ -! This test checks lowering of OpenACC routine Directive. - -// RUN: not flang-new -fc1 -emit-fir -fopenacc %s 2>&1 | FileCheck %s - -program main - // CHECK: not yet implemented: OpenACC Routine construct not lowered yet! - !$acc routine(sub) seq -contains - subroutine sub(a) - real :: a(:) - end -end diff --git a/flang/test/Lower/OpenACC/acc-routine.f90 b/flang/test/Lower/OpenACC/acc-routine.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Lower/OpenACC/acc-routine.f90 @@ -0,0 +1,10 @@ +! This test checks lowering of OpenACC routine directive. + +! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s + +subroutine acc_routine1() + !$acc routine +end subroutine + +! CHECK: acc.routine @acc_routine_0 func(@_QPacc_routine1) +! CHECK-LABEL: func.func @_QPacc_routine1()