[llvm] d5fb596 - [flang][OpenMP] Add parser support for Requires directive

Sergio Afonso via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 10 03:40:21 PST 2022


Author: Sergio Afonso
Date: 2022-11-10T05:38:31-06:00
New Revision: d5fb5960d0df23509a501cfa5a133927bb266d4d

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

LOG: [flang][OpenMP] Add parser support for Requires directive

OpenMP 5.0 adds support for the "requires" directive. This patch adds parser support for it in flang.

Differential revision: https://reviews.llvm.org/D136867

Added: 
    

Modified: 
    flang/docs/OpenMP-semantics.md
    flang/include/flang/Parser/dump-parse-tree.h
    flang/include/flang/Parser/parse-tree.h
    flang/lib/Lower/OpenMP.cpp
    flang/lib/Parser/openmp-parsers.cpp
    flang/lib/Parser/unparse.cpp
    flang/lib/Semantics/check-omp-structure.cpp
    flang/lib/Semantics/check-omp-structure.h
    flang/lib/Semantics/resolve-directives.cpp
    flang/test/Semantics/OpenMP/omp-declarative-directive.f90
    llvm/include/llvm/Frontend/OpenMP/OMP.td

Removed: 
    


################################################################################
diff  --git a/flang/docs/OpenMP-semantics.md b/flang/docs/OpenMP-semantics.md
index 1511bc9e7b3b5..46dc189456f99 100644
--- a/flang/docs/OpenMP-semantics.md
+++ b/flang/docs/OpenMP-semantics.md
@@ -48,6 +48,7 @@ List of existing ones:
 * declare target
 * threadprivate
 * declare reduction
+* requires
 
 There is a parser node for each of these directives and
 the parser node saves information associated with the directive,

