Skip to content

Commit 0298b81

Browse files
committed
Emit declare_mapper to .mod file. Update test to check separate module and program file compilation.
1 parent a8f1613 commit 0298b81

File tree

9 files changed

+129
-25
lines changed

9 files changed

+129
-25
lines changed

flang/include/flang/Lower/OpenMP.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ bool markOpenMPDeferredDeclareTargetFunctions(
9797
AbstractConverter &);
9898
void genOpenMPRequires(mlir::Operation *, const Fortran::semantics::Symbol *);
9999

100+
// Materialize omp.declare_mapper ops for mapper declarations found in
101+
// imported modules. If \p scope is null, materialize for the whole
102+
// semantics global scope; otherwise, operate recursively starting at \p scope.
103+
void materializeOpenMPDeclareMappers(
104+
Fortran::lower::AbstractConverter &, Fortran::semantics::SemanticsContext &,
105+
const Fortran::semantics::Scope *scope = nullptr);
106+
100107
} // namespace lower
101108
} // namespace Fortran
102109

flang/include/flang/Semantics/symbol.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -777,14 +777,32 @@ class UserReductionDetails {
777777
DeclVector declList_;
778778
};
779779

780+
// Used for OpenMP DECLARE MAPPER, it holds the declaration constructs
781+
// so they can be serialized into module files and later re-parsed when
782+
// USE-associated.
783+
class MapperDetails {
784+
public:
785+
using DeclVector = std::vector<const parser::OpenMPDeclarativeConstruct *>;
786+
787+
MapperDetails() = default;
788+
789+
void AddDecl(const parser::OpenMPDeclarativeConstruct *decl) {
790+
declList_.emplace_back(decl);
791+
}
792+
const DeclVector &GetDeclList() const { return declList_; }
793+
794+
private:
795+
DeclVector declList_;
796+
};
797+
780798
class UnknownDetails {};
781799

782800
using Details = std::variant<UnknownDetails, MainProgramDetails, ModuleDetails,
783801
SubprogramDetails, SubprogramNameDetails, EntityDetails,
784802
ObjectEntityDetails, ProcEntityDetails, AssocEntityDetails,
785803
DerivedTypeDetails, UseDetails, UseErrorDetails, HostAssocDetails,
786804
GenericDetails, ProcBindingDetails, NamelistDetails, CommonBlockDetails,
787-
TypeParamDetails, MiscDetails, UserReductionDetails>;
805+
TypeParamDetails, MiscDetails, UserReductionDetails, MapperDetails>;
788806
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Details &);
789807
std::string DetailsToString(const Details &);
790808

flang/lib/Lower/Bridge.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,13 @@ class FirConverter : public Fortran::lower::AbstractConverter {
447447
}
448448
});
449449

450+
// Ensure imported OpenMP declare mappers are materialized at module
451+
// scope before lowering any constructs that may reference them.
452+
createBuilderOutsideOfFuncOpAndDo([&]() {
453+
Fortran::lower::materializeOpenMPDeclareMappers(
454+
*this, bridge.getSemanticsContext());
455+
});
456+
450457
// Create definitions of intrinsic module constants.
451458
createBuilderOutsideOfFuncOpAndDo(
452459
[&]() { createIntrinsicModuleDefinitions(pft); });

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3553,10 +3553,10 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
35533553
TODO(converter.getCurrentLocation(), "OpenMPDeclareSimdConstruct");
35543554
}
35553555

3556-
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3557-
semantics::SemanticsContext &semaCtx,
3558-
lower::pft::Evaluation &eval,
3559-
const parser::OpenMPDeclareMapperConstruct &construct) {
3556+
static void genOpenMPDeclareMapperImpl(
3557+
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
3558+
const parser::OpenMPDeclareMapperConstruct &construct,
3559+
const semantics::Symbol *mapperSymOpt = nullptr) {
35603560
mlir::Location loc = converter.genLocation(construct.source);
35613561
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
35623562
const parser::OmpArgumentList &args = construct.v.Arguments();
@@ -3572,8 +3572,17 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
35723572
"Expected derived type");
35733573

35743574
std::string mapperNameStr = mapperName;
3575-
if (auto *sym = converter.getCurrentScope().FindSymbol(mapperNameStr))
3575+
if (mapperSymOpt && mapperNameStr != "default") {
3576+
mapperNameStr = converter.mangleName(mapperNameStr, mapperSymOpt->owner());
3577+
} else if (auto *sym =
3578+
converter.getCurrentScope().FindSymbol(mapperNameStr)) {
35763579
mapperNameStr = converter.mangleName(mapperNameStr, sym->owner());
3580+
}
3581+
3582+
// If the mapper op already exists (e.g., created by regular lowering),
3583+
// do not recreate it.
3584+
if (converter.getModuleOp().lookupSymbol(mapperNameStr))
3585+
return;
35773586

35783587
// Save current insertion point before moving to the module scope to create
35793588
// the DeclareMapperOp
@@ -3596,6 +3605,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
35963605
mlir::omp::DeclareMapperInfoOp::create(firOpBuilder, loc, clauseOps.mapVars);
35973606
}
35983607

