[llvm-branch-commits] [flang] [flang][OpenMP] Accept old FLUSH syntax in METADIRECTIVE (PR #130122)
Krzysztof Parzyszek via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Mar 6 11:13:35 PST 2025
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/130122
>From bf56b8c80a0f1a7e06dcd3e898172c27e5afabf5 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Wed, 5 Mar 2025 08:24:30 -0600
Subject: [PATCH 1/3] [flang][OpenMP] Accept old FLUSH syntax in METADIRECTIVE
Accommodate it in OmpDirectiveSpecification, which may become the
primary component of the actual FLUSH construct in the future.
---
flang/include/flang/Parser/dump-parse-tree.h | 1 +
flang/include/flang/Parser/parse-tree.h | 6 ++-
flang/lib/Parser/openmp-parsers.cpp | 32 +++++++++--
flang/lib/Parser/unparse.cpp | 28 +++++++---
.../Parser/OpenMP/metadirective-flush.f90 | 54 +++++++++++++++++++
5 files changed, 109 insertions(+), 12 deletions(-)
create mode 100644 flang/test/Parser/OpenMP/metadirective-flush.f90
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index a154794e41e9d..fcd902d25fa40 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -491,6 +491,7 @@ class ParseTreeDumper {
NODE(OmpWhenClause, Modifier)
NODE(parser, OmpDirectiveName)
NODE(parser, OmpDirectiveSpecification)
+ NODE_ENUM(OmpDirectiveSpecification, Flags)
NODE(parser, OmpTraitPropertyName)
NODE(parser, OmpTraitScore)
NODE(parser, OmpTraitPropertyExtension)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 346299b8e5215..a197249ebae91 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4503,13 +4503,15 @@ struct OmpClauseList {
// --- Directives and constructs
struct OmpDirectiveSpecification {
- CharBlock source;
+ ENUM_CLASS(Flags, None, DeprecatedSyntax);
TUPLE_CLASS_BOILERPLATE(OmpDirectiveSpecification);
llvm::omp::Directive DirId() const { //
return std::get<OmpDirectiveName>(t).v;
}
+
+ CharBlock source;
std::tuple<OmpDirectiveName, std::optional<std::list<OmpArgument>>,
- std::optional<OmpClauseList>>
+ std::optional<OmpClauseList>, Flags>
t;
};
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index b3e76d70c8064..0de7690b90262 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -995,10 +995,34 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>(
// --- Parsers for directives and constructs --------------------------
-TYPE_PARSER(sourced(construct<OmpDirectiveSpecification>( //
- sourced(OmpDirectiveNameParser{}),
- maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
- maybe(Parser<OmpClauseList>{}))))
+OmpDirectiveSpecification static makeFlushFromOldSyntax1(
+ Verbatim &&text, std::optional<OmpClauseList> &&clauses,
+ std::optional<std::list<OmpArgument>> &&args,
+ OmpDirectiveSpecification::Flags &&flags) {
+ return OmpDirectiveSpecification{OmpDirectiveName(text), std::move(args),
+ std::move(clauses), std::move(flags)};
+}
+
+TYPE_PARSER(sourced(
+ // Parse the old syntax: FLUSH [clauses] [(objects)]
+ construct<OmpDirectiveSpecification>( //
+ // Force this old-syntax parser to fail for FLUSH followed by '('.
+ // Otherwise it could succeed on the new syntax but have one of
+ // lists absent in the parsed result.
+ // E.g. for FLUSH(x) SEQ_CST it would find no clauses following
+ // the directive name, parse the argument list "(x)" and stop.
+ applyFunction(makeFlushFromOldSyntax1,
+ verbatim("FLUSH"_tok) / !lookAhead("("_tok),
+ maybe(Parser<OmpClauseList>{}),
+ maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
+ pure(OmpDirectiveSpecification::Flags::DeprecatedSyntax))) ||
+ // Parse the standard syntax: directive [(arguments)] [clauses]
+ construct<OmpDirectiveSpecification>( //
+ sourced(OmpDirectiveNameParser{}),
+ maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
+ maybe(Parser<OmpClauseList>{}),
+ pure(OmpDirectiveSpecification::Flags::None))
+))
TYPE_PARSER(sourced(construct<OmpNothingDirective>("NOTHING" >> ok)))
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 4f5c05dc2aa25..262077e62441b 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2094,14 +2094,30 @@ class UnparseVisitor {
Word(llvm::omp::getOpenMPDirectiveName(x).str());
}
void Unparse(const OmpDirectiveSpecification &x) {
- using ArgList = std::list<parser::OmpArgument>;
+ auto unparseArgs{[&]() {
+ using ArgList = std::list<parser::OmpArgument>;
+ if (auto &args{std::get<std::optional<ArgList>>(x.t)}) {
+ Put("(");
+ Walk(*args);
+ Put(")");
+ }
+ }};
+ auto unparseClauses{[&]() {
+ Walk(std::get<std::optional<OmpClauseList>>(x.t));
+ }};
+
Walk(std::get<OmpDirectiveName>(x.t));
- if (auto &args{std::get<std::optional<ArgList>>(x.t)}) {
- Put("(");
- Walk(*args);
- Put(")");
+ auto flags{std::get<OmpDirectiveSpecification::Flags>(x.t)};
+ if (flags == OmpDirectiveSpecification::Flags::DeprecatedSyntax) {
+ if (x.DirId() == llvm::omp::Directive::OMPD_flush) {
+ // FLUSH clause arglist
+ unparseClauses();
+ unparseArgs();
+ }
+ } else {
+ unparseArgs();
+ unparseClauses();
}
- Walk(std::get<std::optional<OmpClauseList>>(x.t));
}
void Unparse(const OmpTraitScore &x) {
Word("SCORE(");
diff --git a/flang/test/Parser/OpenMP/metadirective-flush.f90 b/flang/test/Parser/OpenMP/metadirective-flush.f90
new file mode 100644
index 0000000000000..8403663200f93
--- /dev/null
+++ b/flang/test/Parser/OpenMP/metadirective-flush.f90
@@ -0,0 +1,54 @@
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=52 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
+!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=52 %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+subroutine f00()
+ integer :: x
+ !$omp metadirective when(user={condition(.true.)}: flush seq_cst (x))
+end
+
+!UNPARSE: SUBROUTINE f00
+!UNPARSE: INTEGER x
+!UNPARSE: !$OMP METADIRECTIVE WHEN(USER={CONDITION(.true._4)}: FLUSH SEQ_CST(x))
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: OmpMetadirectiveDirective
+!PARSE-TREE: | OmpClauseList -> OmpClause -> When -> OmpWhenClause
+!PARSE-TREE: | | Modifier -> OmpContextSelectorSpecification -> OmpTraitSetSelector
+!PARSE-TREE: | | | OmpTraitSetSelectorName -> Value = User
+!PARSE-TREE: | | | OmpTraitSelector
+!PARSE-TREE: | | | | OmpTraitSelectorName -> Value = Condition
+!PARSE-TREE: | | | | Properties
+!PARSE-TREE: | | | | | OmpTraitProperty -> Scalar -> Expr = '.true._4'
+!PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
+!PARSE-TREE: | | | | | | | bool = 'true'
+!PARSE-TREE: | | OmpDirectiveSpecification
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = flush
+!PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x'
+!PARSE-TREE: | | | OmpClauseList -> OmpClause -> SeqCst
+!PARSE-TREE: | | | Flags = DeprecatedSyntax
+
+subroutine f01()
+ integer :: x
+ !$omp metadirective when(user={condition(.true.)}: flush(x) seq_cst)
+end
+
+!UNPARSE: SUBROUTINE f01
+!UNPARSE: INTEGER x
+!UNPARSE: !$OMP METADIRECTIVE WHEN(USER={CONDITION(.true._4)}: FLUSH(x) SEQ_CST)
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: OmpMetadirectiveDirective
+!PARSE-TREE: | OmpClauseList -> OmpClause -> When -> OmpWhenClause
+!PARSE-TREE: | | Modifier -> OmpContextSelectorSpecification -> OmpTraitSetSelector
+!PARSE-TREE: | | | OmpTraitSetSelectorName -> Value = User
+!PARSE-TREE: | | | OmpTraitSelector
+!PARSE-TREE: | | | | OmpTraitSelectorName -> Value = Condition
+!PARSE-TREE: | | | | Properties
+!PARSE-TREE: | | | | | OmpTraitProperty -> Scalar -> Expr = '.true._4'
+!PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
+!PARSE-TREE: | | | | | | | bool = 'true'
+!PARSE-TREE: | | OmpDirectiveSpecification
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = flush
+!PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x'
+!PARSE-TREE: | | | OmpClauseList -> OmpClause -> SeqCst
+!PARSE-TREE: | | | Flags = None
>From 00e6f062b3420d1edd0776262905c874e3267d53 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 6 Mar 2025 09:50:57 -0600
Subject: [PATCH 2/3] format
---
flang/lib/Parser/openmp-parsers.cpp | 11 +++++------
flang/lib/Parser/unparse.cpp | 2 +-
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 0de7690b90262..80831db0e7d50 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -995,17 +995,17 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>(
// --- Parsers for directives and constructs --------------------------
-OmpDirectiveSpecification static makeFlushFromOldSyntax1(
- Verbatim &&text, std::optional<OmpClauseList> &&clauses,
+OmpDirectiveSpecification static makeFlushFromOldSyntax1(Verbatim &&text,
+ std::optional<OmpClauseList> &&clauses,
std::optional<std::list<OmpArgument>> &&args,
OmpDirectiveSpecification::Flags &&flags) {
return OmpDirectiveSpecification{OmpDirectiveName(text), std::move(args),
- std::move(clauses), std::move(flags)};
+ std::move(clauses), std::move(flags)};
}
TYPE_PARSER(sourced(
// Parse the old syntax: FLUSH [clauses] [(objects)]
- construct<OmpDirectiveSpecification>( //
+ construct<OmpDirectiveSpecification>(
// Force this old-syntax parser to fail for FLUSH followed by '('.
// Otherwise it could succeed on the new syntax but have one of
// lists absent in the parsed result.
@@ -1021,8 +1021,7 @@ TYPE_PARSER(sourced(
sourced(OmpDirectiveNameParser{}),
maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
maybe(Parser<OmpClauseList>{}),
- pure(OmpDirectiveSpecification::Flags::None))
-))
+ pure(OmpDirectiveSpecification::Flags::None))))
TYPE_PARSER(sourced(construct<OmpNothingDirective>("NOTHING" >> ok)))
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 262077e62441b..12d86653a2b95 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2102,7 +2102,7 @@ class UnparseVisitor {
Put(")");
}
}};
- auto unparseClauses{[&]() {
+ auto unparseClauses{[&]() { //
Walk(std::get<std::optional<OmpClauseList>>(x.t));
}};
>From d7ce7a5e4083760842cbdf17ec4a5453800db213 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 6 Mar 2025 11:39:42 -0600
Subject: [PATCH 3/3] Fix MSVC build error
---
flang/lib/Parser/openmp-parsers.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 1115a3897f082..3175a234aab7a 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1013,7 +1013,7 @@ TYPE_PARSER(sourced(
// lists absent in the parsed result.
// E.g. for FLUSH(x) SEQ_CST it would find no clauses following
// the directive name, parse the argument list "(x)" and stop.
- applyFunction(makeFlushFromOldSyntax1,
+ applyFunction<OmpDirectiveSpecification>(makeFlushFromOldSyntax1,
verbatim("FLUSH"_tok) / !lookAhead("("_tok),
maybe(Parser<OmpClauseList>{}),
maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
More information about the llvm-branch-commits
mailing list