[flang-commits] [flang] [Flang][OpenMP]Make Do concurrent indices private (PR #93785)

via flang-commits flang-commits at lists.llvm.org
Wed Jun 19 22:45:25 PDT 2024


https://github.com/harishch4 updated https://github.com/llvm/llvm-project/pull/93785

>From 250f7cf93188b45e1f91bf642ca02c4bccc1a092 Mon Sep 17 00:00:00 2001
From: Harish Chambeti <harishcse44 at gmail.com>
Date: Thu, 30 May 2024 14:01:39 +0530
Subject: [PATCH 1/2] [Flang][OpenMP] Make Do concurrent indices private

---
 flang/lib/Semantics/resolve-directives.cpp    | 25 ++++++++++++++++---
 .../test/Semantics/OpenMP/doconcurrent01.f90  | 17 +++++++++++++
 2 files changed, 39 insertions(+), 3 deletions(-)
 create mode 100644 flang/test/Semantics/OpenMP/doconcurrent01.f90

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index dbc531372c3f4..3992d527c7ae5 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1698,10 +1698,10 @@ void OmpAttributeVisitor::ResolveSeqLoopIndexInParallelOrTaskConstruct(
 // Use of DO CONCURRENT inside OpenMP construct is unspecified behavior
 // till OpenMP-5.0 standard.
 // In above both cases we skip the privatization of iteration variables.
+// [OpenMP 5.1] DO CONCURRENT indices are private
 bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) {
-  // TODO:[OpenMP 5.1] DO CONCURRENT indices are private
-  if (x.IsDoNormal()) {
-    if (!dirContext_.empty() && GetContext().withinConstruct) {
+  if (!dirContext_.empty() && GetContext().withinConstruct) {
+    if (x.IsDoNormal()) {
       const parser::Name *iv{GetLoopIndex(x)};
       if (iv && iv->symbol) {
         if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) {
@@ -1721,6 +1721,25 @@ bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) {
           }
         }
       }
+    } else if (x.IsDoConcurrent()) {
+      const Fortran::parser::LoopControl *loopControl = &*x.GetLoopControl();
+      const Fortran::parser::LoopControl::Concurrent &concurrent =
+          std::get<Fortran::parser::LoopControl::Concurrent>(loopControl->u);
+      const Fortran::parser::ConcurrentHeader &concurrentHeader =
+          std::get<Fortran::parser::ConcurrentHeader>(concurrent.t);
+      const std::list<Fortran::parser::ConcurrentControl> &controls =
+          std::get<std::list<Fortran::parser::ConcurrentControl>>(
+              concurrentHeader.t);
+      for (const auto &control : controls) {
+        const parser::Name *iv{&std::get<0>(control.t)};
+        if (iv && iv->symbol) {
+          if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) {
+            ResolveSeqLoopIndexInParallelOrTaskConstruct(*iv);
+          } else {
+            // TODO: conflict checks with explicitly determined DSA
+          }
+        }
+      }
     }
   }
   return true;
diff --git a/flang/test/Semantics/OpenMP/doconcurrent01.f90 b/flang/test/Semantics/OpenMP/doconcurrent01.f90
new file mode 100644
index 0000000000000..7e3bdce871dd4
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/doconcurrent01.f90
@@ -0,0 +1,17 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! OpenMP 5.1.1
+! DO Concurrent indices are private
+
+!DEF: /private_iv (Subroutine)Subprogram
+subroutine private_iv
+   !DEF: /private_iv/i ObjectEntity INTEGER(4)
+   integer i
+   !$omp parallel default(private)
+   !$omp single
+   !DEF: /private_iv/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+   do concurrent(i=1:2)
+   end do
+   !$omp end single
+   !$omp end parallel
+end subroutine

>From 2a893c52594546dea99177982896347f9d9afbcf Mon Sep 17 00:00:00 2001
From: Harish Chambeti <harishcse44 at gmail.com>
Date: Thu, 20 Jun 2024 11:15:07 +0530
Subject: [PATCH 2/2] code refactor

---
 flang/lib/Semantics/resolve-directives.cpp | 47 +++++++++++-----------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 3992d527c7ae5..c7494ea352ab4 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1701,26 +1701,11 @@ void OmpAttributeVisitor::ResolveSeqLoopIndexInParallelOrTaskConstruct(
 // [OpenMP 5.1] DO CONCURRENT indices are private
 bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) {
   if (!dirContext_.empty() && GetContext().withinConstruct) {
+    llvm::SmallVector<const parser::Name *> ivs;
     if (x.IsDoNormal()) {
       const parser::Name *iv{GetLoopIndex(x)};
-      if (iv && iv->symbol) {
-        if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) {
-          ResolveSeqLoopIndexInParallelOrTaskConstruct(*iv);
-        } else {
-          // TODO: conflict checks with explicitly determined DSA
-        }
-        ordCollapseLevel--;
-        if (ordCollapseLevel) {
-          if (const auto *details{iv->symbol->detailsIf<HostAssocDetails>()}) {
-            const Symbol *tpSymbol = &details->symbol();
-            if (tpSymbol->test(Symbol::Flag::OmpThreadprivate)) {
-              context_.Say(iv->source,
-                  "Loop iteration variable %s is not allowed in THREADPRIVATE."_err_en_US,
-                  iv->ToString());
-            }
-          }
-        }
-      }
+      if (iv && iv->symbol)
+        ivs.push_back(iv);
     } else if (x.IsDoConcurrent()) {
       const Fortran::parser::LoopControl *loopControl = &*x.GetLoopControl();
       const Fortran::parser::LoopControl::Concurrent &concurrent =
@@ -1732,11 +1717,27 @@ bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) {
               concurrentHeader.t);
       for (const auto &control : controls) {
         const parser::Name *iv{&std::get<0>(control.t)};
-        if (iv && iv->symbol) {
-          if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) {
-            ResolveSeqLoopIndexInParallelOrTaskConstruct(*iv);
-          } else {
-            // TODO: conflict checks with explicitly determined DSA
+        if (iv && iv->symbol)
+          ivs.push_back(iv);
+      }
+    }
+    ordCollapseLevel--;
+    for (auto iv : ivs) {
+      if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) {
+        ResolveSeqLoopIndexInParallelOrTaskConstruct(*iv);
+      } else {
+        // TODO: conflict checks with explicitly determined DSA
+      }
+      if (ordCollapseLevel) {
+        if (const auto *details{iv->symbol->detailsIf<HostAssocDetails>()}) {
+          const Symbol *tpSymbol = &details->symbol();
+          // TODO: DoConcurrent won't capture the following check because a new
+          // symbol is declared in ResolveIndexName(), which will not have the
+          // OmpThreadprivate flag.
+          if (tpSymbol->test(Symbol::Flag::OmpThreadprivate)) {
+            context_.Say(iv->source,
+                "Loop iteration variable %s is not allowed in THREADPRIVATE."_err_en_US,
+                iv->ToString());
           }
         }
       }



More information about the flang-commits mailing list