3608+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3609+
semantics::SemanticsContext &semaCtx,
3610+
lower::pft::Evaluation &eval,
3611+
const parser::OpenMPDeclareMapperConstruct &construct) {
3612+
genOpenMPDeclareMapperImpl(converter, semaCtx, construct);
3613+
}
3614+
35993615
static void
36003616
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
36013617
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
@@ -4239,3 +4255,32 @@ void Fortran::lower::genOpenMPRequires(mlir::Operation *mod,
42394255
offloadMod.setRequires(mlirFlags);
42404256
}
42414257
}
4258+
4259+
// Walk scopes and materialize omp.declare_mapper ops for mapper declarations
4260+
// found in imported modules. If \p scope is null, start from the global scope.
4261+
void Fortran::lower::materializeOpenMPDeclareMappers(
4262+
Fortran::lower::AbstractConverter &converter,
4263+
semantics::SemanticsContext &semaCtx, const semantics::Scope *scope) {
4264+
const semantics::Scope &root = scope ? *scope : semaCtx.globalScope();
4265+
4266+
// Recurse into child scopes first (modules, submodules, etc.).
4267+
for (const semantics::Scope &child : root.children())
4268+
materializeOpenMPDeclareMappers(converter, semaCtx, &child);
4269+
4270+
// Only consider module scopes to avoid duplicating local constructs.
4271+
if (!root.IsModule())
4272+
return;
4273+
4274+
// Scan symbols in this module scope for MapperDetails.
4275+
for (auto &it : root) {
4276+
const semantics::Symbol &sym = *it.second;
4277+
if (auto *md = sym.detailsIf<semantics::MapperDetails>()) {
4278+
for (const auto *decl : md->GetDeclList()) {
4279+
if (const auto *mapperDecl =
4280+
std::get_if<parser::OpenMPDeclareMapperConstruct>(&decl->u)) {
4281+
genOpenMPDeclareMapperImpl(converter, semaCtx, *mapperDecl, &sym);
4282+
}
4283+
}
4284+
}
4285+
}
4286+
}

flang/lib/Semantics/mod-file.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ static void PutBound(llvm::raw_ostream &, const Bound &);
5959
static void PutShapeSpec(llvm::raw_ostream &, const ShapeSpec &);
6060
static void PutShape(
6161
llvm::raw_ostream &, const ArraySpec &, char open, char close);
62+
static void PutMapper(llvm::raw_ostream &, const Symbol &, SemanticsContext &);
6263

