Skip to content

Commit ec1e0c5

Browse files
[Flang][OMP]Add support for DECLARE MAPPER parsing and semantics (#115160)
Will hit a TODO in the lowering, which there are tests added to check for this happening.
1 parent caa9a82 commit ec1e0c5

17 files changed

+269
-5
lines changed

flang/include/flang/Parser/dump-parse-tree.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,7 @@ class ParseTreeDumper {
506506
NODE(parser, OmpDeclareTargetSpecifier)
507507
NODE(parser, OmpDeclareTargetWithClause)
508508
NODE(parser, OmpDeclareTargetWithList)
509+
NODE(parser, OmpDeclareMapperSpecifier)
509510
NODE(parser, OmpDefaultClause)
510511
NODE_ENUM(OmpDefaultClause, Type)
511512
NODE(parser, OmpDefaultmapClause)
@@ -621,6 +622,7 @@ class ParseTreeDumper {
621622
NODE(parser, OpenMPDeclareReductionConstruct)
622623
NODE(parser, OpenMPDeclareSimdConstruct)
623624
NODE(parser, OpenMPDeclareTargetConstruct)
625+
NODE(parser, OpenMPDeclareMapperConstruct)
624626
NODE(parser, OmpMemoryOrderClause)
625627
NODE(parser, OmpAtomicClause)
626628
NODE(parser, OmpAtomicClauseList)

flang/include/flang/Parser/parse-tree.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3916,6 +3916,19 @@ struct OpenMPDeclareTargetConstruct {
39163916
std::tuple<Verbatim, OmpDeclareTargetSpecifier> t;
39173917
};
39183918

3919+
struct OmpDeclareMapperSpecifier {
3920+
TUPLE_CLASS_BOILERPLATE(OmpDeclareMapperSpecifier);
3921+
std::tuple<std::optional<Name>, TypeSpec, Name> t;
3922+
};
3923+
3924+
// OMP v5.2: 5.8.8
3925+
// declare-mapper -> DECLARE MAPPER ([mapper-name :] type :: var) map-clauses
3926+
struct OpenMPDeclareMapperConstruct {
3927+
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareMapperConstruct);
3928+
CharBlock source;
3929+
std::tuple<Verbatim, OmpDeclareMapperSpecifier, OmpClauseList> t;
3930+
};
3931+
39193932
// 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
39203933
// : combiner) [initializer-clause]
39213934
struct OmpReductionCombiner {
@@ -3966,9 +3979,10 @@ struct OpenMPDeclarativeAllocate {
39663979
struct OpenMPDeclarativeConstruct {
39673980
UNION_CLASS_BOILERPLATE(OpenMPDeclarativeConstruct);
39683981
CharBlock source;
3969-
std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareReductionConstruct,
3970-
OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
3971-
OpenMPThreadprivate, OpenMPRequiresConstruct>
3982+
std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareMapperConstruct,
3983+
OpenMPDeclareReductionConstruct, OpenMPDeclareSimdConstruct,
3984+
OpenMPDeclareTargetConstruct, OpenMPThreadprivate,
3985+
OpenMPRequiresConstruct>
39723986
u;
39733987
};
39743988

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2623,6 +2623,13 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
26232623
TODO(converter.getCurrentLocation(), "OpenMPDeclareSimdConstruct");
26242624
}
26252625

2626+
static void
2627+
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
2628+
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
2629+
const parser::OpenMPDeclareMapperConstruct &declareMapperConstruct) {
2630+
TODO(converter.getCurrentLocation(), "OpenMPDeclareMapperConstruct");
2631+
}
2632+
26262633
static void
26272634
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
26282635
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,15 @@ TYPE_PARSER(
860860
TYPE_PARSER(sourced(construct<OpenMPDeclareTargetConstruct>(
861861
verbatim("DECLARE TARGET"_tok), Parser<OmpDeclareTargetSpecifier>{})))
862862

863+
// declare-mapper-specifier
864+
TYPE_PARSER(construct<OmpDeclareMapperSpecifier>(
865+
maybe(name / ":" / !":"_tok), typeSpec / "::", name))
866+
867+
// OpenMP 5.2: 5.8.8 Declare Mapper Construct
868+
TYPE_PARSER(sourced(construct<OpenMPDeclareMapperConstruct>(
869+
verbatim("DECLARE MAPPER"_tok),
870+
"(" >> Parser<OmpDeclareMapperSpecifier>{} / ")", Parser<OmpClauseList>{})))
871+
863872
TYPE_PARSER(construct<OmpReductionCombiner>(Parser<AssignmentStmt>{}) ||
864873
construct<OmpReductionCombiner>(
865874
construct<OmpReductionCombiner::FunctionCombiner>(
@@ -968,6 +977,8 @@ TYPE_PARSER(startOmpLine >>
968977
withMessage("expected OpenMP construct"_err_en_US,
969978
sourced(construct<OpenMPDeclarativeConstruct>(
970979
Parser<OpenMPDeclareReductionConstruct>{}) ||
980+
construct<OpenMPDeclarativeConstruct>(
981+
Parser<OpenMPDeclareMapperConstruct>{}) ||
971982
construct<OpenMPDeclarativeConstruct>(
972983
Parser<OpenMPDeclareSimdConstruct>{}) ||
973984
construct<OpenMPDeclarativeConstruct>(

flang/lib/Parser/unparse.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2652,6 +2652,22 @@ class UnparseVisitor {
26522652
EndOpenMP();
26532653
return false;
26542654
},
2655+
[&](const OpenMPDeclareMapperConstruct &z) {
2656+
Word("DECLARE MAPPER (");
2657+
const auto &spec{std::get<OmpDeclareMapperSpecifier>(z.t)};
2658+
if (auto mapname{std::get<std::optional<Name>>(spec.t)}) {
2659+
Walk(mapname);
2660+
Put(":");
2661+
}
2662+
Walk(std::get<TypeSpec>(spec.t));
2663+
Put("::");
2664+
Walk(std::get<Name>(spec.t));
2665+
Put(")");
2666+
2667+
Walk(std::get<OmpClauseList>(z.t));
2668+
Put("\n");
2669+
return false;
2670+
},
26552671
[&](const OpenMPDeclareReductionConstruct &) {
26562672
Word("DECLARE REDUCTION ");
26572673
return true;

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,6 +1472,21 @@ void OmpStructureChecker::Leave(const parser::OmpDeclareTargetWithClause &x) {
14721472
}
14731473
}
14741474

1475+
void OmpStructureChecker::Enter(const parser::OpenMPDeclareMapperConstruct &x) {
1476+
const auto &dir{std::get<parser::Verbatim>(x.t)};
1477+
PushContextAndClauseSets(
1478+
dir.source, llvm::omp::Directive::OMPD_declare_mapper);
1479+
const auto &spec{std::get<parser::OmpDeclareMapperSpecifier>(x.t)};
1480+
const auto &type = std::get<parser::TypeSpec>(spec.t);
1481+
if (!std::get_if<parser::DerivedTypeSpec>(&type.u)) {
1482+
context_.Say(dir.source, "Type is not a derived type"_err_en_US);
1483+
}
1484+
}
1485+
1486+
void OmpStructureChecker::Leave(const parser::OpenMPDeclareMapperConstruct &) {
1487+
dirContext_.pop_back();
1488+
}
1489+
14751490
void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) {
14761491
const auto &dir{std::get<parser::Verbatim>(x.t)};
14771492
PushContext(dir.source, llvm::omp::Directive::OMPD_declare_target);

flang/lib/Semantics/check-omp-structure.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class OmpStructureChecker
9393
void Leave(const parser::OpenMPDeclareSimdConstruct &);
9494
void Enter(const parser::OpenMPDeclarativeAllocate &);
9595
void Leave(const parser::OpenMPDeclarativeAllocate &);
96+
void Enter(const parser::OpenMPDeclareMapperConstruct &);
97+
void Leave(const parser::OpenMPDeclareMapperConstruct &);
9698
void Enter(const parser::OpenMPDeclareTargetConstruct &);
9799
void Leave(const parser::OpenMPDeclareTargetConstruct &);
98100
void Enter(const parser::OpenMPDepobjConstruct &);

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
431431
bool Pre(const parser::OpenMPDeclareTargetConstruct &);
432432
void Post(const parser::OpenMPDeclareTargetConstruct &) { PopContext(); }
433433

434+
bool Pre(const parser::OpenMPDeclareMapperConstruct &);
435+
void Post(const parser::OpenMPDeclareMapperConstruct &) { PopContext(); }
436+
434437
bool Pre(const parser::OpenMPThreadprivate &);
435438
void Post(const parser::OpenMPThreadprivate &) { PopContext(); }
436439

@@ -1953,6 +1956,11 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareTargetConstruct &x) {
19531956
return true;
19541957
}
19551958

1959+
bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareMapperConstruct &x) {
1960+
PushContext(x.source, llvm::omp::Directive::OMPD_declare_mapper);
1961+
return true;
1962+
}
1963+
19561964
bool OmpAttributeVisitor::Pre(const parser::OpenMPThreadprivate &x) {
19571965
PushContext(x.source, llvm::omp::Directive::OMPD_threadprivate);
19581966
const auto &list{std::get<parser::OmpObjectList>(x.t)};

flang/lib/Semantics/resolve-names.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,6 +1468,9 @@ class OmpVisitor : public virtual DeclarationVisitor {
14681468
AddOmpSourceRange(x.source);
14691469
return true;
14701470
}
1471+
1472+
bool Pre(const parser::OpenMPDeclareMapperConstruct &);
1473+
14711474
void Post(const parser::OmpBeginLoopDirective &) {
14721475
messageHandler().set_currStmtSource(std::nullopt);
14731476
}
@@ -1605,6 +1608,37 @@ void OmpVisitor::Post(const parser::OpenMPBlockConstruct &x) {
16051608
}
16061609
}
16071610

1611+
// This "manually" walks the tree of the construct, because we need
1612+
// to resolve the type before the map clauses are processed - when
1613+
// just following the natural flow, the map clauses gets processed before
1614+
// the type has been fully processed.
1615+
bool OmpVisitor::Pre(const parser::OpenMPDeclareMapperConstruct &x) {
1616+
AddOmpSourceRange(x.source);
1617+
BeginDeclTypeSpec();
1618+
const auto &spec{std::get<parser::OmpDeclareMapperSpecifier>(x.t)};
1619+
Symbol *mapperSym{nullptr};
1620+
if (const auto &mapperName{std::get<std::optional<parser::Name>>(spec.t)}) {
1621+
mapperSym =
1622+
&MakeSymbol(*mapperName, MiscDetails{MiscDetails::Kind::ConstructName});
1623+
mapperName->symbol = mapperSym;
1624+
} else {
1625+
const parser::CharBlock defaultName{"default", 7};
1626+
mapperSym = &MakeSymbol(
1627+
defaultName, Attrs{}, MiscDetails{MiscDetails::Kind::ConstructName});
1628+
}
1629+
1630+
PushScope(Scope::Kind::OtherConstruct, nullptr);
1631+
Walk(std::get<parser::TypeSpec>(spec.t));
1632+
const auto &varName{std::get<parser::ObjectName>(spec.t)};
1633+
DeclareObjectEntity(varName);
1634+
1635+
Walk(std::get<parser::OmpClauseList>(x.t));
1636+
1637+
EndDeclTypeSpec();
1638+
PopScope();
1639+
return false;
1640+
}
1641+
16081642
// Walk the parse tree and resolve names to symbols.
16091643
class ResolveNamesVisitor : public virtual ScopeHandler,
16101644
public ModuleVisitor,

flang/lib/Semantics/unparse-with-symbols.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ class SymbolDumpVisitor {
5353
void Post(const parser::OpenMPThreadprivate &) { currStmt_ = std::nullopt; }
5454
void Post(const parser::Name &name);
5555

56+
bool Pre(const parser::OpenMPDeclareMapperConstruct &x) {
57+
currStmt_ = x.source;
58+
return true;
59+
}
60+
void Post(const parser::OpenMPDeclareMapperConstruct &) {
61+
currStmt_ = std::nullopt;
62+
}
63+
5664
private:
5765
std::optional<SourceName> currStmt_; // current statement we are processing
5866
std::multimap<const char *, const Symbol *> symbols_; // location to symbol
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
! This test checks lowering of OpenMP declare mapper Directive.
2+
3+
! RUN: split-file %s %t
4+
! RUN: not %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-1.f90 2>&1 | FileCheck %t/omp-declare-mapper-1.f90
5+
! RUN not %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 %t/omp-declare-mapper-2.f90 2>&1 | FileCheck %t/omp-declare-mapper-2.f90
6+
7+
!--- omp-declare-mapper-1.f90
8+
subroutine declare_mapper_1
9+
integer,parameter :: nvals = 250
10+
type my_type
11+
integer :: num_vals
12+
integer, allocatable :: values(:)
13+
end type
14+
15+
type my_type2
16+
type (my_type) :: my_type_var
17+
type (my_type) :: temp
18+
real,dimension(nvals) :: unmapped
19+
real,dimension(nvals) :: arr
20+
end type
21+
type (my_type2) :: t
22+
real :: x, y(nvals)
23+
!$omp declare mapper (my_type :: var) map (var, var%values (1:var%num_vals))
24+
!CHECK: not yet implemented: OpenMPDeclareMapperConstruct
25+
end subroutine declare_mapper_1
26+
27+
28+
!--- omp-declare-mapper-2.f90
29+
subroutine declare_mapper_2
30+
integer,parameter :: nvals = 250
31+
type my_type
32+
integer :: num_vals
33+
integer, allocatable :: values(:)
34+
end type
35+
36+
type my_type2
37+
type (my_type) :: my_type_var
38+
type (my_type) :: temp
39+
real,dimension(nvals) :: unmapped
40+
real,dimension(nvals) :: arr
41+
end type
42+
type (my_type2) :: t
43+
real :: x, y(nvals)
44+
!$omp declare mapper (my_mapper : my_type2 :: v) map (v%arr, x, y(:)) &
45+
!$omp& map (alloc : v%temp)
46+
!CHECK: not yet implemented: OpenMPDeclareMapperConstruct
47+
end subroutine declare_mapper_2
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck --ignore-case %s
2+
! RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
3+
program main
4+
!CHECK-LABEL: program main
5+
implicit none
6+
7+
type ty
8+
integer :: x
9+
end type ty
10+
11+
12+
!CHECK: !$OMP DECLARE MAPPER (mymapper:ty::mapped) MAP(mapped,mapped%x)
13+
!$omp declare mapper(mymapper : ty :: mapped) map(mapped, mapped%x)
14+
15+
!PARSE-TREE: OpenMPDeclareMapperConstruct
16+
!PARSE-TREE: OmpDeclareMapperSpecifier
17+
!PARSE-TREE: Name = 'mymapper'
18+
!PARSE-TREE: TypeSpec -> DerivedTypeSpec
19+
!PARSE-TREE: Name = 'ty'
20+
!PARSE-TREE: Name = 'mapped'
21+
!PARSE-TREE: OmpMapClause
22+
!PARSE-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'mapped'
23+
!PARSE-TREE: OmpObject -> Designator -> DataRef -> StructureComponent
24+
!PARSE-TREE: DataRef -> Name = 'mapped'
25+
!PARSE-TREE: Name = 'x'
26+
27+
!CHECK: !$OMP DECLARE MAPPER (ty::mapped) MAP(mapped,mapped%x)
28+
!$omp declare mapper(ty :: mapped) map(mapped, mapped%x)
29+
30+
!PARSE-TREE: OpenMPDeclareMapperConstruct
31+
!PARSE-TREE: OmpDeclareMapperSpecifier
32+
!PARSE-TREE: TypeSpec -> DerivedTypeSpec
33+
!PARSE-TREE: Name = 'ty'
34+
!PARSE-TREE: Name = 'mapped'
35+
!PARSE-TREE: OmpMapClause
36+
!PARSE-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'mapped'
37+
!PARSE-TREE: OmpObject -> Designator -> DataRef -> StructureComponent
38+
!PARSE-TREE: DataRef -> Name = 'mapped'
39+
!PARSE-TREE: Name = 'x'
40+
41+
end program main
42+
!CHECK-LABEL: end program main
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
! RUN: %flang_fc1 -fdebug-dump-symbols -fopenmp -fopenmp-version=50 %s | FileCheck %s
2+
3+
program main
4+
!CHECK-LABEL: MainProgram scope: main
5+
implicit none
6+
7+
type ty
8+
integer :: x
9+
end type ty
10+
!$omp declare mapper(mymapper : ty :: mapped) map(mapped, mapped%x)
11+
!$omp declare mapper(ty :: maptwo) map(maptwo, maptwo%x)
12+
13+
!! Note, symbols come out in their respective scope, but not in declaration order.
14+
!CHECK: default: Misc ConstructName
15+
!CHECK: mymapper: Misc ConstructName
16+
!CHECK: ty: DerivedType components: x
17+
!CHECK: DerivedType scope: ty
18+
!CHECK: OtherConstruct scope:
19+
!CHECK: mapped (OmpMapToFrom) {{.*}} ObjectEntity type: TYPE(ty)
20+
!CHECK: OtherConstruct scope:
21+
!CHECK: maptwo (OmpMapToFrom) {{.*}} ObjectEntity type: TYPE(ty)
22+
23+
end program main
24+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50
2+
! Test the declare mapper with non-derived type.
3+
4+
integer :: y
5+
6+
!ERROR: Type is not a derived type
7+
!$omp declare mapper(mm : integer::x) map(x, y)
8+
end
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50
2+
! Test the declare mapper construct with abstract type.
3+
4+
type, abstract :: t1
5+
integer :: y
6+
end type t1
7+
8+
!ERROR: ABSTRACT derived type may not be used here
9+
!$omp declare mapper(mm : t1::x) map(x, x%y)
10+
end
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50
2+
! Test the declare mapper construct with two default mappers.
3+
4+
type :: t1
5+
integer :: y
6+
end type t1
7+
8+
type :: t2
9+
real :: y, z
10+
end type t2
11+
12+
!error: 'default' is already declared in this scoping unit
13+
14+
!$omp declare mapper(t1::x) map(x, x%y)
15+
!$omp declare mapper(t2::w) map(w, w%y, w%z)
16+
end

llvm/include/llvm/Frontend/OpenMP/OMP.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,8 @@ def OMP_Critical : Directive<"critical"> {
625625
let category = CA_Executable;
626626
}
627627
def OMP_DeclareMapper : Directive<"declare mapper"> {
628-
let allowedClauses = [
629-
VersionedClause<OMPC_Map>,
628+
let requiredClauses = [
629+
VersionedClause<OMPC_Map, 45>,
630630
];
631631
let association = AS_None;
632632
let category = CA_Declarative;

0 commit comments

Comments
 (0)