Skip to content

Commit 6e23352

Browse files
committed
Emit declare_mapper to .mod file. Update test to check separate module and program file compilation.
1 parent 117d77e commit 6e23352

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
@@ -448,6 +448,13 @@ class FirConverter : public Fortran::lower::AbstractConverter {
448448
}
449449
});
450450

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

flang/lib/Lower/OpenMP/OpenMP.cpp

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

3546-
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3547-
semantics::SemanticsContext &semaCtx,
3548-
lower::pft::Evaluation &eval,
3549-
const parser::OpenMPDeclareMapperConstruct &construct) {
3546+
static void genOpenMPDeclareMapperImpl(
3547+
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
3548+
const parser::OpenMPDeclareMapperConstruct &construct,
3549+
const semantics::Symbol *mapperSymOpt = nullptr) {
35503550
mlir::Location loc = converter.genLocation(construct.source);
35513551
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
35523552
const parser::OmpArgumentList &args = construct.v.Arguments();
@@ -3562,8 +3562,17 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
35623562
"Expected derived type");
35633563

35643564
std::string mapperNameStr = mapperName;
3565-
if (auto *sym = converter.getCurrentScope().FindSymbol(mapperNameStr))
3565+
if (mapperSymOpt && mapperNameStr != "default") {
3566+
mapperNameStr = converter.mangleName(mapperNameStr, mapperSymOpt->owner());
3567+
} else if (auto *sym =
3568+
converter.getCurrentScope().FindSymbol(mapperNameStr)) {
35663569
mapperNameStr = converter.mangleName(mapperNameStr, sym->owner());
3570+
}
3571+
3572+
// If the mapper op already exists (e.g., created by regular lowering),
3573+
// do not recreate it.
3574+
if (converter.getModuleOp().lookupSymbol(mapperNameStr))
3575+
return;
35673576

35683577
// Save current insertion point before moving to the module scope to create
35693578
// the DeclareMapperOp
@@ -3586,6 +3595,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
35863595
mlir::omp::DeclareMapperInfoOp::create(firOpBuilder, loc, clauseOps.mapVars);
35873596
}
35883597

3598+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3599+
semantics::SemanticsContext &semaCtx,
3600+
lower::pft::Evaluation &eval,
3601+
const parser::OpenMPDeclareMapperConstruct &construct) {
3602+
genOpenMPDeclareMapperImpl(converter, semaCtx, construct);
3603+
}
3604+
35893605
static void
35903606
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
35913607
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
@@ -4229,3 +4245,32 @@ void Fortran::lower::genOpenMPRequires(mlir::Operation *mod,
42294245
offloadMod.setRequires(mlirFlags);
42304246
}
42314247
}
4248+
4249+
// Walk scopes and materialize omp.declare_mapper ops for mapper declarations
4250+
// found in imported modules. If \p scope is null, start from the global scope.
4251+
void Fortran::lower::materializeOpenMPDeclareMappers(
4252+
Fortran::lower::AbstractConverter &converter,
4253+
semantics::SemanticsContext &semaCtx, const semantics::Scope *scope) {
4254+
const semantics::Scope &root = scope ? *scope : semaCtx.globalScope();
4255+
4256+
// Recurse into child scopes first (modules, submodules, etc.).
4257+
for (const semantics::Scope &child : root.children())
4258+
materializeOpenMPDeclareMappers(converter, semaCtx, &child);
4259+
4260+
// Only consider module scopes to avoid duplicating local constructs.
4261+
if (!root.IsModule())
4262+
return;
4263+
4264+
// Scan symbols in this module scope for MapperDetails.
4265+
for (auto &it : root) {
4266+
const semantics::Symbol &sym = *it.second;
4267+
if (auto *md = sym.detailsIf<semantics::MapperDetails>()) {
4268+
for (const auto *decl : md->GetDeclList()) {
4269+
if (const auto *mapperDecl =
4270+
std::get_if<parser::OpenMPDeclareMapperConstruct>(&decl->u)) {
4271+
genOpenMPDeclareMapperImpl(converter, semaCtx, *mapperDecl, &sym);
4272+
}
4273+
}
4274+
}
4275+
}
4276+
}

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());
@@ -1101,6 +1103,16 @@ void ModFileWriter::PutUserReduction(
11011103
}
11021104
}
11031105