diff  --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 2d9cfaf91f93f..66ab5dd6d0237 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -562,9 +562,12 @@ class ParseTreeDumper {
   NODE(parser, OmpMemoryOrderClause)
   NODE(parser, OmpAtomicClause)
   NODE(parser, OmpAtomicClauseList)
+  NODE(parser, OmpAtomicDefaultMemOrderClause)
+  NODE_ENUM(OmpAtomicDefaultMemOrderClause, Type)
   NODE(parser, OpenMPFlushConstruct)
   NODE(parser, OpenMPLoopConstruct)
   NODE(parser, OpenMPExecutableAllocate)
+  NODE(parser, OpenMPRequiresConstruct)
   NODE(parser, OpenMPSimpleStandaloneConstruct)
   NODE(parser, OpenMPStandaloneConstruct)
   NODE(parser, OpenMPSectionConstruct)

diff  --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 16987fb9660a3..39156c63c7cfe 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3494,6 +3494,14 @@ struct OmpDependClause {
   std::variant<Source, Sink, InOut> u;
 };
 
+// OMP 5.0 2.4 atomic-default-mem-order-clause ->
+//                 ATOMIC_DEFAULT_MEM_ORDER (SEQ_CST | ACQ_REL |
+//                                           RELAXED)
+struct OmpAtomicDefaultMemOrderClause {
+  ENUM_CLASS(Type, SeqCst, AcqRel, Relaxed)
+  WRAPPER_CLASS_BOILERPLATE(OmpAtomicDefaultMemOrderClause, Type);
+};
+
 // OpenMP Clauses
 struct OmpClause {
   UNION_CLASS_BOILERPLATE(OmpClause);
@@ -3611,6 +3619,13 @@ struct OpenMPDeclareSimdConstruct {
   std::tuple<Verbatim, std::optional<Name>, OmpClauseList> t;
 };
 
+// 2.4 requires -> REQUIRES requires-clause[ [ [,] requires-clause]...]
+struct OpenMPRequiresConstruct {
+  TUPLE_CLASS_BOILERPLATE(OpenMPRequiresConstruct);
+  CharBlock source;
+  std::tuple<Verbatim, OmpClauseList> t;
+};
+
 // 2.15.2 threadprivate -> THREADPRIVATE (variable-name-list)
 struct OpenMPThreadprivate {
   TUPLE_CLASS_BOILERPLATE(OpenMPThreadprivate);
@@ -3630,7 +3645,7 @@ struct OpenMPDeclarativeConstruct {
   CharBlock source;
   std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareReductionConstruct,
       OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
-      OpenMPThreadprivate>
+      OpenMPThreadprivate, OpenMPRequiresConstruct>
       u;
 };
 

diff  --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index 4d47b95e00eed..d487fdf29b9fc 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -1815,6 +1815,10 @@ void Fortran::lower::genOpenMPDeclarativeConstruct(
             TODO(converter.getCurrentLocation(),
                  "OpenMPDeclareTargetConstruct");
           },
+          [&](const Fortran::parser::OpenMPRequiresConstruct
+                  &requiresConstruct) {
+            TODO(converter.getCurrentLocation(), "OpenMPRequiresConstruct");
+          },
           [&](const Fortran::parser::OpenMPThreadprivate &threadprivate) {
             // The directive is lowered when instantiating the variable to
             // support the case of threadprivate variable declared in module.

diff  --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 9f2e152236089..0e9f742954218 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -191,6 +191,9 @@ TYPE_PARSER(
                       parenthesized(Parser<OmpAllocateClause>{}))) ||
     "ALLOCATOR" >> construct<OmpClause>(construct<OmpClause::Allocator>(
                        parenthesized(scalarIntExpr))) ||
+    "ATOMIC_DEFAULT_MEM_ORDER" >>
+        construct<OmpClause>(construct<OmpClause::AtomicDefaultMemOrder>(
+            parenthesized(Parser<OmpAtomicDefaultMemOrderClause>{}))) ||
     "COLLAPSE" >> construct<OmpClause>(construct<OmpClause::Collapse>(
                       parenthesized(scalarIntConstantExpr))) ||
     "COPYIN" >> construct<OmpClause>(construct<OmpClause::Copyin>(
@@ -208,6 +211,8 @@ TYPE_PARSER(
     "DIST_SCHEDULE" >>
         construct<OmpClause>(construct<OmpClause::DistSchedule>(
             parenthesized("STATIC" >> maybe("," >> scalarIntExpr)))) ||
+    "DYNAMIC_ALLOCATORS" >>
+        construct<OmpClause>(construct<OmpClause::DynamicAllocators>()) ||
     "FINAL" >> construct<OmpClause>(construct<OmpClause::Final>(
                    parenthesized(scalarLogicalExpr))) ||
     "FIRSTPRIVATE" >> construct<OmpClause>(construct<OmpClause::Firstprivate>(
@@ -261,6 +266,8 @@ TYPE_PARSER(
             parenthesized(Parser<OmpReductionClause>{}))) ||
     "RELAXED" >> construct<OmpClause>(construct<OmpClause::Relaxed>()) ||
     "RELEASE" >> construct<OmpClause>(construct<OmpClause::Release>()) ||
+    "REVERSE_OFFLOAD" >>
+        construct<OmpClause>(construct<OmpClause::ReverseOffload>()) ||
     "SAFELEN" >> construct<OmpClause>(construct<OmpClause::Safelen>(
                      parenthesized(scalarIntConstantExpr))) ||
     "SCHEDULE" >> construct<OmpClause>(construct<OmpClause::Schedule>(
@@ -278,6 +285,10 @@ TYPE_PARSER(
                 parenthesized(Parser<OmpObjectList>{}))) ||
     "USE_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::UseDevicePtr>(
                             parenthesized(nonemptyList(name)))) ||
+    "UNIFIED_ADDRESS" >>
+        construct<OmpClause>(construct<OmpClause::UnifiedAddress>()) ||
+    "UNIFIED_SHARED_MEMORY" >>
+        construct<OmpClause>(construct<OmpClause::UnifiedSharedMemory>()) ||
     "UNIFORM" >> construct<OmpClause>(construct<OmpClause::Uniform>(
                      parenthesized(nonemptyList(name)))) ||
     "UNTIED" >> construct<OmpClause>(construct<OmpClause::Untied>()))
@@ -357,6 +368,16 @@ TYPE_PARSER(sourced(construct<OmpMemoryOrderClause>(
         "ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
         "RELAXED" >> construct<OmpClause>(construct<OmpClause::Relaxed>())))))
 
+// 2.4 Requires construct [OpenMP 5.0]
+//        atomic-default-mem-order-clause ->
+//                               seq_cst
+//                               acq_rel
+//                               relaxed
+TYPE_PARSER(construct<OmpAtomicDefaultMemOrderClause>(
+    "SEQ_CST" >> pure(OmpAtomicDefaultMemOrderClause::Type::SeqCst) ||
+    "ACQ_REL" >> pure(OmpAtomicDefaultMemOrderClause::Type::AcqRel) ||
+    "RELAXED" >> pure(OmpAtomicDefaultMemOrderClause::Type::Relaxed)))
+
 // 2.17.7 Atomic construct
 //        atomic-clause -> memory-order-clause | HINT(hint-expression)
 TYPE_PARSER(sourced(construct<OmpAtomicClause>(
@@ -519,6 +540,10 @@ TYPE_PARSER(
     sourced(construct<OpenMPDeclareSimdConstruct>(verbatim("DECLARE SIMD"_tok),
         maybe(parenthesized(name)), Parser<OmpClauseList>{})))
 
+// 2.4 Requires construct
+TYPE_PARSER(sourced(construct<OpenMPRequiresConstruct>(
+    verbatim("REQUIRES"_tok), some(Parser<OmpClause>{} / maybe(","_tok)))))
+
 // 2.15.2 Threadprivate directive
 TYPE_PARSER(sourced(construct<OpenMPThreadprivate>(
     verbatim("THREADPRIVATE"_tok), parenthesized(Parser<OmpObjectList>{}))))
@@ -539,6 +564,8 @@ TYPE_PARSER(startOmpLine >>
             Parser<OpenMPDeclareTargetConstruct>{}) ||
         construct<OpenMPDeclarativeConstruct>(
             Parser<OpenMPDeclarativeAllocate>{}) ||
+        construct<OpenMPDeclarativeConstruct>(
+            Parser<OpenMPRequiresConstruct>{}) ||
         construct<OpenMPDeclarativeConstruct>(Parser<OpenMPThreadprivate>{})) /
         endOmpLine)
 

diff  --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 534738d19b1d8..9c7990845350f 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2229,6 +2229,21 @@ class UnparseVisitor {
       break;
     }
   }
+
+  void Unparse(const OmpAtomicDefaultMemOrderClause &x) {
+    switch (x.v) {
+    case OmpAtomicDefaultMemOrderClause::Type::SeqCst:
+      Word("SEQ_CST");
+      break;
+    case OmpAtomicDefaultMemOrderClause::Type::AcqRel:
+      Word("ACQ_REL");
+      break;
+    case OmpAtomicDefaultMemOrderClause::Type::Relaxed:
+      Word("RELAXED");
+      break;
+    }
+  }
+
   void Unparse(const OmpAtomicClauseList &x) { Walk(" ", x.v, " "); }
 
   void Unparse(const OmpAtomic &x) {
@@ -2393,6 +2408,13 @@ class UnparseVisitor {
               Word("DECLARE TARGET ");
               return true;
             },
+            [&](const OpenMPRequiresConstruct &y) {
+              Word("REQUIRES ");
+              Walk(std::get<OmpClauseList>(y.t));
+              Put("\n");
+              EndOpenMP();
+              return false;
+            },
             [&](const OpenMPThreadprivate &) {
               Word("THREADPRIVATE (");
               return true;

diff  --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index bb983564acb54..0c11a97c3e8e1 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1060,6 +1060,15 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
   dirContext_.pop_back();
 }
 
+void OmpStructureChecker::Enter(const parser::OpenMPRequiresConstruct &x) {
+  const auto &dir{std::get<parser::Verbatim>(x.t)};
+  PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_requires);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPRequiresConstruct &) {
+  dirContext_.pop_back();
+}
+
 void OmpStructureChecker::Enter(const parser::OpenMPDeclarativeAllocate &x) {
   isPredefinedAllocator = true;
   const auto &dir{std::get<parser::Verbatim>(x.t)};

diff  --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 0ff0b90bbe690..2751cdd6fbe98 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -152,6 +152,8 @@ class OmpStructureChecker
   void Leave(const parser::OpenMPDeclareTargetConstruct &);
   void Enter(const parser::OpenMPExecutableAllocate &);
   void Leave(const parser::OpenMPExecutableAllocate &);
+  void Enter(const parser::OpenMPRequiresConstruct &);
+  void Leave(const parser::OpenMPRequiresConstruct &);
   void Enter(const parser::OpenMPThreadprivate &);
   void Leave(const parser::OpenMPThreadprivate &);
 

diff  --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 16eacc5dff0a4..82623acf13c6c 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -323,6 +323,13 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
     return true;
   }
   void Post(const parser::OpenMPDeclareSimdConstruct &) { PopContext(); }
+
+  bool Pre(const parser::OpenMPRequiresConstruct &x) {
+    PushContext(x.source, llvm::omp::Directive::OMPD_requires);
+    return true;
+  }
+  void Post(const parser::OpenMPRequiresConstruct &) { PopContext(); }
+
   bool Pre(const parser::OpenMPThreadprivate &);
   void Post(const parser::OpenMPThreadprivate &) { PopContext(); }
 

diff  --git a/flang/test/Semantics/OpenMP/omp-declarative-directive.f90 b/flang/test/Semantics/OpenMP/omp-declarative-directive.f90
index 23ed8d5e0b555..e48a682288583 100644
--- a/flang/test/Semantics/OpenMP/omp-declarative-directive.f90
+++ b/flang/test/Semantics/OpenMP/omp-declarative-directive.f90
@@ -5,6 +5,20 @@
 !TODO: all internal errors
 !      enable declare-reduction example after name resolution
 
+! 2.4 requires
+
+subroutine requires_1(a)
+  real(8), intent(inout) :: a
+  !$omp requires reverse_offload, unified_shared_memory, atomic_default_mem_order(relaxed)
+  a = a + 0.01
+end subroutine requires_1
+
+subroutine requires_2(a)
+  real(8), intent(inout) :: a
+  !$omp requires unified_address
+  a = a + 0.01
+end subroutine requires_2
+
 ! 2.8.2 declare-simd
 
 subroutine declare_simd_1(a, b)

diff  --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 6de8a3ea93f1e..4e1865a99beda 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -299,6 +299,7 @@ def OMPC_DynamicAllocators : Clause<"dynamic_allocators"> {
 }
 def OMPC_AtomicDefaultMemOrder : Clause<"atomic_default_mem_order"> {
   let clangClass = "OMPAtomicDefaultMemOrderClause";
+  let flangClass = "OmpAtomicDefaultMemOrderClause";
 }
 def OMPC_Allocate : Clause<"allocate"> {
   let clangClass = "OMPAllocateClause";
@@ -614,7 +615,7 @@ def OMP_Cancel : Directive<"cancel"> {
   ];
 }
 def OMP_Requires : Directive<"requires"> {
-  let allowedClauses = [
+  let allowedOnceClauses = [
     VersionedClause<OMPC_UnifiedAddress>,
     VersionedClause<OMPC_UnifiedSharedMemory>,
     // OpenMP 5.2 Spec: If an implementation is not supporting a requirement


        


More information about the llvm-commits mailing list