6364
static llvm::raw_ostream &PutAttr(llvm::raw_ostream &, Attr);
6465
static llvm::raw_ostream &PutType(llvm::raw_ostream &, const DeclTypeSpec &);
@@ -938,6 +939,7 @@ void ModFileWriter::PutEntity(llvm::raw_ostream &os, const Symbol &symbol) {
938939
[&](const ProcEntityDetails &) { PutProcEntity(os, symbol); },
939940
[&](const TypeParamDetails &) { PutTypeParam(os, symbol); },
940941
[&](const UserReductionDetails &) { PutUserReduction(os, symbol); },
942+
[&](const MapperDetails &) { PutMapper(decls_, symbol, context_); },
941943
[&](const auto &) {
942944
common::die("PutEntity: unexpected details: %s",
943945
DetailsToString(symbol.details()).c_str());
@@ -1098,6 +1100,16 @@ void ModFileWriter::PutUserReduction(
10981100
}
10991101
}
11001102

1103+
static void PutMapper(
1104+
llvm::raw_ostream &os, const Symbol &symbol, SemanticsContext &context) {
1105+
const auto &details{symbol.get<MapperDetails>()};
1106+
// Emit each saved DECLARE MAPPER construct as-is, so that consumers of the
1107+
// module can reparse it and recreate the mapper symbol and semantics state.
1108+
for (const auto *decl : details.GetDeclList()) {
1109+
Unparse(os, *decl, context.langOptions());
1110+
}
1111+
}
1112+
11011113
void PutInit(llvm::raw_ostream &os, const Symbol &symbol, const MaybeExpr &init,
11021114
const parser::Expr *unanalyzed, SemanticsContext &context) {
11031115
if (IsNamedConstant(symbol) || symbol.owner().IsDerivedType()) {

flang/lib/Semantics/resolve-names.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1824,8 +1824,10 @@ bool OmpVisitor::Pre(const parser::OmpMapClause &x) {
18241824
// TODO: Do we need a specific flag or type here, to distinghuish against
18251825
// other ConstructName things? Leaving this for the full implementation
18261826
// of mapper lowering.
1827-
auto *misc{symbol->GetUltimate().detailsIf<MiscDetails>()};
1828-
if (!misc || misc->kind() != MiscDetails::Kind::ConstructName)
1827+
auto &ultimate{symbol->GetUltimate()};
1828+
auto *misc{ultimate.detailsIf<MiscDetails>()};
1829+
auto *md{ultimate.detailsIf<MapperDetails>()};
1830+
if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
18291831
context().Say(mapper->v.source,
18301832
"Name '%s' should be a mapper name"_err_en_US, mapper->v.source);
18311833
else
@@ -1854,8 +1856,15 @@ void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
18541856
// the type has been fully processed.
18551857
BeginDeclTypeSpec();
18561858
auto &mapperName{std::get<std::string>(spec.t)};
1857-
MakeSymbol(parser::CharBlock(mapperName), Attrs{},
1858-
MiscDetails{MiscDetails::Kind::ConstructName});
1859+
// Create or update the mapper symbol with MapperDetails and
1860+
// keep track of the declarative construct for module emission.
1861+
Symbol &mapperSym{MakeSymbol(parser::CharBlock(mapperName), Attrs{})};
1862+
if (auto *md{mapperSym.detailsIf<MapperDetails>()}) {
1863+
md->AddDecl(declaratives_.back());
1864+
} else if (mapperSym.has<UnknownDetails>() || mapperSym.has<MiscDetails>()) {
1865+
mapperSym.set_details(MapperDetails{});
1866+
mapperSym.get<MapperDetails>().AddDecl(declaratives_.back());
1867+
}
18591868
PushScope(Scope::Kind::OtherConstruct, nullptr);
18601869
Walk(std::get<parser::TypeSpec>(spec.t));
18611870
auto &varName{std::get<parser::Name>(spec.t)};
@@ -3617,11 +3626,13 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
36173626
}
36183627
for (const auto &[name, symbol] : *useModuleScope_) {
36193628
// Default USE imports public names, excluding intrinsic-only and most
3620-
// miscellaneous details. However, allow OpenMP mapper identifiers,
3621-
// which are currently represented with MiscDetails::ConstructName.
3622-
bool isMapper{false};
3623-
if (const auto *misc{symbol->detailsIf<MiscDetails>()}) {
3624-
isMapper = misc->kind() == MiscDetails::Kind::ConstructName;
3629+
// miscellaneous details. Allow OpenMP mapper identifiers represented
3630+
// as MapperDetails, and also legacy MiscDetails::ConstructName.
3631+
bool isMapper{symbol->has<MapperDetails>()};
3632+
if (!isMapper) {
3633+
if (const auto *misc{symbol->detailsIf<MiscDetails>()}) {
3634+
isMapper = misc->kind() == MiscDetails::Kind::ConstructName;
3635+
}
36253636
}
36263637
if (symbol->attrs().test(Attr::PUBLIC) && !IsUseRenamed(symbol->name()) &&
36273638
(!symbol->implicitAttrs().test(Attr::INTRINSIC) ||

flang/lib/Semantics/symbol.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,8 @@ std::string DetailsToString(const Details &details) {
338338
[](const TypeParamDetails &) { return "TypeParam"; },
339339
[](const MiscDetails &) { return "Misc"; },
340340
[](const AssocEntityDetails &) { return "AssocEntity"; },
341-
[](const UserReductionDetails &) { return "UserReductionDetails"; }},
341+
[](const UserReductionDetails &) { return "UserReductionDetails"; },
342+
[](const MapperDetails &) { return "MapperDetails"; }},
342343
details);
343344
}
344345

@@ -379,6 +380,7 @@ bool Symbol::CanReplaceDetails(const Details &details) const {
379380
[&](const UserReductionDetails &) {
380381
return has<UserReductionDetails>();
381382
},
383+
[&](const MapperDetails &) { return has<MapperDetails>(); },
382384
[](const auto &) { return false; },
383385
},
384386
details);
@@ -685,6 +687,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Details &details) {
685687
DumpType(os, type);
686688
}
687689
},
690+
// Avoid recursive streaming for MapperDetails; nothing more to dump
691+
[&](const MapperDetails &) {},
688692
[&](const auto &x) { os << x; },
689693
},
690694
details);

