[flang-commits] [flang] 0fd425a - [flang]Add Semantic Checks for OpenMP Allocate Clause

Caroline Concatto via flang-commits flang-commits at lists.llvm.org
Wed Sep 9 04:09:36 PDT 2020


Author: Irina Dobrescu
Date: 2020-09-09T12:06:21+01:00
New Revision: 0fd425af071a9bc5c0891a4db09f4d9a466b7be9

URL: https://github.com/llvm/llvm-project/commit/0fd425af071a9bc5c0891a4db09f4d9a466b7be9
DIFF: https://github.com/llvm/llvm-project/commit/0fd425af071a9bc5c0891a4db09f4d9a466b7be9.diff

LOG: [flang]Add Semantic Checks for OpenMP Allocate Clause

Reviewed By: kiranchandramohan, clementval, kiranktp, raghavendhra

Differential Revision: https://reviews.llvm.org/D86051

Added: 
    flang/test/Semantics/omp-resolve06.f90

Modified: 
    flang/include/flang/Semantics/symbol.h
    flang/lib/Semantics/check-omp-structure.cpp
    flang/lib/Semantics/check-omp-structure.h
    flang/lib/Semantics/resolve-directives.cpp
    flang/test/Semantics/omp-clause-validity01.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 981abb8555f8..5f861d10332e 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -501,9 +501,9 @@ class Symbol {
       // OpenMP data-mapping attribute
       OmpMapTo, OmpMapFrom, OmpMapAlloc, OmpMapRelease, OmpMapDelete,
       // OpenMP miscellaneous flags
-      OmpCommonBlock, OmpReduction, OmpDeclareSimd, OmpDeclareTarget,
-      OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
-      OmpIfSpecified, OmpNone, OmpPreDetermined);
+      OmpCommonBlock, OmpReduction, OmpAllocate, OmpDeclareSimd,
+      OmpDeclareTarget, OmpThreadprivate, OmpDeclareReduction, OmpFlushed,
+      OmpCriticalLock, OmpIfSpecified, OmpNone, OmpPreDetermined);
   using Flags = common::EnumSet<Flag, Flag_enumSize>;
 
   const Scope &owner() const { return *owner_; }

diff  --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 6a4980ebcd54..3e360b8ec4ca 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -456,6 +456,9 @@ void OmpStructureChecker::Enter(const parser::OmpAlignedClause &x) {
   }
   // 2.8.1 TODO: list-item attribute check
 }
+void OmpStructureChecker::Enter(const parser::OmpAllocateClause &) {
+  CheckAllowed(llvm::omp::Clause::OMPC_allocate);
+}
 void OmpStructureChecker::Enter(const parser::OmpDefaultClause &) {
   CheckAllowed(llvm::omp::Clause::OMPC_default);
 }

diff  --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 9a0c1e2c0a2d..fbe95d0ee2e0 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -150,6 +150,7 @@ class OmpStructureChecker
   void Enter(const parser::OmpClause::IsDevicePtr &);
 
   void Enter(const parser::OmpAlignedClause &);
+  void Enter(const parser::OmpAllocateClause &);
   void Enter(const parser::OmpDefaultClause &);
   void Enter(const parser::OmpDefaultmapClause &);
   void Enter(const parser::OmpDependClause &);

diff  --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index e73bfa7c37cc..f68bcd1e1fa8 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -13,6 +13,7 @@
 #include "resolve-names-utils.h"
 #include "flang/Common/idioms.h"
 #include "flang/Evaluate/fold.h"
+#include "flang/Evaluate/type.h"
 #include "flang/Parser/parse-tree-visitor.h"
 #include "flang/Parser/parse-tree.h"
 #include "flang/Parser/tools.h"
@@ -226,7 +227,8 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
   }
 
   bool Pre(const parser::OpenMPBlockConstruct &);
-  void Post(const parser::OpenMPBlockConstruct &) { PopContext(); }
+  void Post(const parser::OpenMPBlockConstruct &);
+
   void Post(const parser::OmpBeginBlockDirective &) {
     GetContext().withinConstruct = true;
   }
@@ -254,6 +256,11 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
     ResolveOmpObjectList(x.v, Symbol::Flag::OmpPrivate);
     return false;
   }
+  bool Pre(const parser::OmpAllocateClause &x) {
+    const auto &objectList{std::get<parser::OmpObjectList>(x.t)};
+    ResolveOmpObjectList(objectList, Symbol::Flag::OmpAllocate);
+    return false;
+  }
   bool Pre(const parser::OmpClause::Firstprivate &x) {
     ResolveOmpObjectList(x.v, Symbol::Flag::OmpFirstPrivate);
     return false;
@@ -273,6 +280,10 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
       Symbol::Flag::OmpFirstPrivate, Symbol::Flag::OmpLastPrivate,
       Symbol::Flag::OmpReduction, Symbol::Flag::OmpLinear};
 
