Skip to content

Commit fe3ec47

Browse files
committed
[flang][OpenMP] Parse WHEN, OTHERWISE, MATCH clauses plus METADIRECTIVE
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 3bfe74e commit fe3ec47

File tree

12 files changed

+377
-8
lines changed

12 files changed

+377
-8
lines changed

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

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

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

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3456,6 +3456,14 @@ WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
34563456
struct OmpClause;
34573457
struct OmpClauseList;
34583458

3459+
struct OmpDirectiveSpecification {
3460+
TUPLE_CLASS_BOILERPLATE(OmpDirectiveSpecification);
3461+
std::tuple<llvm::omp::Directive,
3462+
std::optional<common::Indirection<OmpClauseList>>>
3463+
t;
3464+
CharBlock source;
3465+
};
3466+
34593467
// 2.1 Directives or clauses may accept a list or extended-list.
34603468
// A list item is a variable, array section or common block name (enclosed
34613469
// in slashes). An extended list item is a list item or a procedure Name.
@@ -3964,6 +3972,7 @@ struct OmpBindClause {
39643972
// data-sharing-attribute ->
39653973
// SHARED | NONE | // since 4.5
39663974
// PRIVATE | FIRSTPRIVATE // since 5.0
3975+
// See also otherwise-clause.
39673976
struct OmpDefaultClause {
39683977
ENUM_CLASS(DataSharingAttribute, Private, Firstprivate, Shared, None)
39693978
WRAPPER_CLASS_BOILERPLATE(OmpDefaultClause, DataSharingAttribute);
@@ -4184,6 +4193,16 @@ struct OmpMapClause {
41844193
std::tuple<MODIFIERS(), OmpObjectList, /*CommaSeparated=*/bool> t;
41854194
};
41864195

4196+
// Ref: [5.0:58-60], [5.1:63-68], [5.2:194-195]
4197+
//
4198+
// match-clause ->
4199+
// MATCH (context-selector-specification) // since 5.0
4200+
struct OmpMatchClause {
4201+
// The context-selector is an argument.
4202+
WRAPPER_CLASS_BOILERPLATE(
4203+
OmpMatchClause, traits::OmpContextSelectorSpecification);
4204+
};
4205+
41874206
// Ref: [5.2:217-218]
41884207
// message-clause ->
41894208
// MESSAGE("message-text")
@@ -4214,6 +4233,17 @@ struct OmpOrderClause {
42144233
std::tuple<MODIFIERS(), Ordering> t;
42154234
};
42164235

4236+
// Ref: [5.0:56-57], [5.1:60-62], [5.2:191]
4237+
//
4238+
// otherwise-clause ->
4239+
// DEFAULT ([directive-specification]) // since 5.0, until 5.1
4240+
// otherwise-clause ->
4241+
// OTHERWISE ([directive-specification])] // since 5.2
4242+
struct OmpOtherwiseClause {
4243+
WRAPPER_CLASS_BOILERPLATE(
4244+
OmpOtherwiseClause, std::optional<OmpDirectiveSpecification>);
4245+
};
4246+
42174247
// Ref: [4.5:46-50], [5.0:74-78], [5.1:92-96], [5.2:229-230]
42184248
//
42194249
// proc-bind-clause ->
@@ -4299,6 +4329,17 @@ struct OmpUpdateClause {
42994329
std::variant<OmpDependenceType, OmpTaskDependenceType> u;
43004330
};
43014331

4332+
// Ref: [5.0:56-57], [5.1:60-62], [5.2:190-191]
4333+
//
4334+
// when-clause ->
4335+
// WHEN (context-selector :
4336+
// [directive-specification]) // since 5.0
4337+
struct OmpWhenClause {
4338+
TUPLE_CLASS_BOILERPLATE(OmpWhenClause);
4339+
MODIFIER_BOILERPLATE(OmpContextSelector);
4340+
std::tuple<MODIFIERS(), std::optional<OmpDirectiveSpecification>> t;
4341+
};
4342+
43024343
// OpenMP Clauses
43034344
struct OmpClause {
43044345
UNION_CLASS_BOILERPLATE(OmpClause);
@@ -4323,6 +4364,12 @@ struct OmpClauseList {
43234364

43244365
// --- Directives and constructs
43254366

4367+
struct OmpMetadirectiveDirective {
4368+
TUPLE_CLASS_BOILERPLATE(OmpMetadirectiveDirective);
4369+
std::tuple<OmpClauseList> t;
4370+
CharBlock source;
4371+
};
4372+
43264373
// Ref: [5.1:89-90], [5.2:216]
43274374
//
43284375
// nothing-directive ->
@@ -4696,7 +4743,7 @@ struct OpenMPStandaloneConstruct {
46964743
CharBlock source;
46974744
std::variant<OpenMPSimpleStandaloneConstruct, OpenMPFlushConstruct,
46984745
OpenMPCancelConstruct, OpenMPCancellationPointConstruct,
4699-
OpenMPDepobjConstruct>
4746+
OpenMPDepobjConstruct, OmpMetadirectiveDirective>
47004747
u;
47014748
};
47024749

flang/lib/Lower/OpenMP/Clauses.cpp

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

231231
MAKE_INCOMPLETE_CLASS(AdjustArgs, AdjustArgs);
232232
MAKE_INCOMPLETE_CLASS(AppendArgs, AppendArgs);
233-
MAKE_INCOMPLETE_CLASS(Match, Match);
233+
// MAKE_INCOMPLETE_CLASS(Match, Match);
234234
// MAKE_INCOMPLETE_CLASS(Otherwise, ); // missing-in-parser
235-
MAKE_INCOMPLETE_CLASS(When, When);
235+
// MAKE_INCOMPLETE_CLASS(When, When);
236236

237237
List<IteratorSpecifier>
238238
makeIteratorSpecifiers(const parser::OmpIteratorSpecifier &inp,
@@ -997,7 +997,11 @@ Map make(const parser::OmpClause::Map &inp,
997997
/*LocatorList=*/makeObjects(t4, semaCtx)}};
998998
}
999999

1000-
// Match: incomplete
1000+
Match make(const parser::OmpClause::Match &inp,
1001+
semantics::SemanticsContext &semaCtx) {
1002+
return Match{};
1003+
}
1004+
10011005
// MemoryOrder: empty
10021006
// Mergeable: empty
10031007

@@ -1102,6 +1106,10 @@ Ordered make(const parser::OmpClause::Ordered &inp,
11021106
}
11031107

11041108
// Otherwise: incomplete, missing-in-parser
1109+
Otherwise make(const parser::OmpClause::Otherwise &inp,
1110+
semantics::SemanticsContext &semaCtx) {
1111+
return Otherwise{};
1112+
}
11051113

11061114
Partial make(const parser::OmpClause::Partial &inp,
11071115
semantics::SemanticsContext &semaCtx) {
@@ -1356,7 +1364,12 @@ UsesAllocators make(const parser::OmpClause::UsesAllocators &inp,
13561364
}
13571365

13581366
// Weak: empty
1359-
// When: incomplete
1367+
1368+
When make(const parser::OmpClause::When &inp,
1369+
semantics::SemanticsContext &semaCtx) {
1370+
return When{};
1371+
}
1372+
13601373
// Write: empty
13611374
} // namespace clause
13621375

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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2809,6 +2809,11 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
28092809
TODO(converter.getCurrentLocation(), "OpenMPDepobjConstruct");
28102810
}
28112811

2812+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
2813+
semantics::SemanticsContext &semaCtx,
2814+
lower::pft::Evaluation &eval,
2815+
const parser::OmpMetadirectiveDirective &construct) {}
2816+
28122817
static void
28132818
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
28142819
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 28 additions & 1 deletion
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(); }
@@ -496,6 +499,9 @@ TYPE_PARSER(sourced(construct<OmpToClause::Modifier>(
496499
construct<OmpToClause::Modifier>(Parser<OmpMapper>{}) ||
497500
construct<OmpToClause::Modifier>(Parser<OmpIterator>{})))))
498501

