[flang] [OpenMP] parse tree fix for Declare Target (flang-compiler/f18#670)

The original implementation will throw parsing error for multiple
clauses on `declare target` directive, for example:
```
!$omp declare target to(Q) link(R)
```

Based on the OpenMP Spec, we only need two types for the specifier:

```
!$omp declare target (extended-list)
```
or
```
!$omp declare target [clause[ [,] clause] ... ]
```

This fix makes `declare target` accepts either the `list` or `clauses`,
which is more general and better for error messages.

Adjusted existing test for checking the parse tree changes. More tests
will be added during Semantics.

Original-commit: flang-compiler/f18@60f47fc1a1
Reviewed-on: https://github.com/flang-compiler/f18/pull/670
This commit is contained in:
Jinxin (Brian) Yang
2019-08-20 10:23:56 -07:00
committed by GitHub
parent fdf85d5dbe
commit 39be4ad473
8 changed files with 52 additions and 85 deletions

View File

@@ -456,8 +456,9 @@ public:
NODE(parser::OmpClause, IsDevicePtr)
NODE(parser, OmpCriticalDirective)
NODE(parser::OmpCriticalDirective, Hint)
NODE(parser, OmpDeclareTargetMapType)
NODE_ENUM(parser::OmpDeclareTargetMapType, Type)
NODE(parser, OmpDeclareTargetSpecifier)
NODE(parser, OmpDeclareTargetWithClause)
NODE(parser, OmpDeclareTargetWithList)
NODE(parser, OmpDefaultClause)
NODE_ENUM(parser::OmpDefaultClause, Type)
NODE(parser, OmpDependClause)
@@ -525,10 +526,6 @@ public:
NODE(parser, OpenMPDeclareReductionConstruct)
NODE(parser, OpenMPDeclareSimdConstruct)
NODE(parser, OpenMPDeclareTargetConstruct)
NODE(parser, OpenMPDeclareTargetSpecifier)
NODE(parser::OpenMPDeclareTargetSpecifier, Implicit)
NODE(parser::OpenMPDeclareTargetSpecifier, WithClause)
NODE(parser::OpenMPDeclareTargetSpecifier, WithExtendedList)
NODE(parser, OpenMPFlushConstruct)
NODE(parser, OpenMPLoopConstruct)
NODE(parser, OpenMPSimpleStandaloneConstruct)

View File

@@ -368,26 +368,22 @@ TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(
Parser<OmpReductionCombiner>{} / ")",
maybe(Parser<OmpReductionInitializerClause>{}))))
// declare-target-map-type
TYPE_PARSER(construct<OmpDeclareTargetMapType>(
"LINK" >> pure(OmpDeclareTargetMapType::Type::Link) ||
"TO" >> pure(OmpDeclareTargetMapType::Type::To)))
// declare-target with list
TYPE_PARSER(sourced(construct<OmpDeclareTargetWithList>(
parenthesized(Parser<OmpObjectList>{}))))
// declare-target with clause
TYPE_PARSER(
sourced(construct<OmpDeclareTargetWithClause>(Parser<OmpClauseList>{})))
// declare-target-specifier
TYPE_PARSER(construct<OpenMPDeclareTargetSpecifier>(
construct<OpenMPDeclareTargetSpecifier::WithClause>(
Parser<OmpDeclareTargetMapType>{},
parenthesized(Parser<OmpObjectList>{}))) ||
lookAhead(endOfLine) >>
construct<OpenMPDeclareTargetSpecifier>(
construct<OpenMPDeclareTargetSpecifier::Implicit>()) ||
construct<OpenMPDeclareTargetSpecifier>(
parenthesized(construct<OpenMPDeclareTargetSpecifier::WithExtendedList>(
Parser<OmpObjectList>{}))))
TYPE_PARSER(
construct<OmpDeclareTargetSpecifier>(Parser<OmpDeclareTargetWithList>{}) ||
construct<OmpDeclareTargetSpecifier>(Parser<OmpDeclareTargetWithClause>{}))
// Declare Target Construct
TYPE_PARSER(sourced(construct<OpenMPDeclareTargetConstruct>(
verbatim("DECLARE TARGET"_tok), Parser<OpenMPDeclareTargetSpecifier>{})))
verbatim("DECLARE TARGET"_tok), Parser<OmpDeclareTargetSpecifier>{})))
TYPE_PARSER(construct<OmpReductionCombiner>(Parser<AssignmentStmt>{}) ||
construct<OmpReductionCombiner>(

View File

@@ -821,35 +821,5 @@ void Walk(OmpLinearClause::WithoutModifier &x, M &mutator) {
mutator.Post(x);
}
}
template<typename V>
void Walk(const OpenMPDeclareTargetSpecifier::WithClause &x, V &visitor) {
if (visitor.Pre(x)) {
Walk(x.maptype, visitor);
Walk(x.names, visitor);
visitor.Post(x);
}
}
template<typename M>
void Walk(OpenMPDeclareTargetSpecifier::WithClause &x, M &mutator) {
if (mutator.Pre(x)) {
Walk(x.maptype, mutator);
Walk(x.names, mutator);
mutator.Post(x);
}
}
template<typename V>
void Walk(const OpenMPDeclareTargetSpecifier::WithExtendedList &x, V &visitor) {
if (visitor.Pre(x)) {
Walk(x.names, visitor);
visitor.Post(x);
}
}
template<typename M>
void Walk(OpenMPDeclareTargetSpecifier::WithExtendedList &x, M &mutator) {
if (mutator.Pre(x)) {
Walk(x.names, mutator);
mutator.Post(x);
}
}
}
#endif // FORTRAN_PARSER_PARSE_TREE_VISITOR_H_