+  static constexpr Symbol::Flags privateDataSharingAttributeFlags{
+      Symbol::Flag::OmpPrivate, Symbol::Flag::OmpFirstPrivate,
+      Symbol::Flag::OmpLastPrivate};
+
   static constexpr Symbol::Flags ompFlagsRequireNewSymbol{
       Symbol::Flag::OmpPrivate, Symbol::Flag::OmpLinear,
       Symbol::Flag::OmpFirstPrivate, Symbol::Flag::OmpLastPrivate,
@@ -281,6 +292,21 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
   static constexpr Symbol::Flags ompFlagsRequireMark{
       Symbol::Flag::OmpThreadprivate};
 
+  std::vector<const parser::Name *> allocateNames_; // on one directive
+  SymbolSet privateDataSharingAttributeObjects_; // on one directive
+
+  void AddAllocateName(const parser::Name *&object) {
+    allocateNames_.push_back(object);
+  }
+  void ClearAllocateNames() { allocateNames_.clear(); }
+
+  void AddPrivateDataSharingAttributeObjects(SymbolRef object) {
+    privateDataSharingAttributeObjects_.insert(object);
+  }
+  void ClearPrivateDataSharingAttributeObjects() {
+    privateDataSharingAttributeObjects_.clear();
+  }
+
   // Predetermined DSA rules
   void PrivatizeAssociatedLoopIndex(const parser::OpenMPLoopConstruct &);
   void ResolveSeqLoopIndexInParallelOrTaskConstruct(const parser::Name &);
@@ -632,9 +658,49 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
     break;
   }
   ClearDataSharingAttributeObjects();
+  ClearPrivateDataSharingAttributeObjects();
+  ClearAllocateNames();
   return true;
 }
 
+void OmpAttributeVisitor::Post(const parser::OpenMPBlockConstruct &x) {
+  const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
+  const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
+  switch (beginDir.v) {
+  case llvm::omp::Directive::OMPD_parallel:
+  case llvm::omp::Directive::OMPD_single:
+  case llvm::omp::Directive::OMPD_target:
+  case llvm::omp::Directive::OMPD_task:
+  case llvm::omp::Directive::OMPD_teams:
+  case llvm::omp::Directive::OMPD_parallel_workshare:
+  case llvm::omp::Directive::OMPD_target_teams:
+  case llvm::omp::Directive::OMPD_target_parallel: {
+    bool hasPrivate;
+    for (const auto *allocName : allocateNames_) {
+      hasPrivate = false;
+      for (auto privateObj : privateDataSharingAttributeObjects_) {
+        const Symbol &symbolPrivate{*privateObj};
+        if (allocName->source == symbolPrivate.name()) {
+          hasPrivate = true;
+          break;
+        }
+      }
+      if (!hasPrivate) {
+        context_.Say(allocName->source,
+            "The ALLOCATE clause requires that '%s' must be listed in a "
+            "private "
+            "data-sharing attribute clause on the same directive"_err_en_US,
+            allocName->ToString());
+      }
+    }
+    break;
+  }
+  default:
+    break;
+  }
+  PopContext();
+}
+
 bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
   const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
   const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
@@ -879,6 +945,9 @@ void OmpAttributeVisitor::ResolveOmpObject(
                 if (dataSharingAttributeFlags.test(ompFlag)) {
                   CheckMultipleAppearances(*name, *symbol, ompFlag);
                 }
+                if (ompFlag == Symbol::Flag::OmpAllocate) {
+                  AddAllocateName(name);
+                }
               }
             } else {
               // Array sections to be changed to substrings as needed
@@ -976,6 +1045,9 @@ void OmpAttributeVisitor::CheckMultipleAppearances(
         name.ToString());
   } else {
     AddDataSharingAttributeObject(*target);
+    if (privateDataSharingAttributeFlags.test(ompFlag)) {
+      AddPrivateDataSharingAttributeObjects(*target);
+    }
   }
 }
 

diff  --git a/flang/test/Semantics/omp-clause-validity01.f90 b/flang/test/Semantics/omp-clause-validity01.f90
index d3f77a432de8..07f55733c8dc 100644
--- a/flang/test/Semantics/omp-clause-validity01.f90
+++ b/flang/test/Semantics/omp-clause-validity01.f90
@@ -9,7 +9,7 @@
 ! TODO: all the internal errors
 
   integer :: b = 128
