Skip to content

Commit 15ab7be

Browse files
authored
[flang][OpenMP] Parse WHEN, OTHERWISE, MATCH clauses plus METADIRECTIVE (#121817)
Parse METADIRECTIVE as a standalone executable directive at the moment. This will allow testing the parser code. There is no lowering, not even clause conversion yet. There is also no verification of the allowed values for trait sets, trait properties.
1 parent abc8812 commit 15ab7be

File tree

13 files changed

+476
-32
lines changed

13 files changed

+476
-32
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,12 @@ class ParseTreeDumper {
477477
NODE(parser, NullInit)
478478
NODE(parser, ObjectDecl)
479479
NODE(parser, OldParameterStmt)
480+
NODE(parser, OmpMetadirectiveDirective)
481+
NODE(parser, OmpMatchClause)
482+
NODE(parser, OmpOtherwiseClause)
483+
NODE(parser, OmpWhenClause)
484+
NODE(OmpWhenClause, Modifier)
485+
NODE(parser, OmpDirectiveSpecification)
480486
NODE(parser, OmpTraitPropertyName)
481487
NODE(parser, OmpTraitScore)
482488
NODE(parser, OmpTraitPropertyExtension)

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

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3459,6 +3459,14 @@ WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
34593459
struct OmpClause;
34603460
struct OmpClauseList;
34613461

3462+
struct OmpDirectiveSpecification {
3463+
TUPLE_CLASS_BOILERPLATE(OmpDirectiveSpecification);
3464+
std::tuple<llvm::omp::Directive,
3465+
std::optional<common::Indirection<OmpClauseList>>>
3466+
t;
3467+
CharBlock source;
3468+
};
3469+
34623470
// 2.1 Directives or clauses may accept a list or extended-list.
34633471
// A list item is a variable, array section or common block name (enclosed
34643472
// in slashes). An extended list item is a list item or a procedure Name.
@@ -3962,14 +3970,21 @@ struct OmpBindClause {
39623970

39633971
// Ref: [4.5:46-50], [5.0:74-78], [5.1:92-96], [5.2:109]
39643972
//
3973+
// When used as a data-sharing clause:
39653974
// default-clause ->
39663975
// DEFAULT(data-sharing-attribute) // since 4.5
39673976
// data-sharing-attribute ->
39683977
// SHARED | NONE | // since 4.5
39693978
// PRIVATE | FIRSTPRIVATE // since 5.0
3979+
//
3980+
// When used in METADIRECTIVE:
3981+
// default-clause ->
3982+
// DEFAULT(directive-specification) // since 5.0, until 5.1
3983+
// See also otherwise-clause.
39703984
struct OmpDefaultClause {
39713985
ENUM_CLASS(DataSharingAttribute, Private, Firstprivate, Shared, None)
3972-
WRAPPER_CLASS_BOILERPLATE(OmpDefaultClause, DataSharingAttribute);
3986+
UNION_CLASS_BOILERPLATE(OmpDefaultClause);
3987+
std::variant<DataSharingAttribute, OmpDirectiveSpecification> u;
39733988
};
39743989

39753990
// Ref: [4.5:103-107], [5.0:324-325], [5.1:357-358], [5.2:161-162]
@@ -4187,6 +4202,16 @@ struct OmpMapClause {
41874202
std::tuple<MODIFIERS(), OmpObjectList, /*CommaSeparated=*/bool> t;
41884203
};
41894204

4205+
// Ref: [5.0:58-60], [5.1:63-68], [5.2:194-195]
4206+
//
4207+
// match-clause ->
4208+
// MATCH (context-selector-specification) // since 5.0
4209+
struct OmpMatchClause {
4210+
// The context-selector is an argument.
4211+
WRAPPER_CLASS_BOILERPLATE(
4212+
OmpMatchClause, traits::OmpContextSelectorSpecification);
4213+
};
4214+
41904215
// Ref: [5.2:217-218]
41914216
// message-clause ->
41924217
// MESSAGE("message-text")
@@ -4217,6 +4242,17 @@ struct OmpOrderClause {
42174242
std::tuple<MODIFIERS(), Ordering> t;
42184243
};
42194244

4245+
// Ref: [5.0:56-57], [5.1:60-62], [5.2:191]
4246+
//
4247+
// otherwise-clause ->
4248+
// DEFAULT ([directive-specification]) // since 5.0, until 5.1
4249+
// otherwise-clause ->
4250+
// OTHERWISE ([directive-specification])] // since 5.2
4251+
struct OmpOtherwiseClause {
4252+
WRAPPER_CLASS_BOILERPLATE(
4253+
OmpOtherwiseClause, std::optional<OmpDirectiveSpecification>);
4254+
};
4255+
42204256
// Ref: [4.5:46-50], [5.0:74-78], [5.1:92-96], [5.2:229-230]
42214257
//
42224258
// proc-bind-clause ->
@@ -4302,6 +4338,17 @@ struct OmpUpdateClause {
43024338
std::variant<OmpDependenceType, OmpTaskDependenceType> u;
43034339
};
43044340

4341+
// Ref: [5.0:56-57], [5.1:60-62], [5.2:190-191]
4342+
//
4343+
// when-clause ->
4344+
// WHEN (context-selector :
4345+
// [directive-specification]) // since 5.0
4346+
struct OmpWhenClause {
4347+
TUPLE_CLASS_BOILERPLATE(OmpWhenClause);
4348+
MODIFIER_BOILERPLATE(OmpContextSelector);
4349+
std::tuple<MODIFIERS(), std::optional<OmpDirectiveSpecification>> t;
4350+
};
4351+
43054352
// OpenMP Clauses
43064353
struct OmpClause {
43074354
UNION_CLASS_BOILERPLATE(OmpClause);
@@ -4326,6 +4373,12 @@ struct OmpClauseList {
43264373

43274374
// --- Directives and constructs
43284375

4376+
struct OmpMetadirectiveDirective {
4377+
TUPLE_CLASS_BOILERPLATE(OmpMetadirectiveDirective);
4378+
std::tuple<OmpClauseList> t;
4379+
CharBlock source;
4380+
};
4381+
43294382
// Ref: [5.1:89-90], [5.2:216]
43304383
//
43314384
// nothing-directive ->
@@ -4724,7 +4777,7 @@ struct OpenMPStandaloneConstruct {
47244777
CharBlock source;
47254778
std::variant<OpenMPSimpleStandaloneConstruct, OpenMPFlushConstruct,
47264779
OpenMPCancelConstruct, OpenMPCancellationPointConstruct,
4727-
OpenMPDepobjConstruct>
4780+
OpenMPDepobjConstruct, OmpMetadirectiveDirective>
47284781
u;
47294782
};
47304783

flang/lib/Lower/OpenMP/Clauses.cpp

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,6 @@ MAKE_EMPTY_CLASS(Threadprivate, Threadprivate);
230230

231231
MAKE_INCOMPLETE_CLASS(AdjustArgs, AdjustArgs);
232232
MAKE_INCOMPLETE_CLASS(AppendArgs, AppendArgs);
233-
MAKE_INCOMPLETE_CLASS(Match, Match);
234-
// MAKE_INCOMPLETE_CLASS(Otherwise, ); // missing-in-parser
235-
MAKE_INCOMPLETE_CLASS(When, When);
236233

237234
List<IteratorSpecifier>
238235
makeIteratorSpecifiers(const parser::OmpIteratorSpecifier &inp,
@@ -528,8 +525,13 @@ Copyprivate make(const parser::OmpClause::Copyprivate &inp,
528525
return Copyprivate{/*List=*/makeObjects(inp.v, semaCtx)};
529526
}
530527

531-
Default make(const parser::OmpClause::Default &inp,
532-
semantics::SemanticsContext &semaCtx) {
528+
// The Default clause is overloaded in OpenMP 5.0 and 5.1: it can be either
529+
// a data-sharing clause, or a METADIRECTIVE clause. In the latter case, it
530+
// has been superseded by the OTHERWISE clause.
531+
// Disambiguate this in this representation: for the DSA case, create Default,
532+
// and in the other case create Otherwise.
533+
Default makeDefault(const parser::OmpClause::Default &inp,
534+
semantics::SemanticsContext &semaCtx) {
533535
// inp.v -> parser::OmpDefaultClause
534536
using wrapped = parser::OmpDefaultClause;
535537

@@ -543,7 +545,13 @@ Default make(const parser::OmpClause::Default &inp,
543545
// clang-format on
544546
);
545547

546-
return Default{/*DataSharingAttribute=*/convert(inp.v.v)};
548+
auto dsa = std::get<wrapped::DataSharingAttribute>(inp.v.u);
549+
return Default{/*DataSharingAttribute=*/convert(dsa)};
550+
}
551+
552+
Otherwise makeOtherwise(const parser::OmpClause::Default &inp,
553+
semantics::SemanticsContext &semaCtx) {
554+
return Otherwise{};
547555
}
548556

549557
Defaultmap make(const parser::OmpClause::Defaultmap &inp,
@@ -997,7 +1005,11 @@ Map make(const parser::OmpClause::Map &inp,
9971005
/*LocatorList=*/makeObjects(t4, semaCtx)}};
9981006
}
9991007

1000-
// Match: incomplete
1008+
Match make(const parser::OmpClause::Match &inp,
1009+
semantics::SemanticsContext &semaCtx) {
1010+
return Match{};
1011+
}
1012+
10011013
// MemoryOrder: empty
10021014
// Mergeable: empty
10031015

@@ -1101,7 +1113,11 @@ Ordered make(const parser::OmpClause::Ordered &inp,
11011113
return Ordered{/*N=*/maybeApply(makeExprFn(semaCtx), inp.v)};
11021114
}
11031115

1104-
// Otherwise: incomplete, missing-in-parser
1116+
// See also Default.
1117+
Otherwise make(const parser::OmpClause::Otherwise &inp,
1118+
semantics::SemanticsContext &semaCtx) {
1119+
return Otherwise{};
1120+
}
11051121

11061122
Partial make(const parser::OmpClause::Partial &inp,
11071123
semantics::SemanticsContext &semaCtx) {
@@ -1356,15 +1372,32 @@ UsesAllocators make(const parser::OmpClause::UsesAllocators &inp,
13561372
}
13571373

13581374
// Weak: empty
1359-
// When: incomplete
1375+
1376+
When make(const parser::OmpClause::When &inp,
1377+
semantics::SemanticsContext &semaCtx) {
1378+
return When{};
1379+
}
1380+
13601381
// Write: empty
13611382
} // namespace clause
13621383

13631384
Clause makeClause(const parser::OmpClause &cls,
13641385
semantics::SemanticsContext &semaCtx) {
1365-
return Fortran::common::visit(
1366-
[&](auto &&s) {
1367-
return makeClause(cls.Id(), clause::make(s, semaCtx), cls.source);
1386+
return Fortran::common::visit( //
1387+
common::visitors{
1388+
[&](const parser::OmpClause::Default &s) {
1389+
using DSA = parser::OmpDefaultClause::DataSharingAttribute;
1390+
if (std::holds_alternative<DSA>(s.v.u)) {
1391+
return makeClause(llvm::omp::Clause::OMPC_default,
1392+
clause::makeDefault(s, semaCtx), cls.source);
1393+
} else {
1394+
return makeClause(llvm::omp::Clause::OMPC_otherwise,
1395+
clause::makeOtherwise(s, semaCtx), cls.source);
1396+
}
1397+
},
1398+
[&](auto &&s) {
1399+
return makeClause(cls.Id(), clause::make(s, semaCtx), cls.source);
1400+
},
13681401
},
13691402
cls.u);
13701403
}

flang/lib/Lower/OpenMP/Clauses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ using OmpxBare = tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy>;
257257
using OmpxDynCgroupMem = tomp::clause::OmpxDynCgroupMemT<TypeTy, IdTy, ExprTy>;
258258
using Ordered = tomp::clause::OrderedT<TypeTy, IdTy, ExprTy>;
259259
using Order = tomp::clause::OrderT<TypeTy, IdTy, ExprTy>;
260+
using Otherwise = tomp::clause::OtherwiseT<TypeTy, IdTy, ExprTy>;
260261
using Partial = tomp::clause::PartialT<TypeTy, IdTy, ExprTy>;
261262
using Priority = tomp::clause::PriorityT<TypeTy, IdTy, ExprTy>;
262263
using Private = tomp::clause::PrivateT<TypeTy, IdTy, ExprTy>;

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,9 @@ extractOmpDirective(const parser::OpenMPConstruct &ompConstruct) {
416416
[](const parser::OpenMPCancellationPointConstruct &c) {
417417
return llvm::omp::OMPD_cancellation_point;
418418
},
419+
[](const parser::OmpMetadirectiveDirective &c) {
420+
return llvm::omp::OMPD_metadirective;
421+
},
419422
[](const parser::OpenMPDepobjConstruct &c) {
420423
return llvm::omp::OMPD_depobj;
421424
}},
@@ -3231,6 +3234,11 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
32313234
TODO(converter.getCurrentLocation(), "OpenMPDepobjConstruct");
32323235
}
32333236

3237+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3238+
semantics::SemanticsContext &semaCtx,
3239+
lower::pft::Evaluation &eval,
3240+
const parser::OmpMetadirectiveDirective &construct) {}
3241+
32343242
static void
32353243
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
32363244
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ static TypeDeclarationStmt makeIterSpecDecl(std::list<ObjectName> &&names) {
153153
makeEntityList(std::move(names)));
154154
}
155155

156+
TYPE_PARSER(sourced(construct<OmpDirectiveSpecification>(
157+
OmpDirectiveNameParser{}, maybe(indirect(Parser<OmpClauseList>{})))))
158+
156159
// --- Parsers for context traits -------------------------------------
157160

158161
static std::string nameToString(Name &&name) { return name.ToString(); }
@@ -501,6 +504,9 @@ TYPE_PARSER(sourced(construct<OmpToClause::Modifier>(
501504
construct<OmpToClause::Modifier>(Parser<OmpMapper>{}) ||
502505
construct<OmpToClause::Modifier>(Parser<OmpIterator>{})))))
503506

507+
TYPE_PARSER(sourced(construct<OmpWhenClause::Modifier>( //
508+
Parser<OmpContextSelector>{})))
509+
504510
// --- Parsers for clauses --------------------------------------------
505511

506512
/// `MOBClause` is a clause that has a
@@ -527,13 +533,18 @@ TYPE_PARSER(construct<OmpAffinityClause>(
527533
Parser<OmpObjectList>{}))
528534

529535
// 2.15.3.1 DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE)
530-
TYPE_PARSER(construct<OmpDefaultClause>(
536+
TYPE_PARSER(construct<OmpDefaultClause::DataSharingAttribute>(
531537
"PRIVATE" >> pure(OmpDefaultClause::DataSharingAttribute::Private) ||
532538
"FIRSTPRIVATE" >>
533539
pure(OmpDefaultClause::DataSharingAttribute::Firstprivate) ||
534540
"SHARED" >> pure(OmpDefaultClause::DataSharingAttribute::Shared) ||
535541
"NONE" >> pure(OmpDefaultClause::DataSharingAttribute::None)))
536542

543+
TYPE_PARSER(construct<OmpDefaultClause>(
544+
construct<OmpDefaultClause>(
545+
Parser<OmpDefaultClause::DataSharingAttribute>{}) ||
546+
construct<OmpDefaultClause>(Parser<OmpDirectiveSpecification>{})))
547+
537548
// 2.5 PROC_BIND (MASTER | CLOSE | PRIMARY | SPREAD)
538549
TYPE_PARSER(construct<OmpProcBindClause>(
539550
"CLOSE" >> pure(OmpProcBindClause::AffinityPolicy::Close) ||
@@ -698,6 +709,16 @@ TYPE_PARSER(construct<OmpOrderClause>(
698709
maybe(nonemptyList(Parser<OmpOrderClause::Modifier>{}) / ":"),
699710
"CONCURRENT" >> pure(OmpOrderClause::Ordering::Concurrent)))
700711

712+
TYPE_PARSER(construct<OmpMatchClause>(
713+
Parser<traits::OmpContextSelectorSpecification>{}))
714+
715+
TYPE_PARSER(construct<OmpOtherwiseClause>(
716+
maybe(sourced(Parser<OmpDirectiveSpecification>{}))))
717+
718+
TYPE_PARSER(construct<OmpWhenClause>(
719+
maybe(nonemptyList(Parser<OmpWhenClause::Modifier>{}) / ":"),
720+
maybe(sourced(Parser<OmpDirectiveSpecification>{}))))
721+
701722
// OMP 5.2 12.6.1 grainsize([ prescriptiveness :] scalar-integer-expression)
702723
TYPE_PARSER(construct<OmpGrainsizeClause>(
703724
maybe(nonemptyList(Parser<OmpGrainsizeClause::Modifier>{}) / ":"),
@@ -815,6 +836,8 @@ TYPE_PARSER(
815836
parenthesized(Parser<OmpObjectList>{}))) ||
816837
"MAP" >> construct<OmpClause>(construct<OmpClause::Map>(
817838
parenthesized(Parser<OmpMapClause>{}))) ||
839+
"MATCH" >> construct<OmpClause>(construct<OmpClause::Match>(
840+
parenthesized(Parser<OmpMatchClause>{}))) ||
818841
"MERGEABLE" >> construct<OmpClause>(construct<OmpClause::Mergeable>()) ||
819842
"MESSAGE" >> construct<OmpClause>(construct<OmpClause::Message>(
820843
parenthesized(Parser<OmpMessageClause>{}))) ||
@@ -839,6 +862,8 @@ TYPE_PARSER(
839862
parenthesized(Parser<OmpOrderClause>{}))) ||
840863
"ORDERED" >> construct<OmpClause>(construct<OmpClause::Ordered>(
841864
maybe(parenthesized(scalarIntConstantExpr)))) ||
865+
"OTHERWISE" >> construct<OmpClause>(construct<OmpClause::Otherwise>(
866+
maybe(parenthesized(Parser<OmpOtherwiseClause>{})))) ||
842867
"PARTIAL" >> construct<OmpClause>(construct<OmpClause::Partial>(
843868
maybe(parenthesized(scalarIntConstantExpr)))) ||
844869
"PRIORITY" >> construct<OmpClause>(construct<OmpClause::Priority>(
@@ -894,7 +919,9 @@ TYPE_PARSER(
894919
parenthesized(nonemptyList(name)))) ||
895920
"UNTIED" >> construct<OmpClause>(construct<OmpClause::Untied>()) ||
896921
"UPDATE" >> construct<OmpClause>(construct<OmpClause::Update>(
897-
parenthesized(Parser<OmpUpdateClause>{}))))
922+
parenthesized(Parser<OmpUpdateClause>{}))) ||
923+
"WHEN" >> construct<OmpClause>(construct<OmpClause::When>(
924+
parenthesized(Parser<OmpWhenClause>{}))))
898925

899926
// [Clause, [Clause], ...]
900927
TYPE_PARSER(sourced(construct<OmpClauseList>(
@@ -914,6 +941,9 @@ TYPE_PARSER(sourced(construct<OpenMPUtilityConstruct>(
914941
sourced(construct<OpenMPUtilityConstruct>(
915942
sourced(Parser<OmpNothingDirective>{}))))))
916943

944+
TYPE_PARSER(sourced(construct<OmpMetadirectiveDirective>(
945+
"METADIRECTIVE" >> Parser<OmpClauseList>{})))
946+
917947
// Omp directives enclosing do loop
918948
TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
919949
"DISTRIBUTE PARALLEL DO SIMD" >>
@@ -1059,6 +1089,8 @@ TYPE_PARSER(
10591089
construct<OpenMPStandaloneConstruct>(Parser<OpenMPCancelConstruct>{}) ||
10601090
construct<OpenMPStandaloneConstruct>(
10611091
Parser<OpenMPCancellationPointConstruct>{}) ||
1092+
construct<OpenMPStandaloneConstruct>(
1093+
Parser<OmpMetadirectiveDirective>{}) ||
10621094
construct<OpenMPStandaloneConstruct>(Parser<OpenMPDepobjConstruct>{})) /
10631095
endOfLine)
10641096

0 commit comments

Comments
 (0)