Skip to content

Commit 33faa82

Browse files
authored
[flang][OpenMP] Use new modifiers in IF/LASTPRIVATE (#118128)
The usual changes, added more references to OpenMP specs.
1 parent b8daa45 commit 33faa82

File tree

17 files changed

+298
-166
lines changed

17 files changed

+298
-166
lines changed

flang/examples/FeatureList/FeatureList.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,8 @@ struct NodeVisitor {
492492
READ_FEATURE(OmpPrescriptiveness)
493493
READ_FEATURE(OmpPrescriptiveness::Value)
494494
READ_FEATURE(OmpIfClause)
495-
READ_FEATURE(OmpIfClause::DirectiveNameModifier)
495+
READ_FEATURE(OmpIfClause::Modifier)
496+
READ_FEATURE(OmpDirectiveNameModifier)
496497
READ_FEATURE(OmpLinearClause)
497498
READ_FEATURE(OmpLinearClause::WithModifier)
498499
READ_FEATURE(OmpLinearClause::WithoutModifier)

flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "FlangOmpReportVisitor.h"
1010
#include "llvm/ADT/StringExtras.h"
11+
#include "llvm/Frontend/OpenMP/OMP.h"
1112

1213
namespace Fortran {
1314
namespace parser {
@@ -238,9 +239,9 @@ void OpenMPCounterVisitor::Post(const OmpScheduleClause::Kind &c) {
238239
clauseDetails +=
239240
"type=" + std::string{OmpScheduleClause::EnumToString(c)} + ";";
240241
}
241-
void OpenMPCounterVisitor::Post(const OmpIfClause::DirectiveNameModifier &c) {
242+
void OpenMPCounterVisitor::Post(const OmpDirectiveNameModifier &c) {
242243
clauseDetails +=
243-
"name_modifier=" + std::string{OmpIfClause::EnumToString(c)} + ";";
244+
"name_modifier=" + llvm::omp::getOpenMPDirectiveName(c.v).str() + ";";
244245
}
245246
void OpenMPCounterVisitor::Post(const OmpCancelType::Type &c) {
246247
clauseDetails += "type=" + std::string{OmpCancelType::EnumToString(c)} + ";";

flang/examples/FlangOmpReport/FlangOmpReportVisitor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ struct OpenMPCounterVisitor {
7777
void Post(const OmpTaskDependenceType::Value &c);
7878
void Post(const OmpMapType::Value &c);
7979
void Post(const OmpScheduleClause::Kind &c);
80-
void Post(const OmpIfClause::DirectiveNameModifier &c);
80+
void Post(const OmpDirectiveNameModifier &c);
8181
void Post(const OmpCancelType::Type &c);
8282
void Post(const OmpClause &c);
8383
void PostClauseCommon(const ClauseInfo &ci);

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,10 +550,13 @@ class ParseTreeDumper {
550550
NODE(OmpFromClause, Modifier)
551551
NODE(parser, OmpExpectation)
552552
NODE_ENUM(OmpExpectation, Value)
553+
NODE(parser, OmpDirectiveNameModifier)
553554
NODE(parser, OmpIfClause)
554-
NODE_ENUM(OmpIfClause, DirectiveNameModifier)
555-
NODE_ENUM(OmpLastprivateClause, LastprivateModifier)
555+
NODE(OmpIfClause, Modifier)
556556
NODE(parser, OmpLastprivateClause)
557+
NODE(OmpLastprivateClause, Modifier)
558+
NODE(parser, OmpLastprivateModifier)
559+
NODE_ENUM(OmpLastprivateModifier, Value)
557560
NODE(parser, OmpLinearClause)
558561
NODE(OmpLinearClause, WithModifier)
559562
NODE(OmpLinearClause, WithoutModifier)

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

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3558,6 +3558,23 @@ struct OmpDeviceModifier {
35583558
WRAPPER_CLASS_BOILERPLATE(OmpDeviceModifier, Value);
35593559
};
35603560

3561+
// Ref: [5.2:72-73,230-323], in 4.5-5.1 it's scattered over individual
3562+
// directives that allow the IF clause.
3563+
//
3564+
// directive-name-modifier ->
3565+
// PARALLEL | TARGET | TARGET DATA |
3566+
// TARGET ENTER DATA | TARGET EXIT DATA |
3567+
// TARGET UPDATE | TASK | TASKLOOP | // since 4.5
3568+
// CANCEL[*] | SIMD | // since 5.0
3569+
// TEAMS // since 5.2
3570+
//
3571+
// [*] The IF clause is allowed on CANCEL in OpenMP 4.5, but only without
3572+
// the directive-name-modifier. For the sake of uniformity CANCEL can be
3573+
// considered a valid value in 4.5 as well.
3574+
struct OmpDirectiveNameModifier {
3575+
WRAPPER_CLASS_BOILERPLATE(OmpDirectiveNameModifier, llvm::omp::Directive);
3576+
};
3577+
35613578
// Ref: [5.1:205-209], [5.2:166-168]
35623579
//
35633580
// motion-modifier ->
@@ -3581,6 +3598,15 @@ struct OmpIterator {
35813598
WRAPPER_CLASS_BOILERPLATE(OmpIterator, std::list<OmpIteratorSpecifier>);
35823599
};
35833600

3601+
// Ref: [5.0:288-290], [5.1:321-322], [5.2:115-117]
3602+
//
3603+
// lastprivate-modifier ->
3604+
// CONDITIONAL // since 5.0
3605+
struct OmpLastprivateModifier {
3606+
ENUM_CLASS(Value, Conditional)
3607+
WRAPPER_CLASS_BOILERPLATE(OmpLastprivateModifier, Value);
3608+
};
3609+
35843610
// Ref: [4.5:207-210], [5.0:290-293], [5.1:323-325], [5.2:117-120]
35853611
//
35863612
// linear-modifier ->
@@ -3913,12 +3939,16 @@ struct OmpGrainsizeClause {
39133939
std::tuple<MODIFIERS(), ScalarIntExpr> t;
39143940
};
39153941

3916-
// 2.12 if-clause -> IF ([ directive-name-modifier :] scalar-logical-expr)
3942+
// Ref: [5.2:72-73], in 4.5-5.1 it's scattered over individual directives
3943+
// that allow the IF clause.
3944+
//
3945+
// if-clause ->
3946+
// IF([directive-name-modifier:]
3947+
// scalar-logical-expression) // since 4.5
39173948
struct OmpIfClause {
39183949
TUPLE_CLASS_BOILERPLATE(OmpIfClause);
3919-
ENUM_CLASS(DirectiveNameModifier, Parallel, Simd, Target, TargetData,
3920-
TargetEnterData, TargetExitData, TargetUpdate, Task, Taskloop, Teams)
3921-
std::tuple<std::optional<DirectiveNameModifier>, ScalarLogicalExpr> t;
3950+
MODIFIER_BOILERPLATE(OmpDirectiveNameModifier);
3951+
std::tuple<MODIFIERS(), ScalarLogicalExpr> t;
39223952
};
39233953

39243954
// OMP 5.0 2.19.5.6 in_reduction-clause -> IN_REDUCTION (reduction-identifier:
@@ -3928,13 +3958,15 @@ struct OmpInReductionClause {
39283958
std::tuple<OmpReductionIdentifier, OmpObjectList> t;
39293959
};
39303960

3931-
// OMP 5.0 2.19.4.5 lastprivate-clause ->
3932-
// LASTPRIVATE ([lastprivate-modifier :] list)
3933-
// lastprivate-modifier -> CONDITIONAL
3961+
// Ref: [4.5:199-201], [5.0:288-290], [5.1:321-322], [5.2:115-117]
3962+
//
3963+
// lastprivate-clause ->
3964+
// LASTPRIVATE(list) | // since 4.5
3965+
// LASTPRIVATE([lastprivate-modifier:] list) // since 5.0
39343966
struct OmpLastprivateClause {
39353967
TUPLE_CLASS_BOILERPLATE(OmpLastprivateClause);
3936-
ENUM_CLASS(LastprivateModifier, Conditional);
3937-
std::tuple<std::optional<LastprivateModifier>, OmpObjectList> t;
3968+
MODIFIER_BOILERPLATE(OmpLastprivateModifier);
3969+
std::tuple<MODIFIERS(), OmpObjectList> t;
39383970
};
39393971

39403972
// 2.15.3.7 linear-clause -> LINEAR (linear-list[ : linear-step])

flang/include/flang/Semantics/openmp-modifiers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@ DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier);
7474
DECLARE_DESCRIPTOR(parser::OmpChunkModifier);
7575
DECLARE_DESCRIPTOR(parser::OmpDependenceType);
7676
DECLARE_DESCRIPTOR(parser::OmpDeviceModifier);
77+
DECLARE_DESCRIPTOR(parser::OmpDirectiveNameModifier);
7778
DECLARE_DESCRIPTOR(parser::OmpExpectation);
7879
DECLARE_DESCRIPTOR(parser::OmpIterator);
80+
DECLARE_DESCRIPTOR(parser::OmpLastprivateModifier);
7981
DECLARE_DESCRIPTOR(parser::OmpLinearModifier);
8082
DECLARE_DESCRIPTOR(parser::OmpMapper);
8183
DECLARE_DESCRIPTOR(parser::OmpMapType);

flang/lib/Lower/OpenMP/Clauses.cpp

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -825,27 +825,13 @@ Holds make(const parser::OmpClause::Holds &inp,
825825
If make(const parser::OmpClause::If &inp,
826826
semantics::SemanticsContext &semaCtx) {
827827
// inp.v -> parser::OmpIfClause
828-
using wrapped = parser::OmpIfClause;
829-
830-
CLAUSET_ENUM_CONVERT( //
831-
convert, wrapped::DirectiveNameModifier, llvm::omp::Directive,
832-
// clang-format off
833-
MS(Parallel, OMPD_parallel)
834-
MS(Simd, OMPD_simd)
835-
MS(Target, OMPD_target)
836-
MS(TargetData, OMPD_target_data)
837-
MS(TargetEnterData, OMPD_target_enter_data)
838-
MS(TargetExitData, OMPD_target_exit_data)
839-
MS(TargetUpdate, OMPD_target_update)
840-
MS(Task, OMPD_task)
841-
MS(Taskloop, OMPD_taskloop)
842-
MS(Teams, OMPD_teams)
843-
// clang-format on
844-
);
845-
auto &t0 = std::get<std::optional<wrapped::DirectiveNameModifier>>(inp.v.t);
828+
auto &mods = semantics::OmpGetModifiers(inp.v);
829+
auto *m0 =
830+
semantics::OmpGetUniqueModifier<parser::OmpDirectiveNameModifier>(mods);
846831
auto &t1 = std::get<parser::ScalarLogicalExpr>(inp.v.t);
847-
return If{{/*DirectiveNameModifier=*/maybeApply(convert, t0),
848-
/*IfExpression=*/makeExpr(t1, semaCtx)}};
832+
return If{
833+
{/*DirectiveNameModifier=*/maybeApplyToV([](auto &&s) { return s; }, m0),
834+
/*IfExpression=*/makeExpr(t1, semaCtx)}};
849835
}
850836

851837
// Inbranch: empty
@@ -889,20 +875,20 @@ IsDevicePtr make(const parser::OmpClause::IsDevicePtr &inp,
889875
Lastprivate make(const parser::OmpClause::Lastprivate &inp,
890876
semantics::SemanticsContext &semaCtx) {
891877
// inp.v -> parser::OmpLastprivateClause
892-
using wrapped = parser::OmpLastprivateClause;
893-
894878
CLAUSET_ENUM_CONVERT( //
895-
convert, parser::OmpLastprivateClause::LastprivateModifier,
879+
convert, parser::OmpLastprivateModifier::Value,
896880
Lastprivate::LastprivateModifier,
897881
// clang-format off
898882
MS(Conditional, Conditional)
899883
// clang-format on
900884
);
901885

902-
auto &t0 = std::get<std::optional<wrapped::LastprivateModifier>>(inp.v.t);
886+
auto &mods = semantics::OmpGetModifiers(inp.v);
887+
auto *m0 =
888+
semantics::OmpGetUniqueModifier<parser::OmpLastprivateModifier>(mods);
903889
auto &t1 = std::get<parser::OmpObjectList>(inp.v.t);
904890

905-
return Lastprivate{{/*LastprivateModifier=*/maybeApply(convert, t0),
891+
return Lastprivate{{/*LastprivateModifier=*/maybeApplyToV(convert, m0),
906892
/*List=*/makeObjects(t1, semaCtx)}};
907893
}
908894

flang/lib/Parser/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ add_flang_library(FortranParser
3030
LINK_COMPONENTS
3131
Support
3232
FrontendOpenACC
33+
FrontendOpenMP
3334

3435
DEPENDS
3536
omp_gen

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,58 @@
1616
#include "token-parsers.h"
1717
#include "type-parser-implementation.h"
1818
#include "flang/Parser/parse-tree.h"
19+
#include "llvm/ADT/ArrayRef.h"
20+
#include "llvm/ADT/STLExtras.h"
21+
#include "llvm/ADT/StringRef.h"
22+
#include "llvm/Frontend/OpenMP/OMP.h"
1923

2024
// OpenMP Directives and Clauses
2125
namespace Fortran::parser {
2226

2327
constexpr auto startOmpLine = skipStuffBeforeStatement >> "!$OMP "_sptok;
2428
constexpr auto endOmpLine = space >> endOfLine;
2529

30+
/// Parse OpenMP directive name (this includes compound directives).
31+
struct OmpDirectiveNameParser {
32+
using resultType = llvm::omp::Directive;
33+
using Token = TokenStringMatch<false, false>;
34+
35+
std::optional<resultType> Parse(ParseState &state) const {
36+
for (const NameWithId &nid : directives()) {
37+
if (attempt(Token(nid.first.data())).Parse(state)) {
38+
return nid.second;
39+
}
40+
}
41+
return std::nullopt;
42+
}
43+
44+
private:
45+
using NameWithId = std::pair<std::string, llvm::omp::Directive>;
46+
47+
llvm::iterator_range<const NameWithId *> directives() const;
48+
void initTokens(NameWithId *) const;
49+
};
50+
51+
llvm::iterator_range<const OmpDirectiveNameParser::NameWithId *>
52+
OmpDirectiveNameParser::directives() const {
53+
static NameWithId table[llvm::omp::Directive_enumSize];
54+
[[maybe_unused]] static bool init = (initTokens(table), true);
55+
return llvm::make_range(std::cbegin(table), std::cend(table));
56+
}
57+
58+
void OmpDirectiveNameParser::initTokens(NameWithId *table) const {
59+
for (size_t i{0}, e{llvm::omp::Directive_enumSize}; i != e; ++i) {
60+
auto id{static_cast<llvm::omp::Directive>(i)};
61+
llvm::StringRef name{llvm::omp::getOpenMPDirectiveName(id)};
62+
table[i] = std::make_pair(name.str(), id);
63+
}
64+
// Sort the table with respect to the directive name length in a descending
65+
// order. This is to make sure that longer names are tried first, before
66+
// any potential prefix (e.g. "target update" before "target").
67+
std::sort(table, table + llvm::omp::Directive_enumSize,
68+
[](auto &a, auto &b) { return a.first.size() > b.first.size(); });
69+
}
70+
2671
template <typename Clause, typename Separator> struct ModifierList {
2772
constexpr ModifierList(Separator sep) : sep_(sep) {}
2873
constexpr ModifierList(const ModifierList &) = default;
@@ -136,6 +181,9 @@ TYPE_PARSER(construct<OmpIterator>( //
136181
"ITERATOR" >>
137182
parenthesized(nonemptyList(sourced(Parser<OmpIteratorSpecifier>{})))))
138183

184+
TYPE_PARSER(construct<OmpLastprivateModifier>(
185+
"CONDITIONAL" >> pure(OmpLastprivateModifier::Value::Conditional)))
186+
139187
// 2.15.3.7 LINEAR (linear-list: linear-step)
140188
// linear-list -> list | modifier(list)
141189
// linear-modifier -> REF | VAL | UVAL
@@ -232,6 +280,11 @@ TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>(
232280
TYPE_PARSER(sourced(
233281
construct<OmpGrainsizeClause::Modifier>(Parser<OmpPrescriptiveness>{})))
234282

283+
TYPE_PARSER(sourced(construct<OmpIfClause::Modifier>(OmpDirectiveNameParser{})))
284+
285+
TYPE_PARSER(sourced(construct<OmpLastprivateClause::Modifier>(
286+
Parser<OmpLastprivateModifier>{})))
287+
235288
TYPE_PARSER(sourced(construct<OmpMapClause::Modifier>(
236289
sourced(construct<OmpMapClause::Modifier>(Parser<OmpMapTypeModifier>{}) ||
237290
construct<OmpMapClause::Modifier>(Parser<OmpMapper>{}) ||
@@ -345,22 +398,7 @@ TYPE_PARSER(construct<OmpDeviceTypeClause>(
345398

346399
// 2.12 IF (directive-name-modifier: scalar-logical-expr)
347400
TYPE_PARSER(construct<OmpIfClause>(
348-
maybe(
349-
("PARALLEL" >> pure(OmpIfClause::DirectiveNameModifier::Parallel) ||
350-
"SIMD" >> pure(OmpIfClause::DirectiveNameModifier::Simd) ||
351-
"TARGET ENTER DATA" >>
352-
pure(OmpIfClause::DirectiveNameModifier::TargetEnterData) ||
353-
"TARGET EXIT DATA" >>
354-
pure(OmpIfClause::DirectiveNameModifier::TargetExitData) ||
355-
"TARGET DATA" >>
356-
pure(OmpIfClause::DirectiveNameModifier::TargetData) ||
357-
"TARGET UPDATE" >>
358-
pure(OmpIfClause::DirectiveNameModifier::TargetUpdate) ||
359-
"TARGET" >> pure(OmpIfClause::DirectiveNameModifier::Target) ||
360-
"TASK"_id >> pure(OmpIfClause::DirectiveNameModifier::Task) ||
361-
"TASKLOOP" >> pure(OmpIfClause::DirectiveNameModifier::Taskloop) ||
362-
"TEAMS" >> pure(OmpIfClause::DirectiveNameModifier::Teams)) /
363-
":"),
401+
maybe(nonemptyList(Parser<OmpIfClause::Modifier>{}) / ":"),
364402
scalarLogicalExpr))
365403

366404
TYPE_PARSER(construct<OmpReductionClause>(
@@ -460,8 +498,7 @@ TYPE_PARSER(
460498

461499
// OMP 5.0 2.19.4.5 LASTPRIVATE ([lastprivate-modifier :] list)
462500
TYPE_PARSER(construct<OmpLastprivateClause>(
463-
maybe("CONDITIONAL" >>
464-
pure(OmpLastprivateClause::LastprivateModifier::Conditional) / ":"),
501+
maybe(nonemptyList(Parser<OmpLastprivateClause::Modifier>{}) / ":"),
465502
Parser<OmpObjectList>{}))
466503

467504
// OMP 5.2 11.7.1 BIND ( PARALLEL | TEAMS | THREAD )

flang/lib/Parser/unparse.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2074,6 +2074,9 @@ class UnparseVisitor {
20742074
},
20752075
x.u);
20762076
}
2077+
void Unparse(const OmpDirectiveNameModifier &x) {
2078+
Word(llvm::omp::getOpenMPDirectiveName(x.v));
2079+
}
20772080
void Unparse(const OmpIteratorSpecifier &x) {
20782081
Walk(std::get<TypeDeclarationStmt>(x.t));
20792082
Put(" = ");
@@ -2090,9 +2093,8 @@ class UnparseVisitor {
20902093
Put(")");
20912094
}
20922095
void Unparse(const OmpLastprivateClause &x) {
2093-
Walk(
2094-
std::get<std::optional<OmpLastprivateClause::LastprivateModifier>>(x.t),
2095-
":");
2096+
using Modifier = OmpLastprivateClause::Modifier;
2097+
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
20962098
Walk(std::get<OmpObjectList>(x.t));
20972099
}
20982100
void Unparse(const OmpMapClause &x) {
@@ -2127,7 +2129,8 @@ class UnparseVisitor {
21272129
Walk(std::get<OmpObjectList>(x.t));
21282130
}
21292131
void Unparse(const OmpIfClause &x) {
2130-
Walk(std::get<std::optional<OmpIfClause::DirectiveNameModifier>>(x.t), ":");
2132+
using Modifier = OmpIfClause::Modifier;
2133+
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
21312134
Walk(std::get<ScalarLogicalExpr>(x.t));
21322135
}
21332136
void Unparse(const OmpLinearClause::WithoutModifier &x) {
@@ -2837,8 +2840,7 @@ class UnparseVisitor {
28372840
WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default
28382841
WALK_NESTED_ENUM(OmpDefaultmapClause, ImplicitBehavior) // OMP defaultmap
28392842
WALK_NESTED_ENUM(OmpVariableCategory, Value) // OMP variable-category
2840-
WALK_NESTED_ENUM(
2841-
OmpLastprivateClause, LastprivateModifier) // OMP lastprivate-modifier
2843+
WALK_NESTED_ENUM(OmpLastprivateModifier, Value) // OMP lastprivate-modifier
28422844
WALK_NESTED_ENUM(OmpChunkModifier, Value) // OMP chunk-modifier
28432845
WALK_NESTED_ENUM(OmpLinearModifier, Value) // OMP linear-modifier
28442846
WALK_NESTED_ENUM(OmpOrderingModifier, Value) // OMP ordering-modifier
@@ -2849,7 +2851,6 @@ class UnparseVisitor {
28492851
OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type
28502852
WALK_NESTED_ENUM(OmpReductionModifier, Value) // OMP reduction-modifier
28512853
WALK_NESTED_ENUM(OmpExpectation, Value) // OMP motion-expectation
2852-
WALK_NESTED_ENUM(OmpIfClause, DirectiveNameModifier) // OMP directive-modifier
28532854
WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type
28542855
WALK_NESTED_ENUM(OmpOrderClause, Ordering) // OMP ordering
28552856
WALK_NESTED_ENUM(OmpOrderModifier, Value) // OMP order-modifier

0 commit comments

Comments
 (0)