-  integer :: c = 32
+  integer :: z, c = 32
   integer, parameter :: num = 16
   real(8) :: arrayA(256), arrayB(512)
 
@@ -39,29 +39,54 @@
   enddo
   !$omp end parallel
 
-  !$omp parallel allocate(b)
+  !$omp parallel private(b) allocate(b)
   do i = 1, N
      a = 3.14
   enddo
   !$omp end parallel
 
-  !$omp parallel allocate(omp_default_mem_space : b, c)
+  !$omp parallel private(c, b) allocate(omp_default_mem_space : b, c)
   do i = 1, N
      a = 3.14
   enddo
   !$omp end parallel
 
-  !$omp parallel allocate(b) allocate(c)
+  !$omp parallel allocate(b) allocate(c) private(b, c)
   do i = 1, N
      a = 3.14
   enddo
   !$omp end parallel
 
-  !$omp parallel allocate(xy_alloc :b) 
+  !$omp parallel allocate(xy_alloc :b) private(b)
   do i = 1, N
      a = 3.14
   enddo
   !$omp end parallel
+  
+  !$omp task private(b) allocate(b)
+  do i = 1, N
+     z = 2
+  end do
+  !$omp end task
+
+  !$omp teams private(b) allocate(b)
+  do i = 1, N
+     z = 2
+  end do
+  !$omp end teams
+
+  !$omp target private(b) allocate(b)
+  do i = 1, N
+     z = 2
+  end do
+  !$omp end target
+ 
+  !ERROR: ALLOCATE clause is not allowed on the TARGET DATA directive
+  !$omp target data map(from: b) allocate(b)
+  do i = 1, N
+     z = 2
+  enddo
+   !$omp end target data
 
   !ERROR: SCHEDULE clause is not allowed on the PARALLEL directive
   !$omp parallel schedule(static)

diff  --git a/flang/test/Semantics/omp-resolve06.f90 b/flang/test/Semantics/omp-resolve06.f90
new file mode 100644
index 000000000000..0909c0f54a57
--- /dev/null
+++ b/flang/test/Semantics/omp-resolve06.f90
@@ -0,0 +1,54 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+use omp_lib
+!2.11.4 Allocate Clause
+!For any list item that is specified in the allocate
+!clause on a directive, a data-sharing attribute clause
+!that may create a private copy of that list item must be
+!specified on the same directive.
+
+  integer ::  N = 2
+
+  !ERROR: The ALLOCATE clause requires that 'x' must be listed in a private data-sharing attribute clause on the same directive
+  !$omp parallel allocate(omp_default_mem_space : x)
+  do i = 1, N
+     x = 2
+  enddo
+  !$omp end parallel
+
+  !ERROR: The ALLOCATE clause requires that 'y' must be listed in a private data-sharing attribute clause on the same directive
+  !$omp parallel allocate(omp_default_mem_space : y) firstprivate(x)
+  do i = 1, N
+     x = 2
+  enddo
+  !$omp end parallel
+
+  !ERROR: The ALLOCATE clause requires that 'x' must be listed in a private data-sharing attribute clause on the same directive
+  !ERROR: The ALLOCATE clause requires that 'x' must be listed in a private data-sharing attribute clause on the same directive
+  !$omp parallel allocate(omp_default_mem_space : x) allocate(omp_default_mem_space : x)
+  do i = 1, N
+     x = 2
+  enddo
+  !$omp end parallel
+
+  !ERROR: The ALLOCATE clause requires that 'f' must be listed in a private data-sharing attribute clause on the same directive
+  !$omp parallel allocate(omp_default_mem_space : f) shared(f)
+  do i = 1, N
+     x = 2
+  enddo
+  !$omp end parallel
+
+  !ERROR: The ALLOCATE clause requires that 'q' must be listed in a private data-sharing attribute clause on the same directive
+  !$omp parallel private(t) allocate(omp_default_mem_space : z, t, q, r) firstprivate(z, r)
+  do i = 1, N
+     x = 2
+  enddo
+  !$omp end parallel
+
+  !ERROR: The ALLOCATE clause requires that 'b' must be listed in a private data-sharing attribute clause on the same directive
+  !ERROR: The ALLOCATE clause requires that 'c' must be listed in a private data-sharing attribute clause on the same directive
+  !$omp parallel allocate(omp_default_mem_space : a, b, c, d) firstprivate(a, d)
+  do i = 1, N
+     x = 2
+  enddo
+  !$omp end parallel
+end


        


More information about the flang-commits mailing list