Skip to content

[flang][OpenMP] Accept modern syntax of FLUSH construct #128975

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 3, 2025

Conversation

kparzysz
Copy link
Contributor

The syntax with the object list following the memory-order clause has been removed in OpenMP 5.2. Still, accept that syntax with versions >= 5.2, but treat it as deprecated (and emit a warning).

The syntax with the object list following the memory-order clause
has been removed in OpenMP 5.2. Still, accept that syntax with
versions >= 5.2, but treat it as deprecated (and emit a warning).
@llvmbot
Copy link
Member

llvmbot commented Feb 27, 2025

@llvm/pr-subscribers-flang-fir-hlfir
@llvm/pr-subscribers-flang-semantics

@llvm/pr-subscribers-flang-parser

Author: Krzysztof Parzyszek (kparzysz)

Changes

The syntax with the object list following the memory-order clause has been removed in OpenMP 5.2. Still, accept that syntax with versions >= 5.2, but treat it as deprecated (and emit a warning).


Full diff: https://github.com/llvm/llvm-project/pull/128975.diff

6 Files Affected:

  • (modified) flang/include/flang/Parser/parse-tree.h (+14-3)
  • (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+3-4)
  • (modified) flang/lib/Parser/openmp-parsers.cpp (+20-3)
  • (modified) flang/lib/Parser/unparse.cpp (+8-3)
  • (modified) flang/lib/Semantics/check-omp-structure.cpp (+12-2)
  • (modified) flang/test/Semantics/OpenMP/flush01.f90 (+4-4)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index d3b3d69015bf3..e42c0c0923bc9 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4888,12 +4888,23 @@ struct OpenMPDispatchConstruct {
       t;
 };
 
-// 2.17.8 flush -> FLUSH [memory-order-clause] [(variable-name-list)]
+// [4.5:162-165], [5.0:242-246], [5.1:275-279], [5.2:315-316], [6.0:498-500]
+//
+// flush-construct ->
+//    FLUSH [(list)]                                // since 4.5, until 4.5
+// flush-construct ->
+//    FLUSH [memory-order-clause] [(list)]          // since 5.0, until 5.1
+// flush-construct ->
+//    FLUSH [(list)] [clause-list]                  // since 5.2
+//
+// memory-order-clause ->                           // since 5.0, until 5.1
+//    ACQ_REL | RELEASE | ACQUIRE |                 // since 5.0
+//    SEQ_CST                                       // since 5.1
 struct OpenMPFlushConstruct {
   TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct);
   CharBlock source;
-  std::tuple<Verbatim, std::optional<std::list<OmpMemoryOrderClause>>,
-      std::optional<OmpObjectList>>
+  std::tuple<Verbatim, std::optional<OmpObjectList>,
+      std::optional<OmpClauseList>, /*TrailingClauses=*/bool>
       t;
 };
 
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 97b4778d488fa..7970d77da8a6b 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3275,13 +3275,12 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
   const auto &objectList =
       std::get<std::optional<parser::OmpObjectList>>(flushConstruct.t);
   const auto &clauseList =
-      std::get<std::optional<std::list<parser::OmpMemoryOrderClause>>>(
-          flushConstruct.t);
+      std::get<std::optional<parser::OmpClauseList>>(flushConstruct.t);
   ObjectList objects =
       objectList ? makeObjects(*objectList, semaCtx) : ObjectList{};
   List<Clause> clauses =
