[flang-commits] [flang] e73d8c7 - [flang][openacc] Semantic check for cache directive

via flang-commits flang-commits at lists.llvm.org
Wed Nov 25 07:28:23 PST 2020


Author: Valentin Clement
Date: 2020-11-25T10:28:14-05:00
New Revision: e73d8c793a5028b8ba93b9b9a82d059760c3ec4d

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

LOG: [flang][openacc] Semantic check for cache directive

Add semantic check for the cache directive. According to section 2.10 from the specification:
A var in a cache directive must be a single array element or a simple subarray.

Reviewed By: kiranchandramohan

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

Added: 
    

Modified: 
    flang/lib/Semantics/check-acc-structure.cpp
    flang/lib/Semantics/check-acc-structure.h
    flang/lib/Semantics/resolve-directives.cpp
    flang/test/Semantics/acc-clause-validity.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp
index 8c05b585dda5..edcb41eae0c5 100644
--- a/flang/lib/Semantics/check-acc-structure.cpp
+++ b/flang/lib/Semantics/check-acc-structure.cpp
@@ -238,6 +238,15 @@ void AccStructureChecker::Leave(const parser::OpenACCAtomicConstruct &x) {
   dirContext_.pop_back();
 }
 
+void AccStructureChecker::Enter(const parser::OpenACCCacheConstruct &x) {
+  const auto &verbatim = std::get<parser::Verbatim>(x.t);
+  PushContextAndClauseSets(verbatim.source, llvm::acc::Directive::ACCD_cache);
+  SetContextDirectiveSource(verbatim.source);
+}
+void AccStructureChecker::Leave(const parser::OpenACCCacheConstruct &x) {
+  dirContext_.pop_back();
+}
+
 // Clause checkers
 CHECK_REQ_SCALAR_INT_CONSTANT_CLAUSE(Collapse, ACCC_collapse)
 

diff  --git a/flang/lib/Semantics/check-acc-structure.h b/flang/lib/Semantics/check-acc-structure.h
index 04c08b14598c..e2ea3899c98b 100644
--- a/flang/lib/Semantics/check-acc-structure.h
+++ b/flang/lib/Semantics/check-acc-structure.h
@@ -59,6 +59,8 @@ class AccStructureChecker
   void Leave(const parser::OpenACCWaitConstruct &);
   void Enter(const parser::OpenACCAtomicConstruct &);
   void Leave(const parser::OpenACCAtomicConstruct &);
+  void Enter(const parser::OpenACCCacheConstruct &);
+  void Leave(const parser::OpenACCCacheConstruct &);
 
   // Clauses
   void Leave(const parser::AccClauseList &);

diff  --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 65606d119dc4..f34cb69beca9 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -140,6 +140,9 @@ class AccAttributeVisitor : DirectiveAttributeVisitor<llvm::acc::Directive> {
     GetContext().withinConstruct = true;
   }
 