View File

@@ -3501,33 +3501,25 @@ struct OmpBlockDirective {
CharBlock source;
};
struct OmpDeclareTargetMapType {
ENUM_CLASS(Type, Link, To)
WRAPPER_CLASS_BOILERPLATE(OmpDeclareTargetMapType, Type);
struct OmpDeclareTargetWithList {
WRAPPER_CLASS_BOILERPLATE(OmpDeclareTargetWithList, OmpObjectList);
CharBlock source;
};
struct OpenMPDeclareTargetSpecifier {
UNION_CLASS_BOILERPLATE(OpenMPDeclareTargetSpecifier);
struct WithClause {
BOILERPLATE(WithClause);
WithClause(OmpDeclareTargetMapType &&m, OmpObjectList &&n)
: maptype(std::move(m)), names(std::move(n)) {}
OmpDeclareTargetMapType maptype;
OmpObjectList names;
};
struct WithExtendedList {
BOILERPLATE(WithExtendedList);
WithExtendedList(OmpObjectList &&n) : names(std::move(n)) {}
OmpObjectList names;
};
EMPTY_CLASS(Implicit);
std::variant<WithClause, WithExtendedList, Implicit> u;
struct OmpDeclareTargetWithClause {
WRAPPER_CLASS_BOILERPLATE(OmpDeclareTargetWithClause, OmpClauseList);
CharBlock source;
};
struct OmpDeclareTargetSpecifier {
UNION_CLASS_BOILERPLATE(OmpDeclareTargetSpecifier);
std::variant<OmpDeclareTargetWithList, OmpDeclareTargetWithClause> u;
};
struct OpenMPDeclareTargetConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareTargetConstruct);
CharBlock source;
std::tuple<Verbatim, OpenMPDeclareTargetSpecifier> t;
std::tuple<Verbatim, OmpDeclareTargetSpecifier> t;
};
struct OmpReductionCombiner {

View File

@@ -2187,11 +2187,8 @@ public:
Walk(std::get<Block>(x.t), "");
Walk(std::get<OmpEndCriticalDirective>(x.t));
}
void Unparse(const OpenMPDeclareTargetSpecifier::WithClause &x) {
Walk(x.maptype), Put("("), Walk(x.names), Put(")");
}
void Unparse(const OpenMPDeclareTargetSpecifier::WithExtendedList &x) {
Put("("), Walk(x.names), Put(")");
void Unparse(const OmpDeclareTargetWithList &x) {
Put("("), Walk(x.v), Put(")");
}
void Unparse(const OmpReductionInitializerClause &x) {
Word(" INITIALIZER(OMP_PRIV = ");
@@ -2415,7 +2412,6 @@ public:
WALK_NESTED_ENUM(OmpScheduleClause, ScheduleType) // OMP schedule-type
WALK_NESTED_ENUM(
OmpIfClause, DirectiveNameModifier) // OMP directive-modifier
WALK_NESTED_ENUM(OmpDeclareTargetMapType, Type) // OMP DeclareTarget map-type
WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type
#undef WALK_NESTED_ENUM

View File

@@ -282,6 +282,19 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
ompContext_.pop_back();
}
void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
PushContext(dir.source, OmpDirective::DECLARE_TARGET);
const auto &spec{std::get<parser::OmpDeclareTargetSpecifier>(x.t)};
if (std::holds_alternative<parser::OmpDeclareTargetWithClause>(spec.u)) {
SetContextAllowed(OmpClauseSet{OmpClause::TO, OmpClause::LINK});
}
}
void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &) {
ompContext_.pop_back();
}
void OmpStructureChecker::Enter(
const parser::OpenMPSimpleStandaloneConstruct &x) {
const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(x.t)};

View File

@@ -71,6 +71,8 @@ public:
void Enter(const parser::OpenMPDeclareSimdConstruct &);
void Leave(const parser::OpenMPDeclareSimdConstruct &);
void Enter(const parser::OpenMPDeclareTargetConstruct &);
void Leave(const parser::OpenMPDeclareTargetConstruct &);
void Enter(const parser::OpenMPSimpleStandaloneConstruct &);
void Leave(const parser::OpenMPSimpleStandaloneConstruct &);

View File

@@ -56,16 +56,17 @@ end subroutine sub1
! 2.15.2 threadprivate
module m2
!$omp declare target
!$omp declare target (N)
!$omp declare target to(Q)
integer, parameter :: N=10000, M=1024
integer :: i
real :: Q(N, N)
!$omp threadprivate(i)
contains
subroutine foo
!$omp declare target
!$omp declare target (foo, N, M)
!$omp declare target to(Q, S) link(R)
!ERROR: MAP clause is not allowed on the DECLARE TARGET directive
!$omp declare target map(from:Q)
integer, parameter :: N=10000, M=1024
integer :: i
real :: Q(N, N), R(N,M), S(M,M)
!$omp threadprivate(i)
end subroutine foo
end module m2