flang/test/Lower/OpenMP/declare-mapper.f90

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-4.f90 -o - | FileCheck %t/omp-declare-mapper-4.f90
88
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-5.f90 -o - | FileCheck %t/omp-declare-mapper-5.f90
99
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-6.f90 -o - | FileCheck %t/omp-declare-mapper-6.f90
10-
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-7.f90 -o - | FileCheck %t/omp-declare-mapper-7.f90
10+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -module-dir %t %t/omp-declare-mapper-7.mod.f90 -o - >/dev/null
11+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -J %t %t/omp-declare-mapper-7.use.f90 -o - | FileCheck %t/omp-declare-mapper-7.use.f90
1112

1213
!--- omp-declare-mapper-1.f90
1314
subroutine declare_mapper_1
@@ -303,8 +304,8 @@ subroutine declare_mapper_nested_parent
303304
!$omp end target
304305
end subroutine declare_mapper_nested_parent
305306

306-
!--- omp-declare-mapper-7.f90
307-
! Check mappers declared inside modules and used via USE association.
307+
!--- omp-declare-mapper-7.mod.f90
308+
! Module with DECLARE MAPPER to be compiled separately
308309
module m_mod
309310
implicit none
310311
type :: mty
@@ -313,13 +314,13 @@ module m_mod
313314
!$omp declare mapper(mymap : mty :: v) map(tofrom: v%x)
314315
end module m_mod
315316

317+
!--- omp-declare-mapper-7.use.f90
318+
! Consumer program that USEs the module and applies the mapper by name.
319+
! CHECK: %{{.*}} = omp.map.info {{.*}} mapper(@{{.*mymap}}) {{.*}} {name = "a"}
316320
program use_module_mapper
317321
use m_mod
318322
implicit none
319323
type(mty) :: a
320-
321-
! CHECK: omp.declare_mapper @[[MODMAP:[^ ]*mymap]]
322-
! CHECK: %{{.*}} = omp.map.info {{.*}} mapper(@[[MODMAP]]) {{.*}} {name = "a"}
323324
!$omp target map(mapper(mymap) : a)
324325
a%x = 42
325326
!$omp end target

flang/test/Semantics/OpenMP/declare-mapper-symbols.f90

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@ program main
1111
!$omp declare mapper(ty :: maptwo) map(maptwo, maptwo%x)
1212

1313
!! Note, symbols come out in their respective scope, but not in declaration order.
14-
!CHECK: mymapper: Misc ConstructName
14+
!CHECK: mymapper: MapperDetails
1515
!CHECK: ty: DerivedType components: x
16-
!CHECK: ty.omp.default.mapper: Misc ConstructName
16+
!CHECK: ty.omp.default.mapper: MapperDetails
1717
!CHECK: DerivedType scope: ty
1818
!CHECK: OtherConstruct scope:
1919
!CHECK: mapped (OmpMapToFrom) {{.*}} ObjectEntity type: TYPE(ty)
2020
!CHECK: OtherConstruct scope:
2121
!CHECK: maptwo (OmpMapToFrom) {{.*}} ObjectEntity type: TYPE(ty)
2222

2323
end program main
24-

0 commit comments

Comments
 (0)