+  bool Pre(const parser::OpenACCCacheConstruct &);
+  void Post(const parser::OpenACCCacheConstruct &) { PopContext(); }
+
   void Post(const parser::AccDefaultClause &);
 
   bool Pre(const parser::AccClause::Copy &x) {
@@ -209,6 +212,7 @@ class AccAttributeVisitor : DirectiveAttributeVisitor<llvm::acc::Directive> {
   Symbol *DeclareOrMarkOtherAccessEntity(Symbol &, Symbol::Flag);
   void CheckMultipleAppearances(
       const parser::Name &, const Symbol &, Symbol::Flag);
+  void AllowOnlyArrayAndSubArray(const parser::AccObjectList &objectList);
 };
 
 // Data-sharing and Data-mapping attributes for data-refs in OpenMP construct
@@ -450,7 +454,6 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCLoopConstruct &x) {
 bool AccAttributeVisitor::Pre(const parser::OpenACCStandaloneConstruct &x) {
   const auto &standaloneDir{std::get<parser::AccStandaloneDirective>(x.t)};
   switch (standaloneDir.v) {
-  case llvm::acc::Directive::ACCD_cache:
   case llvm::acc::Directive::ACCD_enter_data:
   case llvm::acc::Directive::ACCD_exit_data:
   case llvm::acc::Directive::ACCD_init:
@@ -483,6 +486,64 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCCombinedConstruct &x) {
   return true;
 }
 
+static bool IsLastNameArray(const parser::Designator &designator) {
+  const auto &name{GetLastName(designator)};
+  const evaluate::DataRef dataRef{*(name.symbol)};
+  return std::visit(
+      common::visitors{
+          [](const evaluate::SymbolRef &ref) { return ref->Rank() > 0; },
+          [](const evaluate::ArrayRef &aref) {
+            return aref.base().IsSymbol() ||
+                aref.base().GetComponent().base().Rank() == 0;
+          },
+          [](const auto &) { return false; },
+      },
+      dataRef.u);
+}
+
+void AccAttributeVisitor::AllowOnlyArrayAndSubArray(
+    const parser::AccObjectList &objectList) {
+  for (const auto &accObject : objectList.v) {
+    std::visit(
+        common::visitors{
+            [&](const parser::Designator &designator) {
+              if (!IsLastNameArray(designator))
+                context_.Say(designator.source,
+                    "Only array element or subarray are allowed in %s directive"_err_en_US,
+                    parser::ToUpperCaseLetters(
+                        llvm::acc::getOpenACCDirectiveName(
+                            GetContext().directive)
+                            .str()));
+            },
+            [&](const auto &name) {
+              context_.Say(name.source,
+                  "Only array element or subarray are allowed in %s directive"_err_en_US,
+                  parser::ToUpperCaseLetters(
+                      llvm::acc::getOpenACCDirectiveName(GetContext().directive)
+                          .str()));
+            },
+        },
+        accObject.u);
+  }
+}
+
+bool AccAttributeVisitor::Pre(const parser::OpenACCCacheConstruct &x) {
+  const auto &verbatim{std::get<parser::Verbatim>(x.t)};
+  PushContext(verbatim.source, llvm::acc::Directive::ACCD_cache);
+  ClearDataSharingAttributeObjects();
+
+  const auto &objectListWithModifier =
+      std::get<parser::AccObjectListWithModifier>(x.t);
+  const auto &objectList =
+      std::get<Fortran::parser::AccObjectList>(objectListWithModifier.t);
+
+  // 2.10 Cache directive restriction: A var in a cache directive must be a
+  // single array element or a simple subarray.
+  AllowOnlyArrayAndSubArray(objectList);
+
+  return true;
+}
+
 std::int64_t AccAttributeVisitor::GetAssociatedLoopLevelFromClauses(
     const parser::AccClauseList &x) {
   std::int64_t collapseLevel{0};

diff  --git a/flang/test/Semantics/acc-clause-validity.f90 b/flang/test/Semantics/acc-clause-validity.f90
index da053d5fdeab..b2fb57796f3f 100644
--- a/flang/test/Semantics/acc-clause-validity.f90
+++ b/flang/test/Semantics/acc-clause-validity.f90
@@ -11,6 +11,7 @@
 !   2.14.3 Set
 !   2.14.4 Update
 !   2.15.1 Routine
+!   2.10 Cache
 !   2.11 Parallel Loop
 !   2.11 Kernels Loop
 !   2.11 Serial Loop
@@ -21,6 +22,11 @@ program openacc_clause_validity
 
   implicit none
 
+  type atype
+    real(8), dimension(10) :: arr
+    real(8) :: s
+  end type atype
+
   integer :: i, j, b, gang_size, vector_size, worker_size
   integer, parameter :: N = 256
   integer, dimension(N) :: c
@@ -31,6 +37,8 @@ program openacc_clause_validity
   logical :: reduction_l
   real(8), dimension(N, N) :: aa, bb, cc
   logical :: ifCondition = .TRUE.
+  type(atype) :: t
+  type(atype), dimension(10) :: ta
 
   !ERROR: At least one clause is required on the DECLARE directive
   !$acc declare
@@ -646,6 +654,28 @@ program openacc_clause_validity
   i = i + 1
   !$acc end atomic
   !$acc end parallel
+  t%arr(i) = 2.0
+
+  !$acc cache(a(i))
+  !$acc cache(a(1:2,3:4))
+  !$acc cache(a)
+  !$acc cache(readonly: a, aa)
+  !$acc cache(readonly: a(i), aa(i, i))
+  !$acc cache(t%arr)
+  !$acc cache(ta(1:2)%arr)
+  !$acc cache(ta(1:2)%arr(1:4))
+
+  !ERROR: Only array element or subarray are allowed in CACHE directive
+  !$acc cache(ta(1:2)%s)
+
+  !ERROR: Only array element or subarray are allowed in CACHE directive
+  !$acc cache(i)
+
+  !ERROR: Only array element or subarray are allowed in CACHE directive
+  !$acc cache(t%s)
+
+  !ERROR: Only array element or subarray are allowed in CACHE directive
+  !$acc cache(/i/)
 
  contains
 


        


More information about the flang-commits mailing list