502+
TYPE_PARSER(sourced(construct<OmpWhenClause::Modifier>( //
503+
Parser<OmpContextSelector>{})))
504+
499505
// --- Parsers for clauses --------------------------------------------
500506

501507
/// `MOBClause` is a clause that has a
@@ -693,6 +699,16 @@ TYPE_PARSER(construct<OmpOrderClause>(
693699
maybe(nonemptyList(Parser<OmpOrderClause::Modifier>{}) / ":"),
694700
"CONCURRENT" >> pure(OmpOrderClause::Ordering::Concurrent)))
695701

702+
TYPE_PARSER(construct<OmpMatchClause>(
703+
Parser<traits::OmpContextSelectorSpecification>{}))
704+
705+
TYPE_PARSER(construct<OmpOtherwiseClause>(
706+
maybe(sourced(Parser<OmpDirectiveSpecification>{}))))
707+
708+
TYPE_PARSER(construct<OmpWhenClause>(
709+
maybe(nonemptyList(Parser<OmpWhenClause::Modifier>{}) / ":"),
710+
maybe(sourced(Parser<OmpDirectiveSpecification>{}))))
711+
696712
// OMP 5.2 12.6.1 grainsize([ prescriptiveness :] scalar-integer-expression)
697713
TYPE_PARSER(construct<OmpGrainsizeClause>(
698714
maybe(nonemptyList(Parser<OmpGrainsizeClause::Modifier>{}) / ":"),
@@ -810,6 +826,8 @@ TYPE_PARSER(
810826
parenthesized(Parser<OmpObjectList>{}))) ||
811827
"MAP" >> construct<OmpClause>(construct<OmpClause::Map>(
812828
parenthesized(Parser<OmpMapClause>{}))) ||
829+
"MATCH" >> construct<OmpClause>(construct<OmpClause::Match>(
830+
parenthesized(Parser<OmpMatchClause>{}))) ||
813831
"MERGEABLE" >> construct<OmpClause>(construct<OmpClause::Mergeable>()) ||
814832
"MESSAGE" >> construct<OmpClause>(construct<OmpClause::Message>(
815833
parenthesized(Parser<OmpMessageClause>{}))) ||
@@ -830,6 +848,8 @@ TYPE_PARSER(
830848
parenthesized(Parser<OmpOrderClause>{}))) ||
831849
"ORDERED" >> construct<OmpClause>(construct<OmpClause::Ordered>(
832850
maybe(parenthesized(scalarIntConstantExpr)))) ||
851+
"OTHERWISE" >> construct<OmpClause>(construct<OmpClause::Otherwise>(
852+
maybe(parenthesized(Parser<OmpOtherwiseClause>{})))) ||
833853
"PARTIAL" >> construct<OmpClause>(construct<OmpClause::Partial>(
834854
maybe(parenthesized(scalarIntConstantExpr)))) ||
835855
"PRIORITY" >> construct<OmpClause>(construct<OmpClause::Priority>(
@@ -885,7 +905,9 @@ TYPE_PARSER(
885905
parenthesized(nonemptyList(name)))) ||
886906
"UNTIED" >> construct<OmpClause>(construct<OmpClause::Untied>()) ||
887907
"UPDATE" >> construct<OmpClause>(construct<OmpClause::Update>(
888-
parenthesized(Parser<OmpUpdateClause>{}))))
908+
parenthesized(Parser<OmpUpdateClause>{}))) ||
909+
"WHEN" >> construct<OmpClause>(construct<OmpClause::When>(
910+
parenthesized(Parser<OmpWhenClause>{}))))
889911

890912
// [Clause, [Clause], ...]
891913
TYPE_PARSER(sourced(construct<OmpClauseList>(
@@ -905,6 +927,9 @@ TYPE_PARSER(sourced(construct<OpenMPUtilityConstruct>(
905927
sourced(construct<OpenMPUtilityConstruct>(
906928
sourced(Parser<OmpNothingDirective>{}))))))
907929

930+
TYPE_PARSER(sourced(construct<OmpMetadirectiveDirective>(
931+
"METADIRECTIVE" >> Parser<OmpClauseList>{})))
932+
908933
// Omp directives enclosing do loop
909934
TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
910935
"DISTRIBUTE PARALLEL DO SIMD" >>
@@ -1050,6 +1075,8 @@ TYPE_PARSER(
10501075
construct<OpenMPStandaloneConstruct>(Parser<OpenMPCancelConstruct>{}) ||
10511076
construct<OpenMPStandaloneConstruct>(
10521077
Parser<OpenMPCancellationPointConstruct>{}) ||
1078+
construct<OpenMPStandaloneConstruct>(
1079+
Parser<OmpMetadirectiveDirective>{}) ||
10531080
construct<OpenMPStandaloneConstruct>(Parser<OpenMPDepobjConstruct>{})) /
10541081
endOfLine)
10551082

flang/lib/Parser/unparse.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2070,6 +2070,10 @@ class UnparseVisitor {
20702070
void Unparse(const llvm::omp::Directive &x) {
20712071
Word(llvm::omp::getOpenMPDirectiveName(x).str());
20722072
}
2073+
void Unparse(const OmpDirectiveSpecification &x) {
2074+
Walk(std::get<llvm::omp::Directive>(x.t));
2075+
Walk(std::get<std::optional<common::Indirection<OmpClauseList>>>(x.t));
2076+
}
20732077
void Unparse(const OmpTraitScore &x) {
20742078
Word("SCORE(");
20752079
Walk(x.v);
@@ -2291,6 +2295,11 @@ class UnparseVisitor {
22912295
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
22922296
Walk(std::get<OmpObjectList>(x.t));
22932297
}
2298+
void Unparse(const OmpWhenClause &x) {
2299+
using Modifier = OmpWhenClause::Modifier;
2300+
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
2301+
Walk(std::get<std::optional<OmpDirectiveSpecification>>(x.t));
2302+
}
22942303
#define GEN_FLANG_CLAUSE_UNPARSE
22952304
#include "llvm/Frontend/OpenMP/OMP.inc"
22962305
void Unparse(const OmpLoopDirective &x) {
@@ -2800,6 +2809,13 @@ class UnparseVisitor {
28002809
},
28012810
x.u);
28022811
}
2812+
void Unparse(const OmpMetadirectiveDirective &x) {
2813+
BeginOpenMP();
2814+
Word("!$OMP METADIRECTIVE ");
2815+
Walk(std::get<OmpClauseList>(x.t));
2816+
Put("\n");
2817+
EndOpenMP();
2818+
}
28032819
void Unparse(const OpenMPDepobjConstruct &x) {
28042820
BeginOpenMP();
28052821
Word("!$OMP DEPOBJ");

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ class AssociatedLoopChecker {
214214
};
215215

216216
bool OmpStructureChecker::CheckAllowedClause(llvmOmpClause clause) {
217+
// Do not do clause checks while processing METADIRECTIVE.
218+
if (GetDirectiveNest(ContextSelectorNest) > 0) {
219+
return true;
220+
}
221+
217222
unsigned version{context_.langOptions().OpenMPVersion};
218223
DirectiveContext &dirCtx = GetContext();
219224
llvm::omp::Directive dir{dirCtx.directive};
@@ -590,6 +595,22 @@ void OmpStructureChecker::CheckHintClause(
590595
}
591596
}
592597

598+
void OmpStructureChecker::Enter(const parser::OmpDirectiveSpecification &x) {
599+
PushContextAndClauseSets(x.source, std::get<llvm::omp::Directive>(x.t));
600+
}
601+
602+
void OmpStructureChecker::Leave(const parser::OmpDirectiveSpecification &) {
603+
dirContext_.pop_back();
604+
}
605+
606+
void OmpStructureChecker::Enter(const parser::OmpMetadirectiveDirective &x) {
607+
PushContextAndClauseSets(x.source, llvm::omp::Directive::OMPD_metadirective);
608+
}
609+
610+
void OmpStructureChecker::Leave(const parser::OmpMetadirectiveDirective &) {
611+
dirContext_.pop_back();
612+
}
613+
593614
void OmpStructureChecker::Enter(const parser::OpenMPConstruct &x) {
594615
// Simd Construct with Ordered Construct Nesting check
595616
// We cannot use CurrentDirectiveIsNested() here because
@@ -2894,6 +2915,7 @@ CHECK_SIMPLE_CLAUSE(Nocontext, OMPC_nocontext)
28942915
CHECK_SIMPLE_CLAUSE(Severity, OMPC_severity)
28952916
CHECK_SIMPLE_CLAUSE(Message, OMPC_message)
28962917
CHECK_SIMPLE_CLAUSE(Filter, OMPC_filter)
2918+
CHECK_SIMPLE_CLAUSE(Otherwise, OMPC_otherwise)
28972919
CHECK_SIMPLE_CLAUSE(When, OMPC_when)
28982920
CHECK_SIMPLE_CLAUSE(AdjustArgs, OMPC_adjust_args)
28992921
CHECK_SIMPLE_CLAUSE(AppendArgs, OMPC_append_args)
@@ -4441,6 +4463,14 @@ void OmpStructureChecker::Enter(const parser::OmpClause::OmpxBare &x) {
44414463
}
44424464
}
44434465

4466+
void OmpStructureChecker::Enter(const parser::OmpContextSelector &ctxSel) {
4467+
EnterDirectiveNest(ContextSelectorNest);
4468+
}
4469+
4470+
void OmpStructureChecker::Leave(const parser::OmpContextSelector &) {
4471+
ExitDirectiveNest(ContextSelectorNest);
4472+
}
4473+
44444474
llvm::StringRef OmpStructureChecker::getClauseName(llvm::omp::Clause clause) {
44454475
return llvm::omp::getOpenMPClauseName(clause);
44464476
}

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,15 @@ class OmpStructureChecker
144144
void Enter(const parser::DoConstruct &);
145145
void Leave(const parser::DoConstruct &);
146146

147+
void Enter(const parser::OmpDirectiveSpecification &);
148+
void Leave(const parser::OmpDirectiveSpecification &);
149+
150+
void Enter(const parser::OmpMetadirectiveDirective &);
151+
void Leave(const parser::OmpMetadirectiveDirective &);
152+
153+
void Enter(const parser::OmpContextSelector &);
154+
void Leave(const parser::OmpContextSelector &);
155+
147156
#define GEN_FLANG_CLAUSE_CHECK_ENTER
148157
#include "llvm/Frontend/OpenMP/OMP.inc"
149158

@@ -280,7 +289,8 @@ class OmpStructureChecker
280289
TargetBlockOnlyTeams,
281290
TargetNest,
282291
DeclarativeNest,
283-
LastType = DeclarativeNest,
292+
ContextSelectorNest,
293+
LastType = ContextSelectorNest,
284294
};
285295
int directiveNest_[LastType + 1] = {0};
286296

0 commit comments

Comments
 (0)