3636#include " llvm/Frontend/OpenACC/ACC.h.inc"
3737#include " llvm/Support/CommandLine.h"
3838#include " llvm/Support/Debug.h"
39+ #include " llvm/Support/ErrorHandling.h"
3940#include " mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
4041#include " mlir/IR/MLIRContext.h"
4142#include " mlir/Support/LLVM.h"
@@ -4140,6 +4141,14 @@ static void attachRoutineInfo(mlir::func::FuncOp func,
41404141 mlir::acc::RoutineInfoAttr::get (func.getContext (), routines));
41414142}
41424143
4144+ static mlir::ArrayAttr getArrayAttrOrNull (fir::FirOpBuilder &builder, llvm::SmallVector<mlir::Attribute> &attributes) {
4145+ if (attributes.empty ()) {
4146+ return nullptr ;
4147+ } else {
4148+ return builder.getArrayAttr (attributes);
4149+ }
4150+ }
4151+
41434152void createOpenACCRoutineConstruct (
41444153 Fortran::lower::AbstractConverter &converter, mlir::Location loc,
41454154 mlir::ModuleOp mod, mlir::func::FuncOp funcOp, std::string funcName,
@@ -4173,31 +4182,29 @@ void createOpenACCRoutineConstruct(
41734182 fir::FirOpBuilder &builder = converter.getFirOpBuilder ();
41744183 modBuilder.create <mlir::acc::RoutineOp>(
41754184 loc, routineOpStr, funcName,
4176- bindNames.empty () ? nullptr : builder.getArrayAttr (bindNames),
4177- bindNameDeviceTypes.empty () ? nullptr
4178- : builder.getArrayAttr (bindNameDeviceTypes),
4179- workerDeviceTypes.empty () ? nullptr
4180- : builder.getArrayAttr (workerDeviceTypes),
4181- vectorDeviceTypes.empty () ? nullptr
4182- : builder.getArrayAttr (vectorDeviceTypes),
4183- seqDeviceTypes.empty () ? nullptr : builder.getArrayAttr (seqDeviceTypes),
4185+ getArrayAttrOrNull (builder, bindNames),
4186+ getArrayAttrOrNull (builder, bindNameDeviceTypes),
4187+ getArrayAttrOrNull (builder, workerDeviceTypes),
4188+ getArrayAttrOrNull (builder, vectorDeviceTypes),
4189+ getArrayAttrOrNull (builder, seqDeviceTypes),
41844190 hasNohost, /* implicit=*/ false ,
4185- gangDeviceTypes.empty () ? nullptr : builder.getArrayAttr (gangDeviceTypes),
4186- gangDimValues.empty () ? nullptr : builder.getArrayAttr (gangDimValues),
4187- gangDimDeviceTypes.empty () ? nullptr
4188- : builder.getArrayAttr (gangDimDeviceTypes));
4189-
4190- if (funcOp)
4191- attachRoutineInfo (funcOp, builder.getSymbolRefAttr (routineOpStr));
4192- else
4191+ getArrayAttrOrNull (builder, gangDeviceTypes),
4192+ getArrayAttrOrNull (builder, gangDimValues),
4193+ getArrayAttrOrNull (builder, gangDimDeviceTypes));
4194+
4195+ auto symbolRefAttr = builder.getSymbolRefAttr (routineOpStr);
4196+ if (funcOp) {
4197+
4198+ attachRoutineInfo (funcOp, symbolRefAttr);
4199+ } else {
41934200 // FuncOp is not lowered yet. Keep the information so the routine info
41944201 // can be attached later to the funcOp.
4195- converter.getAccDelayedRoutines ().push_back (
4196- std::make_pair (funcName, builder. getSymbolRefAttr (routineOpStr)));
4202+ converter.getAccDelayedRoutines ().push_back (std::make_pair (funcName, symbolRefAttr));
4203+ }
41974204}
41984205
41994206static void interpretRoutineDeviceInfo (
4200- fir::FirOpBuilder &builder ,
4207+ Fortran::lower::AbstractConverter &converter ,
42014208 const Fortran::semantics::OpenACCRoutineDeviceTypeInfo &dinfo,
42024209 llvm::SmallVector<mlir::Attribute> &seqDeviceTypes,
42034210 llvm::SmallVector<mlir::Attribute> &vectorDeviceTypes,
@@ -4207,23 +4214,24 @@ static void interpretRoutineDeviceInfo(
42074214 llvm::SmallVector<mlir::Attribute> &gangDeviceTypes,
42084215 llvm::SmallVector<mlir::Attribute> &gangDimValues,
42094216 llvm::SmallVector<mlir::Attribute> &gangDimDeviceTypes) {
4210- mlir::MLIRContext *context{builder.getContext ()};
4217+ fir::FirOpBuilder &builder = converter.getFirOpBuilder ();
4218+ auto getDeviceTypeAttr = [&]() -> mlir::Attribute {
4219+ auto context = builder.getContext ();
4220+ auto value = getDeviceType (dinfo.dType ());
4221+ return mlir::acc::DeviceTypeAttr::get (context, value );
4222+ };
42114223 if (dinfo.isSeq ()) {
4212- seqDeviceTypes.push_back (
4213- mlir::acc::DeviceTypeAttr::get (context, getDeviceType (dinfo.dType ())));
4224+ seqDeviceTypes.push_back (getDeviceTypeAttr ());
42144225 }
42154226 if (dinfo.isVector ()) {
4216- vectorDeviceTypes.push_back (
4217- mlir::acc::DeviceTypeAttr::get (context, getDeviceType (dinfo.dType ())));
4227+ vectorDeviceTypes.push_back (getDeviceTypeAttr ());
42184228 }
42194229 if (dinfo.isWorker ()) {
4220- workerDeviceTypes.push_back (
4221- mlir::acc::DeviceTypeAttr::get (context, getDeviceType (dinfo.dType ())));
4230+ workerDeviceTypes.push_back (getDeviceTypeAttr ());
42224231 }
42234232 if (dinfo.isGang ()) {
42244233 unsigned gangDim = dinfo.gangDim ();
4225- auto deviceType =
4226- mlir::acc::DeviceTypeAttr::get (context, getDeviceType (dinfo.dType ()));
4234+ auto deviceType = getDeviceTypeAttr ();
42274235 if (!gangDim) {
42284236 gangDeviceTypes.push_back (deviceType);
42294237 } else {
@@ -4232,10 +4240,18 @@ static void interpretRoutineDeviceInfo(
42324240 gangDimDeviceTypes.push_back (deviceType);
42334241 }
42344242 }
4235- if (const std::string *bindName{dinfo.bindName ()}) {
4236- bindNames.push_back (builder.getStringAttr (*bindName));
4237- bindNameDeviceTypes.push_back (
4238- mlir::acc::DeviceTypeAttr::get (context, getDeviceType (dinfo.dType ())));
4243+ if (dinfo.bindNameOpt ().has_value ()) {
4244+ const auto &bindName = dinfo.bindNameOpt ().value ();
4245+ mlir::Attribute bindNameAttr;
4246+ if (const auto &bindStr{std::get_if<std::string>(&bindName)}) {
4247+ bindNameAttr = builder.getStringAttr (*bindStr);
4248+ } else if (const auto &bindSym{std::get_if<Fortran::semantics::SymbolRef>(&bindName)}) {
4249+ bindNameAttr = builder.getStringAttr (converter.mangleName (*bindSym));
4250+ } else {
4251+ llvm_unreachable (" Unsupported bind name type" );
4252+ }
4253+ bindNames.push_back (bindNameAttr);
4254+ bindNameDeviceTypes.push_back (getDeviceTypeAttr ());
42394255 }
42404256}
42414257
@@ -4244,7 +4260,6 @@ void Fortran::lower::genOpenACCRoutineConstruct(
42444260 mlir::func::FuncOp funcOp,
42454261 const std::vector<Fortran::semantics::OpenACCRoutineInfo> &routineInfos) {
42464262 CHECK (funcOp && " Expected a valid function operation" );
4247- fir::FirOpBuilder &builder{converter.getFirOpBuilder ()};
42484263 mlir::Location loc{funcOp.getLoc ()};
42494264 std::string funcName{funcOp.getName ()};
42504265
@@ -4262,7 +4277,7 @@ void Fortran::lower::genOpenACCRoutineConstruct(
42624277 }
42634278 // Note: Device Independent Attributes are set to the
42644279 // none device type in `info`.
4265- interpretRoutineDeviceInfo (builder , info, seqDeviceTypes, vectorDeviceTypes,
4280+ interpretRoutineDeviceInfo (converter , info, seqDeviceTypes, vectorDeviceTypes,
42664281 workerDeviceTypes, bindNameDeviceTypes,
42674282 bindNames, gangDeviceTypes, gangDimValues,
42684283 gangDimDeviceTypes);
@@ -4271,7 +4286,7 @@ void Fortran::lower::genOpenACCRoutineConstruct(
42714286 for (const Fortran::semantics::OpenACCRoutineDeviceTypeInfo &dinfo :
42724287 info.deviceTypeInfos ()) {
42734288 interpretRoutineDeviceInfo (
4274- builder , dinfo, seqDeviceTypes, vectorDeviceTypes, workerDeviceTypes,
4289+ converter , dinfo, seqDeviceTypes, vectorDeviceTypes, workerDeviceTypes,
42754290 bindNameDeviceTypes, bindNames, gangDeviceTypes, gangDimValues,
42764291 gangDimDeviceTypes);
42774292 }
@@ -4369,8 +4384,6 @@ void Fortran::lower::genOpenACCRoutineConstruct(
43694384 std::get_if<Fortran::parser::AccClause::Bind>(&clause.u )) {
43704385 if (const auto *name =
43714386 std::get_if<Fortran::parser::Name>(&bindClause->v .u )) {
4372- // FIXME: This case mangles the name, the one below does not.
4373- // which is correct?
43744387 mlir::Attribute bindNameAttr =
43754388 builder.getStringAttr (converter.mangleName (*name->symbol ));
43764389 for (auto crtDeviceTypeAttr : crtDeviceTypes) {
0 commit comments