@@ -2366,6 +2366,23 @@ static void processDoLoopBounds(
23662366 }
23672367}
23682368
2369+ static void remapCommonBlockMember (
2370+ Fortran::lower::AbstractConverter &converter, mlir::Location loc,
2371+ const Fortran::semantics::Symbol &member,
2372+ mlir::Value newCommonBlockBaseAddress,
2373+ const Fortran::semantics::Symbol &commonBlockSymbol,
2374+ llvm::SmallPtrSetImpl<const Fortran::semantics::Symbol *> &seenSymbols) {
2375+ if (seenSymbols.contains (&member))
2376+ return ;
2377+ mlir::Value accMemberValue = Fortran::lower::genCommonBlockMember (
2378+ converter, loc, member, newCommonBlockBaseAddress,
2379+ commonBlockSymbol.size ());
2380+ fir::ExtendedValue hostExv = converter.getSymbolExtendedValue (member);
2381+ fir::ExtendedValue accExv = fir::substBase (hostExv, accMemberValue);
2382+ converter.bindSymbol (member, accExv);
2383+ seenSymbols.insert (&member);
2384+ }
2385+
23692386// / Remap symbols that appeared in OpenACC data clauses to use the results of
23702387// / the corresponding data operations. This allows isolating symbol accesses
23712388// / inside the OpenACC region from accesses in the host and other regions while
@@ -2391,14 +2408,39 @@ static void remapDataOperandSymbols(
23912408 builder.setInsertionPointToStart (®ionOp.getRegion ().front ());
23922409 llvm::SmallPtrSet<const Fortran::semantics::Symbol *, 8 > seenSymbols;
23932410 mlir::IRMapping mapper;
2411+ mlir::Location loc = regionOp.getLoc ();
23942412 for (auto [value, symbol] : dataOperandSymbolPairs) {
2395-
2396- // If A symbol appears on several data clause, just map it to the first
2413+ // If a symbol appears on several data clause, just map it to the first
23972414 // result (all data operations results for a symbol are pointing same
23982415 // memory, so it does not matter which one is used).
23992416 if (seenSymbols.contains (&symbol.get ()))
24002417 continue ;
24012418 seenSymbols.insert (&symbol.get ());
2419+ // When a common block appears in a directive, remap its members.
2420+ // Note: this will instantiate all common block members even if they are not
2421+ // used inside the region. If hlfir.declare DCE is not made possible, this
2422+ // could be improved to reduce IR noise.
2423+ if (const auto *commonBlock = symbol->template detailsIf <
2424+ Fortran::semantics::CommonBlockDetails>()) {
2425+ const Fortran::semantics::Scope &commonScope = symbol->owner ();
2426+ if (commonScope.equivalenceSets ().empty ()) {
2427+ for (auto member : commonBlock->objects ())
2428+ remapCommonBlockMember (converter, loc, *member, value, *symbol,
2429+ seenSymbols);
2430+ } else {
2431+ // Objects equivalenced with common block members still belong to the
2432+ // common block storage even if they are not part of the common block
2433+ // declaration. The easiest and most robust way to find all symbols
2434+ // belonging to the common block is to loop through the scope symbols
2435+ // and check if they belong to the common.
2436+ for (const auto &scopeSymbol : commonScope)
2437+ if (Fortran::semantics::FindCommonBlockContaining (
2438+ *scopeSymbol.second ) == &symbol.get ())
2439+ remapCommonBlockMember (converter, loc, *scopeSymbol.second , value,
2440+ *symbol, seenSymbols);
2441+ }
2442+ continue ;
2443+ }
24022444 std::optional<fir::FortranVariableOpInterface> hostDef =
24032445 symbolMap.lookupVariableDefinition (symbol);
24042446 assert (hostDef.has_value () && llvm::isa<hlfir::DeclareOp>(*hostDef) &&
@@ -2415,10 +2457,8 @@ static void remapDataOperandSymbols(
24152457 " box type mismatch between compute region variable and "
24162458 " hlfir.declare input unexpected" );
24172459 if (Fortran::semantics::IsOptional (symbol))
2418- TODO (regionOp.getLoc (),
2419- " remapping OPTIONAL symbol in OpenACC compute region" );
2420- auto rawValue =
2421- fir::BoxAddrOp::create (builder, regionOp.getLoc (), hostType, value);
2460+ TODO (loc, " remapping OPTIONAL symbol in OpenACC compute region" );
2461+ auto rawValue = fir::BoxAddrOp::create (builder, loc, hostType, value);
24222462 mapper.map (hostInput, rawValue);
24232463 } else {
24242464 assert (!llvm::isa<fir::BaseBoxType>(hostType) &&
@@ -2430,8 +2470,7 @@ static void remapDataOperandSymbols(
24302470 assert (fir::isa_ref_type (hostType) && fir::isa_ref_type (computeType) &&
24312471 " compute region variable and host variable should both be raw "
24322472 " addresses" );
2433- mlir::Value cast =
2434- builder.createConvert (regionOp.getLoc (), hostType, value);
2473+ mlir::Value cast = builder.createConvert (loc, hostType, value);
24352474 mapper.map (hostInput, cast);
24362475 }
24372476 if (mlir::Value dummyScope = hostDeclare.getDummyScope ()) {
0 commit comments