@@ -4058,6 +4058,66 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter,
40584058 const Fortran::parser::AccObjectList &accObjectList,
40594059 mlir::acc::DataClause clause) {
40604060 fir::FirOpBuilder &builder = converter.getFirOpBuilder ();
4061+ auto genCtors = [&](const mlir::Location operandLocation,
4062+ const Fortran::semantics::Symbol &symbol) {
4063+ std::string globalName = converter.mangleName (symbol);
4064+ fir::GlobalOp globalOp = builder.getNamedGlobal (globalName);
4065+ std::stringstream declareGlobalCtorName;
4066+ declareGlobalCtorName << globalName << " _acc_ctor" ;
4067+ std::stringstream declareGlobalDtorName;
4068+ declareGlobalDtorName << globalName << " _acc_dtor" ;
4069+ std::stringstream asFortran;
4070+ asFortran << symbol.name ().ToString ();
4071+
4072+ if (builder.getModule ().lookupSymbol <mlir::acc::GlobalConstructorOp>(
4073+ declareGlobalCtorName.str ()))
4074+ return ;
4075+
4076+ if (!globalOp) {
4077+ if (Fortran::semantics::FindEquivalenceSet (symbol)) {
4078+ for (Fortran::semantics::EquivalenceObject eqObj :
4079+ *Fortran::semantics::FindEquivalenceSet (symbol)) {
4080+ std::string eqName = converter.mangleName (eqObj.symbol );
4081+ globalOp = builder.getNamedGlobal (eqName);
4082+ if (globalOp)
4083+ break ;
4084+ }
4085+
4086+ if (!globalOp)
4087+ llvm::report_fatal_error (" could not retrieve global symbol" );
4088+ } else {
4089+ llvm::report_fatal_error (" could not retrieve global symbol" );
4090+ }
4091+ }
4092+
4093+ addDeclareAttr (builder, globalOp.getOperation (), clause);
4094+ auto crtPos = builder.saveInsertionPoint ();
4095+ modBuilder.setInsertionPointAfter (globalOp);
4096+ if (mlir::isa<fir::BaseBoxType>(fir::unwrapRefType (globalOp.getType ()))) {
4097+ createDeclareGlobalOp<mlir::acc::GlobalConstructorOp, mlir::acc::CopyinOp,
4098+ mlir::acc::DeclareEnterOp, ExitOp>(
4099+ modBuilder, builder, operandLocation, globalOp, clause,
4100+ declareGlobalCtorName.str (), /* implicit=*/ true , asFortran);
4101+ createDeclareAllocFunc<EntryOp>(modBuilder, builder, operandLocation,
4102+ globalOp, clause);
4103+ if constexpr (!std::is_same_v<EntryOp, ExitOp>)
4104+ createDeclareDeallocFunc<ExitOp>(modBuilder, builder, operandLocation,
4105+ globalOp, clause);
4106+ } else {
4107+ createDeclareGlobalOp<mlir::acc::GlobalConstructorOp, EntryOp,
4108+ mlir::acc::DeclareEnterOp, ExitOp>(
4109+ modBuilder, builder, operandLocation, globalOp, clause,
4110+ declareGlobalCtorName.str (), /* implicit=*/ false , asFortran);
4111+ }
4112+ if constexpr (!std::is_same_v<EntryOp, ExitOp>) {
4113+ createDeclareGlobalOp<mlir::acc::GlobalDestructorOp,
4114+ mlir::acc::GetDevicePtrOp, mlir::acc::DeclareExitOp,
4115+ ExitOp>(
4116+ modBuilder, builder, operandLocation, globalOp, clause,
4117+ declareGlobalDtorName.str (), /* implicit=*/ false , asFortran);
4118+ }
4119+ builder.restoreInsertionPoint (crtPos);
4120+ };
40614121 for (const auto &accObject : accObjectList.v ) {
40624122 mlir::Location operandLocation = genOperandLocation (converter, accObject);
40634123 Fortran::common::visit (
@@ -4066,76 +4126,20 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter,
40664126 if (const auto *name =
40674127 Fortran::semantics::getDesignatorNameIfDataRef (
40684128 designator)) {
4069- std::string globalName = converter.mangleName (*name->symbol );
4070- fir::GlobalOp globalOp = builder.getNamedGlobal (globalName);
4071- std::stringstream declareGlobalCtorName;
4072- declareGlobalCtorName << globalName << " _acc_ctor" ;
4073- std::stringstream declareGlobalDtorName;
4074- declareGlobalDtorName << globalName << " _acc_dtor" ;
4075- std::stringstream asFortran;
4076- asFortran << name->symbol ->name ().ToString ();
4077-
4078- if (builder.getModule ()
4079- .lookupSymbol <mlir::acc::GlobalConstructorOp>(
4080- declareGlobalCtorName.str ()))
4081- return ;
4082-
4083- if (!globalOp) {
4084- if (Fortran::semantics::FindEquivalenceSet (*name->symbol )) {
4085- for (Fortran::semantics::EquivalenceObject eqObj :
4086- *Fortran::semantics::FindEquivalenceSet (
4087- *name->symbol )) {
4088- std::string eqName = converter.mangleName (eqObj.symbol );
4089- globalOp = builder.getNamedGlobal (eqName);
4090- if (globalOp)
4091- break ;
4092- }
4093-
4094- if (!globalOp)
4095- llvm::report_fatal_error (
4096- " could not retrieve global symbol" );
4097- } else {
4098- llvm::report_fatal_error (
4099- " could not retrieve global symbol" );
4100- }
4101- }
4102-
4103- addDeclareAttr (builder, globalOp.getOperation (), clause);
4104- auto crtPos = builder.saveInsertionPoint ();
4105- modBuilder.setInsertionPointAfter (globalOp);
4106- if (mlir::isa<fir::BaseBoxType>(
4107- fir::unwrapRefType (globalOp.getType ()))) {
4108- createDeclareGlobalOp<mlir::acc::GlobalConstructorOp,
4109- mlir::acc::CopyinOp,
4110- mlir::acc::DeclareEnterOp, ExitOp>(
4111- modBuilder, builder, operandLocation, globalOp, clause,
4112- declareGlobalCtorName.str (), /* implicit=*/ true ,
4113- asFortran);
4114- createDeclareAllocFunc<EntryOp>(
4115- modBuilder, builder, operandLocation, globalOp, clause);
4116- if constexpr (!std::is_same_v<EntryOp, ExitOp>)
4117- createDeclareDeallocFunc<ExitOp>(
4118- modBuilder, builder, operandLocation, globalOp, clause);
4119- } else {
4120- createDeclareGlobalOp<mlir::acc::GlobalConstructorOp, EntryOp,
4121- mlir::acc::DeclareEnterOp, ExitOp>(
4122- modBuilder, builder, operandLocation, globalOp, clause,
4123- declareGlobalCtorName.str (), /* implicit=*/ false ,
4124- asFortran);
4125- }
4126- if constexpr (!std::is_same_v<EntryOp, ExitOp>) {
4127- createDeclareGlobalOp<mlir::acc::GlobalDestructorOp,
4128- mlir::acc::GetDevicePtrOp,
4129- mlir::acc::DeclareExitOp, ExitOp>(
4130- modBuilder, builder, operandLocation, globalOp, clause,
4131- declareGlobalDtorName.str (), /* implicit=*/ false ,
4132- asFortran);
4133- }
4134- builder.restoreInsertionPoint (crtPos);
4129+ genCtors (operandLocation, *name->symbol );
41354130 }
41364131 },
41374132 [&](const Fortran::parser::Name &name) {
4138- TODO (operandLocation, " OpenACC Global Ctor from parser::Name" );
4133+ if (const auto *symbol = name.symbol ) {
4134+ if (const auto *commonBlockDetails =
4135+ symbol->detailsIf <
4136+ Fortran::semantics::CommonBlockDetails>()) {
4137+ genCtors (operandLocation, *symbol);
4138+ } else {
4139+ TODO (operandLocation,
4140+ " OpenACC Global Ctor from parser::Name" );
4141+ }
4142+ }
41394143 }},
41404144 accObject.u );
41414145 }
0 commit comments