-      clauseList ? makeList(*clauseList,
-                            [&](auto &&s) { return makeClause(s.v, semaCtx); })
+      clauseList ? makeList(clauseList->v,
+                            [&](auto &&s) { return makeClause(s, semaCtx); })
                  : List<Clause>{};
   mlir::Location currentLocation = converter.genLocation(verbatim.source);
 
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 014b4f8c69574..9fd56b9f2bd0a 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1104,9 +1104,26 @@ TYPE_PARSER(sourced(construct<OmpAtomicClauseList>(
 TYPE_PARSER(sourced(construct<OpenMPDepobjConstruct>(verbatim("DEPOBJ"_tok),
     parenthesized(Parser<OmpObject>{}), sourced(Parser<OmpClause>{}))))
 
-TYPE_PARSER(sourced(construct<OpenMPFlushConstruct>(verbatim("FLUSH"_tok),
-    many(maybe(","_tok) >> sourced(Parser<OmpMemoryOrderClause>{})),
-    maybe(parenthesized(Parser<OmpObjectList>{})))))
+static OpenMPFlushConstruct makeFlushFromOldSyntax(
+    Verbatim &&text, std::optional<OmpClauseList> &&clauses,
+    std::optional<OmpObjectList> &&objects) {
+  bool oldSyntax{
+      clauses && !clauses->v.empty() && objects && !objects->v.empty()};
+  return OpenMPFlushConstruct{
+      std::move(text), std::move(objects), std::move(clauses),
+      /*TrailingClauses=*/!oldSyntax};
+}
+
+TYPE_PARSER(sourced( //
+    construct<OpenMPFlushConstruct>(
+        applyFunction<OpenMPFlushConstruct>(makeFlushFromOldSyntax,
+            verbatim("FLUSH"_tok), maybe(Parser<OmpClauseList>{}),
+            maybe(parenthesized(Parser<OmpObjectList>{})))) ||
+
+    construct<OpenMPFlushConstruct>(
+        verbatim("FLUSH"_tok),
+        maybe(parenthesized(Parser<OmpObjectList>{})),
+        Parser<OmpClauseList>{}, pure(/*TrailingClauses=*/true))))
 
 // Simple Standalone Directives
 TYPE_PARSER(sourced(construct<OmpSimpleStandaloneDirective>(first(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 960337b8a91b5..7b0524771cdc4 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2874,9 +2874,14 @@ class UnparseVisitor {
   }
   void Unparse(const OpenMPFlushConstruct &x) {
     BeginOpenMP();
-    Word("!$OMP FLUSH ");
-    Walk(std::get<std::optional<std::list<OmpMemoryOrderClause>>>(x.t));
-    Walk(" (", std::get<std::optional<OmpObjectList>>(x.t), ")");
+    Word("!$OMP FLUSH");
+    if (std::get</*ClausesTrailing=*/bool>(x.t)) {
+      Walk("(", std::get<std::optional<OmpObjectList>>(x.t), ")");
+      Walk(" ", std::get<std::optional<OmpClauseList>>(x.t));
+    } else {
+      Walk(" ", std::get<std::optional<OmpClauseList>>(x.t));
+      Walk(" (", std::get<std::optional<OmpObjectList>>(x.t), ")");
+    }
     Put("\n");
     EndOpenMP();
   }
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index c95cf0d5921cf..6a50455b97170 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2139,16 +2139,26 @@ void OmpStructureChecker::Enter(const parser::OpenMPFlushConstruct &x) {
 }
 
 void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &x) {
+  auto &flushList{std::get<std::optional<parser::OmpObjectList>>(x.t)};
+
   if (FindClause(llvm::omp::Clause::OMPC_acquire) ||
       FindClause(llvm::omp::Clause::OMPC_release) ||
       FindClause(llvm::omp::Clause::OMPC_acq_rel)) {
-    if (const auto &flushList{
-            std::get<std::optional<parser::OmpObjectList>>(x.t)}) {
+    if (flushList) {
       context_.Say(parser::FindSourceLocation(flushList),
           "If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items "
           "must not be specified on the FLUSH directive"_err_en_US);
     }
   }
+
+  unsigned version{context_.langOptions().OpenMPVersion};
+  if (version >= 52) {
+    if (!std::get</*TrailingClauses=*/bool>(x.t)) {
+      context_.Say(parser::FindSourceLocation(flushList),
+          "The syntax \"FLUSH clause (object, ...)\" has been deprecated, use \"FLUSH(object, ...) clause\" instead"_warn_en_US);
+    }
+  }
+
   dirContext_.pop_back();
 }
 
diff --git a/flang/test/Semantics/OpenMP/flush01.f90 b/flang/test/Semantics/OpenMP/flush01.f90
index 27324de4a8f7a..d0dbeb9c5cc96 100644
--- a/flang/test/Semantics/OpenMP/flush01.f90
+++ b/flang/test/Semantics/OpenMP/flush01.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50
 
 ! 2.17.8 Flush construct [OpenMP 5.0]
 !        memory-order-clause ->
@@ -22,13 +22,13 @@
     array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
     !$omp flush acquire
 
-    !ERROR: expected end of line
+    !ERROR: PRIVATE clause is not allowed on the FLUSH directive
     !$omp flush private(array)
-    !ERROR: expected end of line
+    !ERROR: NUM_THREADS clause is not allowed on the FLUSH directive
     !$omp flush num_threads(4)
 
     ! Mix allowed and not allowed clauses.
-    !ERROR: expected end of line
+    !ERROR: NUM_THREADS clause is not allowed on the FLUSH directive
     !$omp flush num_threads(4) acquire
   end if
   !$omp end parallel

Copy link

github-actions bot commented Feb 27, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@kparzysz kparzysz merged commit 9573c62 into llvm:main Mar 3, 2025
11 checks passed
@kparzysz kparzysz deleted the users/kparzysz/omp-flush-syntax branch March 3, 2025 13:59
jph-13 pushed a commit to jph-13/llvm-project that referenced this pull request Mar 21, 2025
The syntax with the object list following the memory-order clause has
been removed in OpenMP 5.2. Still, accept that syntax with versions >=
5.2, but treat it as deprecated (and emit a warning).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants