[flang-commits] [flang] c9e967a - [flang]Add Parser Support for Allocate Directive

Irina Dobrescu via flang-commits flang-commits at lists.llvm.org
Thu Dec 10 08:25:32 PST 2020


Author: Irina Dobrescu
Date: 2020-12-10T16:21:19Z
New Revision: c9e967af3fc7ce824cd811379c5e99a998819779

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

LOG: [flang]Add Parser Support for Allocate Directive

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

Added: 
    flang/test/Parser/omp-allocate-unparse.f90
    flang/test/Semantics/omp-allocate-directive.f90

Modified: 
    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/type-parsers.h
    flang/lib/Parser/unparse.cpp
    flang/lib/Semantics/check-omp-structure.cpp
    flang/lib/Semantics/check-omp-structure.h
    llvm/include/llvm/Frontend/OpenMP/OMP.td

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index c86c2ec6e66b..791e21fa4b62 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -545,6 +545,7 @@ class ParseTreeDumper {
   NODE(parser, OpenMPCancellationPointConstruct)
   NODE(parser, OpenMPConstruct)
   NODE(parser, OpenMPCriticalConstruct)
+  NODE(parser, OpenMPDeclarativeAllocate)
   NODE(parser, OpenMPDeclarativeConstruct)
   NODE(parser, OpenMPDeclareReductionConstruct)
   NODE(parser, OpenMPDeclareSimdConstruct)
@@ -552,6 +553,7 @@ class ParseTreeDumper {
   NODE(parser, OmpMemoryOrderClause)
   NODE(parser, OpenMPFlushConstruct)
   NODE(parser, OpenMPLoopConstruct)
+  NODE(parser, OpenMPExecutableAllocate)
   NODE(parser, OpenMPSimpleStandaloneConstruct)
   NODE(parser, OpenMPStandaloneConstruct)
   NODE(parser, OpenMPSectionsConstruct)

diff  --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 6bed37c2b871..ca73af210c15 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3583,11 +3583,19 @@ struct OpenMPThreadprivate {
   std::tuple<Verbatim, OmpObjectList> t;
 };
 
+// 2.11.3 allocate -> ALLOCATE (variable-name-list) [clause]
+struct OpenMPDeclarativeAllocate {
+  TUPLE_CLASS_BOILERPLATE(OpenMPDeclarativeAllocate);
+  CharBlock source;
+  std::tuple<Verbatim, OmpObjectList, OmpClauseList> t;
+};
+
 struct OpenMPDeclarativeConstruct {
   UNION_CLASS_BOILERPLATE(OpenMPDeclarativeConstruct);
   CharBlock source;
-  std::variant<OpenMPDeclareReductionConstruct, OpenMPDeclareSimdConstruct,
-      OpenMPDeclareTargetConstruct, OpenMPThreadprivate>
+  std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareReductionConstruct,
+      OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
+      OpenMPThreadprivate>
       u;
 };
 
@@ -3607,6 +3615,19 @@ struct OpenMPCriticalConstruct {
   std::tuple<OmpCriticalDirective, Block, OmpEndCriticalDirective> t;
 };
 
+// 2.11.3 allocate -> ALLOCATE [(variable-name-list)] [clause]
+//        [ALLOCATE (variable-name-list) [clause] [...]]
+//        allocate-statement
+//        clause -> allocator-clause
+struct OpenMPExecutableAllocate {
+  TUPLE_CLASS_BOILERPLATE(OpenMPExecutableAllocate);
+  CharBlock source;
+  std::tuple<Verbatim, std::optional<OmpObjectList>, OmpClauseList,
+      std::optional<std::list<OpenMPDeclarativeAllocate>>,
+      Statement<AllocateStmt>>
+      t;
+};
+
 // 2.17.7 atomic -> ATOMIC [clause[,]] atomic-clause [[,]clause] |
 //                  ATOMIC [clause]
 //        clause -> memory-order-clause | HINT(hint-expression)
@@ -3777,6 +3798,7 @@ struct OpenMPConstruct {
   UNION_CLASS_BOILERPLATE(OpenMPConstruct);
   std::variant<OpenMPStandaloneConstruct, OpenMPSectionsConstruct,
       OpenMPLoopConstruct, OpenMPBlockConstruct, OpenMPAtomicConstruct,
+      OpenMPExecutableAllocate, OpenMPDeclarativeAllocate,
       OpenMPCriticalConstruct>
       u;
 };

diff  --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index 780aea9664fc..cfe4b0b86b67 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -256,6 +256,10 @@ void Fortran::lower::genOpenMPConstruct(
           [&](const Fortran::parser::OpenMPLoopConstruct &loopConstruct) {
             TODO("");
           },
+          [&](const Fortran::parser::OpenMPDeclarativeAllocate
+                  &execAllocConstruct) { TODO(""); },
+          [&](const Fortran::parser::OpenMPExecutableAllocate
+                  &execAllocConstruct) { TODO(""); },
           [&](const Fortran::parser::OpenMPBlockConstruct &blockConstruct) {
             genOMP(converter, eval, blockConstruct);
           },

diff  --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index da10f9ffb0a8..69fc4f0e67ee 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -159,6 +159,8 @@ TYPE_PARSER(
         construct<OmpClause>(parenthesized(Parser<OmpAlignedClause>{})) ||
     "ALLOCATE" >>
         construct<OmpClause>(parenthesized(Parser<OmpAllocateClause>{})) ||
+    "ALLOCATOR" >> construct<OmpClause>(construct<OmpClause::Allocator>(
+                       parenthesized(scalarIntExpr))) ||
     "COLLAPSE" >> construct<OmpClause>(construct<OmpClause::Collapse>(
                       parenthesized(scalarIntConstantExpr))) ||
     "COPYIN" >> construct<OmpClause>(construct<OmpClause::Copyin>(
@@ -454,6 +456,13 @@ TYPE_PARSER(sourced(construct<OmpCriticalDirective>(verbatim("CRITICAL"_tok),
 TYPE_PARSER(construct<OpenMPCriticalConstruct>(
     Parser<OmpCriticalDirective>{}, block, Parser<OmpEndCriticalDirective>{}))
 
+// 2.11.3 Executable Allocate directive
+TYPE_PARSER(
+    sourced(construct<OpenMPExecutableAllocate>(verbatim("ALLOCATE"_tok),
+        maybe(parenthesized(Parser<OmpObjectList>{})), Parser<OmpClauseList>{},
+        maybe(nonemptyList(Parser<OpenMPDeclarativeAllocate>{})) / endOmpLine,
+        statement(allocateStmt))))
+
 // 2.8.2 Declare Simd construct
 TYPE_PARSER(
     sourced(construct<OpenMPDeclareSimdConstruct>(verbatim("DECLARE SIMD"_tok),
@@ -463,6 +472,12 @@ TYPE_PARSER(
 TYPE_PARSER(sourced(construct<OpenMPThreadprivate>(
     verbatim("THREADPRIVATE"_tok), parenthesized(Parser<OmpObjectList>{}))))
 
+// 2.11.3 Declarative Allocate directive
+TYPE_PARSER(
+    sourced(construct<OpenMPDeclarativeAllocate>(verbatim("ALLOCATE"_tok),
+        parenthesized(Parser<OmpObjectList>{}), Parser<OmpClauseList>{})) /
+    lookAhead(endOmpLine / !statement(allocateStmt)))
+
 // Declarative constructs
 TYPE_PARSER(startOmpLine >>
     sourced(construct<OpenMPDeclarativeConstruct>(
@@ -471,6 +486,8 @@ TYPE_PARSER(startOmpLine >>
             Parser<OpenMPDeclareSimdConstruct>{}) ||
         construct<OpenMPDeclarativeConstruct>(
             Parser<OpenMPDeclareTargetConstruct>{}) ||
+        construct<OpenMPDeclarativeConstruct>(
+            Parser<OpenMPDeclarativeAllocate>{}) ||
         construct<OpenMPDeclarativeConstruct>(Parser<OpenMPThreadprivate>{})) /
         endOmpLine)
 
@@ -511,6 +528,8 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
             // OpenMPStandaloneConstruct to resolve !$OMP ORDERED
             construct<OpenMPConstruct>(Parser<OpenMPStandaloneConstruct>{}),
             construct<OpenMPConstruct>(Parser<OpenMPAtomicConstruct>{}),
+            construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}),
+            construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}),
             construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{})))
 
 // END OMP Block directives

diff  --git a/flang/lib/Parser/type-parsers.h b/flang/lib/Parser/type-parsers.h
index d6269cbdc715..b5f6e34d3a72 100644
--- a/flang/lib/Parser/type-parsers.h
+++ b/flang/lib/Parser/type-parsers.h
@@ -85,6 +85,7 @@ constexpr Parser<Variable> variable; // R902
 constexpr Parser<Substring> substring; // R908
 constexpr Parser<DataRef> dataRef; // R911, R914, R917
 constexpr Parser<StructureComponent> structureComponent; // R913
+constexpr Parser<AllocateStmt> allocateStmt; // R927
 constexpr Parser<StatVariable> statVariable; // R929
 constexpr Parser<StatOrErrmsg> statOrErrmsg; // R942 & R1165
 constexpr Parser<DefinedOpName> definedOpName; // R1003, R1023, R1414, & R1415

diff  --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 56f09f97d98e..cf843ffb3c9d 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2287,6 +2287,25 @@ class UnparseVisitor {
     Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n");
     EndOpenMP();
   }
+  void Unparse(const OpenMPExecutableAllocate &x) {
+    BeginOpenMP();
+    Word("!$OMP ALLOCATE");
+    Walk(" (", std::get<std::optional<OmpObjectList>>(x.t), ")");
+    Walk(std::get<OmpClauseList>(x.t));
+    Put("\n");
+    EndOpenMP();
+    Walk(std::get<Statement<AllocateStmt>>(x.t));
+  }
+  void Unparse(const OpenMPDeclarativeAllocate &x) {
+    BeginOpenMP();
+    Word("!$OMP ALLOCATE");
+    Put(" (");
+    Walk(std::get<OmpObjectList>(x.t));
+    Put(")");
+    Walk(std::get<OmpClauseList>(x.t));
+    Put("\n");
+    EndOpenMP();
+  }
   void Unparse(const OmpCriticalDirective &x) {
     BeginOpenMP();
     Word("!$OMP CRITICAL");
@@ -2339,6 +2358,15 @@ class UnparseVisitor {
     BeginOpenMP();
     Word("!$OMP ");
     return std::visit(common::visitors{
+                          [&](const OpenMPDeclarativeAllocate &z) {
+                            Word("ALLOCATE (");
+                            Walk(std::get<OmpObjectList>(z.t));
+                            Put(")");
+                            Walk(std::get<OmpClauseList>(z.t));
+                            Put("\n");
+                            EndOpenMP();
+                            return false;
+                          },
                           [&](const OpenMPDeclareReductionConstruct &) {
                             Word("DECLARE REDUCTION ");
                             return true;

diff  --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 9ed73e65e57c..af76ca5a0a5a 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -179,6 +179,15 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
   dirContext_.pop_back();
 }
 
+void OmpStructureChecker::Enter(const parser::OpenMPDeclarativeAllocate &x) {
+  const auto &dir{std::get<parser::Verbatim>(x.t)};
+  PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_allocate);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPDeclarativeAllocate &) {
+  dirContext_.pop_back();
+}
+
 void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) {
   const auto &dir{std::get<parser::Verbatim>(x.t)};
   PushContext(dir.source, llvm::omp::Directive::OMPD_declare_target);
@@ -192,6 +201,15 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &) {
   dirContext_.pop_back();
 }
 
+void OmpStructureChecker::Enter(const parser::OpenMPExecutableAllocate &x) {
+  const auto &dir{std::get<parser::Verbatim>(x.t)};
+  PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_allocate);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPExecutableAllocate &) {
+  dirContext_.pop_back();
+}
+
 void OmpStructureChecker::Enter(
     const parser::OpenMPSimpleStandaloneConstruct &x) {
   const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(x.t)};
@@ -382,6 +400,7 @@ CHECK_SIMPLE_CLAUSE(SeqCst, OMPC_seq_cst)
 CHECK_SIMPLE_CLAUSE(Release, OMPC_release)
 CHECK_SIMPLE_CLAUSE(Relaxed, OMPC_relaxed)
 
+CHECK_REQ_SCALAR_INT_CLAUSE(Allocator, OMPC_allocator)
 CHECK_REQ_SCALAR_INT_CLAUSE(Grainsize, OMPC_grainsize)
 CHECK_REQ_SCALAR_INT_CLAUSE(NumTasks, OMPC_num_tasks)
 CHECK_REQ_SCALAR_INT_CLAUSE(NumTeams, OMPC_num_teams)

diff  --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index bb1509b4bdfb..e2233a1094c9 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -104,8 +104,12 @@ class OmpStructureChecker
 
   void Enter(const parser::OpenMPDeclareSimdConstruct &);
   void Leave(const parser::OpenMPDeclareSimdConstruct &);
+  void Enter(const parser::OpenMPDeclarativeAllocate &);
+  void Leave(const parser::OpenMPDeclarativeAllocate &);
   void Enter(const parser::OpenMPDeclareTargetConstruct &);
   void Leave(const parser::OpenMPDeclareTargetConstruct &);
+  void Enter(const parser::OpenMPExecutableAllocate &);
+  void Leave(const parser::OpenMPExecutableAllocate &);
 
   void Enter(const parser::OpenMPSimpleStandaloneConstruct &);
   void Leave(const parser::OpenMPSimpleStandaloneConstruct &);
@@ -121,6 +125,7 @@ class OmpStructureChecker
   void Leave(const parser::OmpClauseList &);
   void Enter(const parser::OmpClause &);
   void Enter(const parser::OmpNowait &);
+  void Enter(const parser::OmpClause::Allocator &);
   void Enter(const parser::OmpClause::Inbranch &);
   void Enter(const parser::OmpClause::Mergeable &);
   void Enter(const parser::OmpClause::Nogroup &);

diff  --git a/flang/test/Parser/omp-allocate-unparse.f90 b/flang/test/Parser/omp-allocate-unparse.f90
new file mode 100644
index 000000000000..3f517c1e2d04
--- /dev/null
+++ b/flang/test/Parser/omp-allocate-unparse.f90
@@ -0,0 +1,44 @@
+! RUN: %f18 -fdebug-no-semantics -funparse -fopenmp %s | FileCheck %s
+! Check Unparsing of OpenMP Allocate directive
+
+program allocate_unparse
+use omp_lib
+
+real, dimension (:,:), allocatable :: darray
+integer :: a, b, m, n, t, x, y, z
+
+! 2.11.3 declarative allocate
+
+!$omp allocate(x, y)
+!$omp allocate(x, y) allocator(omp_default_mem_alloc)
+
+! 2.11.3 executable allocate
+
+!$omp allocate(a, b)
+    allocate ( darray(a, b) )
+!$omp allocate allocator(omp_default_mem_alloc)
+    allocate ( darray(a, b) )
+!$omp allocate(a, b) allocator(omp_default_mem_alloc)
+    allocate ( darray(a, b) )
+
+!$omp allocate(t) allocator(omp_const_mem_alloc)
+!$omp allocate(z) allocator(omp_default_mem_alloc)
+!$omp allocate(m) allocator(omp_default_mem_alloc)
+!$omp allocate(n)
+    allocate ( darray(z, t) )
+
+end program allocate_unparse
+
+!CHECK:!$OMP ALLOCATE (x,y)
+!CHECK:!$OMP ALLOCATE (x,y) ALLOCATOR(omp_default_mem_alloc)
+!CHECK:!$OMP ALLOCATE (a,b)
+!CHECK:ALLOCATE(darray(a,b))
+!CHECK:!$OMP ALLOCATE ALLOCATOR(omp_default_mem_alloc)
+!CHECK:ALLOCATE(darray(a,b))
+!CHECK:!$OMP ALLOCATE (a,b) ALLOCATOR(omp_default_mem_alloc)
+!CHECK:ALLOCATE(darray(a,b))
+!CHECK:!$OMP ALLOCATE (t) ALLOCATOR(omp_const_mem_alloc)
+!CHECK:!$OMP ALLOCATE (z) ALLOCATOR(omp_default_mem_alloc)
+!CHECK:!$OMP ALLOCATE (m) ALLOCATOR(omp_default_mem_alloc)
+!CHECK:!$OMP ALLOCATE (n)
+!CHECK:ALLOCATE(darray(z,t))

diff  --git a/flang/test/Semantics/omp-allocate-directive.f90 b/flang/test/Semantics/omp-allocate-directive.f90
new file mode 100644
index 000000000000..62f85ce4ed1e
--- /dev/null
+++ b/flang/test/Semantics/omp-allocate-directive.f90
@@ -0,0 +1,25 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+! Check OpenMP Allocate directive
+use omp_lib
+
+! 2.11.3 declarative allocate
+! 2.11.3 executable allocate
+
+real, dimension (:,:), allocatable :: darray
+integer :: a, b, x, y, m, n, t, z
+!$omp allocate(x, y)
+!$omp allocate(x, y) allocator(omp_default_mem_alloc)
+
+!$omp allocate(a, b)
+    allocate ( darray(a, b) )
+
+!$omp allocate(a, b) allocator(omp_default_mem_alloc)
+    allocate ( darray(a, b) )
+
+!$omp allocate(t) allocator(omp_const_mem_alloc)
+!$omp allocate(z) allocator(omp_default_mem_alloc)
+!$omp allocate(m) allocator(omp_default_mem_alloc)
+!$omp allocate(n)
+    allocate ( darray(z, t) )
+
+end

diff  --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 3a93dd73edeb..6f16cfe730b7 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -34,6 +34,7 @@ def OpenMP : DirectiveLanguage {
 
 def OMPC_Allocator : Clause<"allocator"> {
   let clangClass = "OMPAllocatorClause";
+  let flangClassValue = "ScalarIntExpr";
 }
 def OMPC_If : Clause<"if"> {
   let clangClass = "OMPIfClause";


        


More information about the flang-commits mailing list