1106+
static void PutMapper(
1107+
llvm::raw_ostream &os, const Symbol &symbol, SemanticsContext &context) {
1108+
const auto &details{symbol.get<MapperDetails>()};
1109+
// Emit each saved DECLARE MAPPER construct as-is, so that consumers of the
1110+
// module can reparse it and recreate the mapper symbol and semantics state.
1111+
for (const auto *decl : details.GetDeclList()) {
1112+
Unparse(os, *decl, context.langOptions());
1113+
}
1114+
}
1115+
11041116
void PutInit(llvm::raw_ostream &os, const Symbol &symbol, const MaybeExpr &init,
11051117
const parser::Expr *unanalyzed, SemanticsContext &context) {
11061118
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
@@ -1852,8 +1852,10 @@ bool OmpVisitor::Pre(const parser::OmpMapClause &x) {
18521852
// TODO: Do we need a specific flag or type here, to distinghuish against
18531853
// other ConstructName things? Leaving this for the full implementation
18541854
// of mapper lowering.
1855-
auto *misc{symbol->GetUltimate().detailsIf<MiscDetails>()};
1856-
if (!misc || misc->kind() != MiscDetails::Kind::ConstructName)
1855+
auto &ultimate{symbol->GetUltimate()};
1856+
auto *misc{ultimate.detailsIf<MiscDetails>()};
1857+
auto *md{ultimate.detailsIf<MapperDetails>()};
1858+
if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
18571859
context().Say(mapper->v.source,
18581860
"Name '%s' should be a mapper name"_err_en_US, mapper->v.source);
18591861
else
@@ -1882,8 +1884,15 @@ void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
18821884
// the type has been fully processed.
18831885
BeginDeclTypeSpec();
18841886
auto &mapperName{std::get<std::string>(spec.t)};
1885-
MakeSymbol(parser::CharBlock(mapperName), Attrs{},
1886-
MiscDetails{MiscDetails::Kind::ConstructName});
1887+
// Create or update the mapper symbol with MapperDetails and
1888+
// keep track of the declarative construct for module emission.
1889+
Symbol &mapperSym{MakeSymbol(parser::CharBlock(mapperName), Attrs{})};
1890+
if (auto *md{mapperSym.detailsIf<MapperDetails>()}) {
1891+
md->AddDecl(declaratives_.back());
1892+
} else if (mapperSym.has<UnknownDetails>() || mapperSym.has<MiscDetails>()) {
1893+
mapperSym.set_details(MapperDetails{});
1894+
mapperSym.get<MapperDetails>().AddDecl(declaratives_.back());
1895+
}
18871896
PushScope(Scope::Kind::OtherConstruct, nullptr);
18881897
Walk(std::get<parser::TypeSpec>(spec.t));
18891898
auto &varName{std::get<parser::Name>(spec.t)};
@@ -3614,11 +3623,13 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
36143623
}
36153624
for (const auto &[name, symbol] : *useModuleScope_) {
36163625
// Default USE imports public names, excluding intrinsic-only and most
3617-
// miscellaneous details. However, allow OpenMP mapper identifiers,
3618-
// which are currently represented with MiscDetails::ConstructName.
3619-
bool isMapper{false};
3620-
if (const auto *misc{symbol->detailsIf<MiscDetails>()}) {
3621-
isMapper = misc->kind() == MiscDetails::Kind::ConstructName;
3626+
// miscellaneous details. Allow OpenMP mapper identifiers represented
3627+
// as MapperDetails, and also legacy MiscDetails::ConstructName.
3628+
bool isMapper{symbol->has<MapperDetails>()};
3629+
if (!isMapper) {
3630+
if (const auto *misc{symbol->detailsIf<MiscDetails>()}) {
3631+
isMapper = misc->kind() == MiscDetails::Kind::ConstructName;
3632+
}
36223633
}
36233634
if (symbol->attrs().test(Attr::PUBLIC) && !IsUseRenamed(symbol->name()) &&
36243635
(!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)