@@ -2925,29 +2925,53 @@ GetConstExpr(Fortran::semantics::SemanticsContext &semanticsContext,
2925
2925
return std::nullopt;
2926
2926
}
2927
2927
2928
+ static void attachRoutineInfo (mlir::func::FuncOp func,
2929
+ mlir::SymbolRefAttr routineAttr) {
2930
+ llvm::SmallVector<mlir::SymbolRefAttr> routines;
2931
+ if (func.getOperation ()->hasAttr (mlir::acc::getRoutineInfoAttrName ())) {
2932
+ auto routineInfo =
2933
+ func.getOperation ()->getAttrOfType <mlir::acc::RoutineInfoAttr>(
2934
+ mlir::acc::getRoutineInfoAttrName ());
2935
+ routines.append (routineInfo.getAccRoutines ().begin (),
2936
+ routineInfo.getAccRoutines ().end ());
2937
+ }
2938
+ routines.push_back (routineAttr);
2939
+ func.getOperation ()->setAttr (
2940
+ mlir::acc::getRoutineInfoAttrName (),
2941
+ mlir::acc::RoutineInfoAttr::get (func.getContext (), routines));
2942
+ }
2943
+
2928
2944
static void
2929
2945
genACC (Fortran::lower::AbstractConverter &converter,
2930
2946
Fortran::semantics::SemanticsContext &semanticsContext,
2931
2947
Fortran::lower::pft::Evaluation &eval,
2932
- const Fortran::parser::OpenACCRoutineConstruct &routineConstruct) {
2948
+ const Fortran::parser::OpenACCRoutineConstruct &routineConstruct,
2949
+ Fortran::lower::AccRoutineInfoMappingList &accRoutineInfos) {
2933
2950
fir::FirOpBuilder &builder = converter.getFirOpBuilder ();
2934
2951
mlir::Location loc = converter.genLocation (routineConstruct.source );
2935
2952
std::optional<Fortran::parser::Name> name =
2936
2953
std::get<std::optional<Fortran::parser::Name>>(routineConstruct.t );
2937
2954
const auto &clauses =
2938
2955
std::get<Fortran::parser::AccClauseList>(routineConstruct.t );
2939
- if (name)
2940
- TODO (loc, " acc routine with name" );
2941
2956
2942
- mlir::func::FuncOp func = builder.getFunction ();
2943
2957
mlir::ModuleOp mod = builder.getModule ();
2958
+ mlir::func::FuncOp funcOp;
2959
+ std::string funcName;
2960
+ if (name) {
2961
+ funcName = converter.mangleName (*name->symbol );
2962
+ funcOp = builder.getNamedFunction (funcName);
2963
+ } else {
2964
+ funcOp = builder.getFunction ();
2965
+ funcName = funcOp.getName ();
2966
+ }
2967
+
2944
2968
mlir::OpBuilder modBuilder (mod.getBodyRegion ());
2945
2969
std::stringstream routineOpName;
2946
2970
routineOpName << accRoutinePrefix.str () << routineCounter++;
2947
2971
auto routineOp = modBuilder.create <mlir::acc::RoutineOp>(
2948
- loc, routineOpName.str (), func. getName () , mlir::StringAttr{},
2972
+ loc, routineOpName.str (), funcName , mlir::StringAttr{}, mlir::UnitAttr {},
2949
2973
mlir::UnitAttr{}, mlir::UnitAttr{}, mlir::UnitAttr{}, mlir::UnitAttr{},
2950
- mlir::UnitAttr{}, mlir::UnitAttr{}, mlir:: IntegerAttr{});
2974
+ mlir::UnitAttr{}, mlir::IntegerAttr{});
2951
2975
2952
2976
for (const Fortran::parser::AccClause &clause : clauses.v ) {
2953
2977
if (std::get_if<Fortran::parser::AccClause::Seq>(&clause.u )) {
@@ -2994,18 +3018,27 @@ genACC(Fortran::lower::AbstractConverter &converter,
2994
3018
}
2995
3019
}
2996
3020
2997
- llvm::SmallVector<mlir::SymbolRefAttr> routines;
2998
- if (func.getOperation ()->hasAttr (mlir::acc::getRoutineInfoAttrName ())) {
2999
- auto routineInfo =
3000
- func.getOperation ()->getAttrOfType <mlir::acc::RoutineInfoAttr>(
3001
- mlir::acc::getRoutineInfoAttrName ());
3002
- routines.append (routineInfo.getAccRoutines ().begin (),
3003
- routineInfo.getAccRoutines ().end ());
3021
+ if (funcOp)
3022
+ attachRoutineInfo (funcOp, builder.getSymbolRefAttr (routineOpName.str ()));
3023
+ else
3024
+ // FuncOp is not lowered yet. Keep the information so the routine info
3025
+ // can be attached later to the funcOp.
3026
+ accRoutineInfos.push_back (std::make_pair (
3027
+ funcName, builder.getSymbolRefAttr (routineOpName.str ())));
3028
+ }
3029
+
3030
+ void Fortran::lower::finalizeOpenACCRoutineAttachment (
3031
+ mlir::ModuleOp &mod,
3032
+ Fortran::lower::AccRoutineInfoMappingList &accRoutineInfos) {
3033
+ for (auto &mapping : accRoutineInfos) {
3034
+ mlir::func::FuncOp funcOp =
3035
+ mod.lookupSymbol <mlir::func::FuncOp>(mapping.first );
3036
+ if (!funcOp)
3037
+ llvm::report_fatal_error (
3038
+ " could not find function to attach OpenACC routine information." );
3039
+ attachRoutineInfo (funcOp, mapping.second );
3004
3040
}
3005
- routines.push_back (builder.getSymbolRefAttr (routineOpName.str ()));
3006
- func.getOperation ()->setAttr (
3007
- mlir::acc::getRoutineInfoAttrName (),
3008
- mlir::acc::RoutineInfoAttr::get (builder.getContext (), routines));
3041
+ accRoutineInfos.clear ();
3009
3042
}
3010
3043
3011
3044
void Fortran::lower::genOpenACCConstruct (
@@ -3050,7 +3083,8 @@ void Fortran::lower::genOpenACCDeclarativeConstruct(
3050
3083
Fortran::semantics::SemanticsContext &semanticsContext,
3051
3084
Fortran::lower::StatementContext &fctCtx,
3052
3085
Fortran::lower::pft::Evaluation &eval,
3053
- const Fortran::parser::OpenACCDeclarativeConstruct &accDeclConstruct) {
3086
+ const Fortran::parser::OpenACCDeclarativeConstruct &accDeclConstruct,
3087
+ Fortran::lower::AccRoutineInfoMappingList &accRoutineInfos) {
3054
3088
3055
3089
std::visit (
3056
3090
common::visitors{
@@ -3061,7 +3095,8 @@ void Fortran::lower::genOpenACCDeclarativeConstruct(
3061
3095
},
3062
3096
[&](const Fortran::parser::OpenACCRoutineConstruct
3063
3097
&routineConstruct) {
3064
- genACC (converter, semanticsContext, eval, routineConstruct);
3098
+ genACC (converter, semanticsContext, eval, routineConstruct,
3099
+ accRoutineInfos);
3065
3100
},
3066
3101
},
3067
3102
accDeclConstruct.u );
0 commit comments