mirror of
https://github.com/intel/llvm.git
synced 2026-01-19 09:31:59 +08:00
[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:
committed by
GitHub
parent
fdf85d5dbe
commit
39be4ad473
@@ -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)
|
||||
|
||||
@@ -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>(
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)};
|
||||
|
||||
@@ -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 &);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user