Skip to content

Commit 4e453d5

Browse files
authored
[flang][OpenMP] Accept old FLUSH syntax in METADIRECTIVE (#130122)
Accommodate it in OmpDirectiveSpecification, which may become the primary component of the actual FLUSH construct in the future.
1 parent d679471 commit 4e453d5

File tree

5 files changed

+107
-12
lines changed

5 files changed

+107
-12
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@ class ParseTreeDumper {
491491
NODE(OmpWhenClause, Modifier)
492492
NODE(parser, OmpDirectiveName)
493493
NODE(parser, OmpDirectiveSpecification)
494+
NODE_ENUM(OmpDirectiveSpecification, Flags)
494495
NODE(parser, OmpTraitPropertyName)
495496
NODE(parser, OmpTraitScore)
496497
NODE(parser, OmpTraitPropertyExtension)

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4502,15 +4502,16 @@ struct OmpClauseList {
45024502
// --- Directives and constructs
45034503

45044504
struct OmpDirectiveSpecification {
4505-
CharBlock source;
4505+
ENUM_CLASS(Flags, None, DeprecatedSyntax);
45064506
TUPLE_CLASS_BOILERPLATE(OmpDirectiveSpecification);
45074507
llvm::omp::Directive DirId() const { //
45084508
return std::get<OmpDirectiveName>(t).v;
45094509
}
45104510
const OmpClauseList &Clauses() const;
45114511

4512+
CharBlock source;
45124513
std::tuple<OmpDirectiveName, std::optional<std::list<OmpArgument>>,
4513-
std::optional<OmpClauseList>>
4514+
std::optional<OmpClauseList>, Flags>
45144515
t;
45154516
};
45164517

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -996,10 +996,33 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>(
996996

997997
// --- Parsers for directives and constructs --------------------------
998998

999-
TYPE_PARSER(sourced(construct<OmpDirectiveSpecification>( //
1000-
sourced(OmpDirectiveNameParser{}),
1001-
maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
1002-
maybe(Parser<OmpClauseList>{}))))
999+
OmpDirectiveSpecification static makeFlushFromOldSyntax1(Verbatim &&text,
1000+
std::optional<OmpClauseList> &&clauses,
1001+
std::optional<std::list<OmpArgument>> &&args,
1002+
OmpDirectiveSpecification::Flags &&flags) {
1003+
return OmpDirectiveSpecification{OmpDirectiveName(text), std::move(args),
1004+
std::move(clauses), std::move(flags)};
1005+
}
1006+
1007+
TYPE_PARSER(sourced(
1008+
// Parse the old syntax: FLUSH [clauses] [(objects)]
1009+
construct<OmpDirectiveSpecification>(
1010+
// Force this old-syntax parser to fail for FLUSH followed by '('.
1011+
// Otherwise it could succeed on the new syntax but have one of
1012+
// lists absent in the parsed result.
1013+
// E.g. for FLUSH(x) SEQ_CST it would find no clauses following
1014+
// the directive name, parse the argument list "(x)" and stop.
1015+
applyFunction<OmpDirectiveSpecification>(makeFlushFromOldSyntax1,
1016+
verbatim("FLUSH"_tok) / !lookAhead("("_tok),
1017+
maybe(Parser<OmpClauseList>{}),
1018+
maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
1019+
pure(OmpDirectiveSpecification::Flags::DeprecatedSyntax))) ||
1020+
// Parse the standard syntax: directive [(arguments)] [clauses]
1021+
construct<OmpDirectiveSpecification>( //
1022+
sourced(OmpDirectiveNameParser{}),
1023+
maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
1024+
maybe(Parser<OmpClauseList>{}),
1025+
pure(OmpDirectiveSpecification::Flags::None))))
10031026

10041027
TYPE_PARSER(sourced(construct<OmpNothingDirective>("NOTHING" >> ok)))
10051028

flang/lib/Parser/unparse.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,14 +2094,30 @@ class UnparseVisitor {
20942094
Word(llvm::omp::getOpenMPDirectiveName(x).str());
20952095
}
20962096
void Unparse(const OmpDirectiveSpecification &x) {
2097-
using ArgList = std::list<parser::OmpArgument>;
2097+
auto unparseArgs{[&]() {
2098+
using ArgList = std::list<parser::OmpArgument>;
2099+
if (auto &args{std::get<std::optional<ArgList>>(x.t)}) {
2100+
Put("(");
2101+
Walk(*args);
2102+
Put(")");
2103+
}
2104+
}};
2105+
auto unparseClauses{[&]() { //
2106+
Walk(std::get<std::optional<OmpClauseList>>(x.t));
2107+
}};
2108+
20982109
Walk(std::get<OmpDirectiveName>(x.t));
2099-
if (auto &args{std::get<std::optional<ArgList>>(x.t)}) {
2100-
Put("(");
2101-
Walk(*args);
2102-
Put(")");
2110+
auto flags{std::get<OmpDirectiveSpecification::Flags>(x.t)};
2111+
if (flags == OmpDirectiveSpecification::Flags::DeprecatedSyntax) {
2112+
if (x.DirId() == llvm::omp::Directive::OMPD_flush) {
2113+
// FLUSH clause arglist
2114+
unparseClauses();
2115+
unparseArgs();
2116+
}
2117+
} else {
2118+
unparseArgs();
2119+
unparseClauses();
21032120
}
2104-
Walk(std::get<std::optional<OmpClauseList>>(x.t));
21052121
}
21062122
void Unparse(const OmpTraitScore &x) {
21072123
Word("SCORE(");
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=52 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
2+
!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=52 %s | FileCheck --check-prefix="PARSE-TREE" %s
3+
4+
subroutine f00()
5+
integer :: x
6+
!$omp metadirective when(user={condition(.true.)}: flush seq_cst (x))
7+
end
8+
9+
!UNPARSE: SUBROUTINE f00
10+
!UNPARSE: INTEGER x
11+
!UNPARSE: !$OMP METADIRECTIVE WHEN(USER={CONDITION(.true._4)}: FLUSH SEQ_CST(x))
12+
!UNPARSE: END SUBROUTINE
13+
14+
!PARSE-TREE: OmpMetadirectiveDirective
15+
!PARSE-TREE: | OmpClauseList -> OmpClause -> When -> OmpWhenClause
16+
!PARSE-TREE: | | Modifier -> OmpContextSelectorSpecification -> OmpTraitSetSelector
17+
!PARSE-TREE: | | | OmpTraitSetSelectorName -> Value = User
18+
!PARSE-TREE: | | | OmpTraitSelector
19+
!PARSE-TREE: | | | | OmpTraitSelectorName -> Value = Condition
20+
!PARSE-TREE: | | | | Properties
21+
!PARSE-TREE: | | | | | OmpTraitProperty -> Scalar -> Expr = '.true._4'
22+
!PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
23+
!PARSE-TREE: | | | | | | | bool = 'true'
24+
!PARSE-TREE: | | OmpDirectiveSpecification
25+
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = flush
26+
!PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x'
27+
!PARSE-TREE: | | | OmpClauseList -> OmpClause -> SeqCst
28+
!PARSE-TREE: | | | Flags = DeprecatedSyntax
29+
30+
subroutine f01()
31+
integer :: x
32+
!$omp metadirective when(user={condition(.true.)}: flush(x) seq_cst)
33+
end
34+
35+
!UNPARSE: SUBROUTINE f01
36+
!UNPARSE: INTEGER x
37+
!UNPARSE: !$OMP METADIRECTIVE WHEN(USER={CONDITION(.true._4)}: FLUSH(x) SEQ_CST)
38+
!UNPARSE: END SUBROUTINE
39+
40+
!PARSE-TREE: OmpMetadirectiveDirective
41+
!PARSE-TREE: | OmpClauseList -> OmpClause -> When -> OmpWhenClause
42+
!PARSE-TREE: | | Modifier -> OmpContextSelectorSpecification -> OmpTraitSetSelector
43+
!PARSE-TREE: | | | OmpTraitSetSelectorName -> Value = User
44+
!PARSE-TREE: | | | OmpTraitSelector
45+
!PARSE-TREE: | | | | OmpTraitSelectorName -> Value = Condition
46+
!PARSE-TREE: | | | | Properties
47+
!PARSE-TREE: | | | | | OmpTraitProperty -> Scalar -> Expr = '.true._4'
48+
!PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
49+
!PARSE-TREE: | | | | | | | bool = 'true'
50+
!PARSE-TREE: | | OmpDirectiveSpecification
51+
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = flush
52+
!PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x'
53+
!PARSE-TREE: | | | OmpClauseList -> OmpClause -> SeqCst
54+
!PARSE-TREE: | | | Flags = None

0 commit comments

Comments
 (0)