[flang-commits] [flang] ae1623b - [flang][Parser] Add a node for individual sections in sections construct

Shraiysh Vaishay via flang-commits flang-commits at lists.llvm.org
Fri Mar 18 09:25:48 PDT 2022


Author: Shraiysh Vaishay
Date: 2022-03-18T21:55:35+05:30
New Revision: ae1623b30645fd9a3ded019114678d1c34af1621

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

LOG: [flang][Parser] Add a node for individual sections in sections construct

This patch adds parser nodes for each indivudual section in sections
construct. This should help with the translation to FIR. `!$omp section`
was not recognized as a construct and hence needed special handling.

`OpenMPSectionsConstruct` contains a list of `OpenMPConstruct`. Each
such `OpenMPConstruct` wraps an `OpenMPSectionConstruct`
(section, not sections). An `OpenMPSectionConstruct` is a wrapper around
a `Block`.

Reviewed By: kiranchandramohan, peixin

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

Added: 
    flang/test/Examples/omp-sections.f90
    flang/test/Lower/OpenMP/sections-pft.f90
    flang/test/Parser/omp-sections.f90

Modified: 
    flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
    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

Removed: 
    


################################################################################
diff  --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
index a0c3b194bfd31..58cd8f73b8bd8 100644
--- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
+++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
@@ -85,6 +85,10 @@ SourcePosition OpenMPCounterVisitor::getLocation(const OpenMPConstruct &c) {
                 },
                 c.u);
           },
+          [&](const OpenMPSectionConstruct &c) -> SourcePosition {
+            const CharBlock &source{c.source};
+            return (parsing->allCooked().GetSourcePositionRange(source))->first;
+          },
       },
       c.u);
 }
@@ -134,6 +138,9 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
                 },
                 c.u);
           },
+          [&](const OpenMPSectionConstruct &c) -> std::string {
+            return "section";
+          },
           // OpenMPSectionsConstruct, OpenMPLoopConstruct,
           // OpenMPBlockConstruct, OpenMPCriticalConstruct Get the source from
           // the directive field of the begin directive or from the verbatim

diff  --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index cf85194c0d0fa..3ed00dd5e9133 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -562,6 +562,7 @@ class ParseTreeDumper {
   NODE(parser, OpenMPExecutableAllocate)
   NODE(parser, OpenMPSimpleStandaloneConstruct)
   NODE(parser, OpenMPStandaloneConstruct)
+  NODE(parser, OpenMPSectionConstruct)
   NODE(parser, OpenMPSectionsConstruct)
   NODE(parser, OpenMPThreadprivate)
   NODE(parser, OpenStmt)

diff  --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index f0a97402204e0..bc15b3c84606e 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3515,7 +3515,15 @@ struct OmpEndSectionsDirective {
 // [!$omp section
 //    structured-block]
 // ...
-WRAPPER_CLASS(OmpSectionBlocks, std::list<Block>);
+struct OpenMPSectionConstruct {
+  WRAPPER_CLASS_BOILERPLATE(OpenMPSectionConstruct, Block);
+  CharBlock source;
+};
+
+// `OmpSectionBlocks` is a list of section constructs. The parser guarentees
+// that the `OpenMPConstruct` here always encapsulates an
+// `OpenMPSectionConstruct` and not any other OpenMP construct.
+WRAPPER_CLASS(OmpSectionBlocks, std::list<OpenMPConstruct>);
 
 struct OpenMPSectionsConstruct {
   TUPLE_CLASS_BOILERPLATE(OpenMPSectionsConstruct);
@@ -3817,9 +3825,9 @@ struct OpenMPLoopConstruct {
 struct OpenMPConstruct {
   UNION_CLASS_BOILERPLATE(OpenMPConstruct);
   std::variant<OpenMPStandaloneConstruct, OpenMPSectionsConstruct,
-      OpenMPLoopConstruct, OpenMPBlockConstruct, OpenMPAtomicConstruct,
-      OpenMPDeclarativeAllocate, OpenMPExecutableAllocate,
-      OpenMPCriticalConstruct>
+      OpenMPSectionConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct,
+      OpenMPAtomicConstruct, OpenMPDeclarativeAllocate,
+      OpenMPExecutableAllocate, OpenMPCriticalConstruct>
       u;
 };
 

diff  --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index 83e1a99f95ffd..70c01f2a309c5 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -217,6 +217,9 @@ void Fortran::lower::genOpenMPConstruct(
                   &sectionsConstruct) {
             TODO(converter.getCurrentLocation(), "OpenMPSectionsConstruct");
           },
+          [&](const Fortran::parser::OpenMPSectionConstruct &sectionConstruct) {
+            TODO(converter.getCurrentLocation(), "OpenMPSectionConstruct");
+          },
           [&](const Fortran::parser::OpenMPLoopConstruct &loopConstruct) {
             TODO(converter.getCurrentLocation(), "OpenMPLoopConstruct");
           },

diff  --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 7e7adca6ef1b4..9a4f4bbcc7abd 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -529,11 +529,15 @@ TYPE_PARSER(
                         Parser<OmpClauseList>{})))
 
 // OMP SECTION-BLOCK
+
+TYPE_PARSER(construct<OpenMPSectionConstruct>(block))
+
 TYPE_PARSER(maybe(startOmpLine >> "SECTION"_tok / endOmpLine) >>
-    construct<OmpSectionBlocks>(
-        nonemptySeparated(block, startOmpLine >> "SECTION"_tok / endOmpLine)))
+    construct<OmpSectionBlocks>(nonemptySeparated(
+        construct<OpenMPConstruct>(sourced(Parser<OpenMPSectionConstruct>{})),
+        startOmpLine >> "SECTION"_tok / endOmpLine)))
 
-// OMP SECTIONS (2.7.2), PARALLEL SECTIONS (2.11.2)
+// OMP SECTIONS (OpenMP 5.0 - 2.8.1), PARALLEL SECTIONS (OpenMP 5.0 - 2.13.3)
 TYPE_PARSER(construct<OpenMPSectionsConstruct>(
     Parser<OmpBeginSectionsDirective>{} / endOmpLine,
     Parser<OmpSectionBlocks>{}, Parser<OmpEndSectionsDirective>{} / endOmpLine))

diff  --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 39343dfe24958..4a66d528f407c 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2405,7 +2405,9 @@ class UnparseVisitor {
       Word("!$OMP SECTION");
       Put("\n");
       EndOpenMP();
-      Walk(y, ""); // y is Block
+      // y.u is an OpenMPSectionConstruct
+      // (y.u).v is Block
+      Walk(std::get<OpenMPSectionConstruct>(y.u).v, "");
     }
   }
   void Unparse(const OpenMPSectionsConstruct &x) {

diff  --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 5f5811cdf3fbe..88d2a6d399908 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -801,8 +801,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
 
   PushContextAndClauseSets(beginDir.source, beginDir.v);
   const auto &sectionBlocks{std::get<parser::OmpSectionBlocks>(x.t)};
-  for (const auto &block : sectionBlocks.v) {
-    CheckNoBranching(block, beginDir.v, beginDir.source);
+  for (const parser::OpenMPConstruct &block : sectionBlocks.v) {
+    CheckNoBranching(std::get<parser::OpenMPSectionConstruct>(block.u).v,
+        beginDir.v, beginDir.source);
   }
   HasInvalidWorksharingNesting(
       beginDir.source, llvm::omp::nestedWorkshareErrSet);

diff  --git a/flang/test/Examples/omp-sections.f90 b/flang/test/Examples/omp-sections.f90
new file mode 100644
index 0000000000000..41e6e8fd9e5ab
--- /dev/null
+++ b/flang/test/Examples/omp-sections.f90
@@ -0,0 +1,30 @@
+! REQUIRES: plugins, examples, shell
+
+! RUN: %flang_fc1 -load %llvmshlibdir/flangOmpReport.so -plugin flang-omp-report -fopenmp %s -o - | FileCheck %s
+
+subroutine omp_sections()
+  integer :: x
+  !$omp sections private(x)
+    !$omp section
+    call f1()
+    !$omp section
+    call f2()
+  !$omp end sections nowait
+end subroutine omp_sections
+
+!CHECK: - file:            {{.*}}
+!CHECK:   line:            9
+!CHECK:   construct:       section
+!CHECK:   clauses:         []
+!CHECK: - file:            {{.*}}
+!CHECK:   line:            11
+!CHECK:   construct:       section
+!CHECK:   clauses:         []
+!CHECK: - file:            {{.*}}
+!CHECK:   line:            7
+!CHECK:   construct:       sections
+!CHECK:   clauses:
+!CHECK:     - clause:          nowait
+!CHECK:       details:         ''
+!CHECK:     - clause:          private
+!CHECK:       details:         x

diff  --git a/flang/test/Lower/OpenMP/sections-pft.f90 b/flang/test/Lower/OpenMP/sections-pft.f90
new file mode 100644
index 0000000000000..7b20a87022c90
--- /dev/null
+++ b/flang/test/Lower/OpenMP/sections-pft.f90
@@ -0,0 +1,91 @@
+! RUN: %flang_fc1 -fdebug-pre-fir-tree -fopenmp %s | FileCheck %s
+
+subroutine openmp_sections(x, y)
+
+  integer, intent(inout)::x, y
+
+!==============================================================================
+! empty construct
+!==============================================================================
+!$omp sections
+!$omp end sections
+
+!CHECK: OpenMPConstruct
+!CHECK: End OpenMPConstruct
+
+!==============================================================================
+! single section, without `!$omp section`
+!==============================================================================
+!$omp sections
+    call F1()
+!$omp end sections
+
+!CHECK: OpenMPConstruct
+!CHECK:  OpenMPConstruct
+!CHECK:   CallStmt
+!CHECK:  End OpenMPConstruct
+!CHECK: End OpenMPConstruct
+
+!==============================================================================
+! single section with `!$omp section`
+!==============================================================================
+!$omp sections
+  !$omp section
+    call F1
+!$omp end sections
+
+!CHECK: OpenMPConstruct
+!CHECK:  OpenMPConstruct
+!CHECK:   CallStmt
+!CHECK:  End OpenMPConstruct
+!CHECK: End OpenMPConstruct
+
+!==============================================================================
+! multiple sections
+!==============================================================================
+!$omp sections
+  !$omp section
+    call F1
+  !$omp section
+    call F2
+  !$omp section
+    call F3
+!$omp end sections
+
+!CHECK: OpenMPConstruct
+!CHECK:  OpenMPConstruct
+!CHECK:   CallStmt
+!CHECK:  End OpenMPConstruct
+!CHECK:  OpenMPConstruct
+!CHECK:   CallStmt
+!CHECK:  End OpenMPConstruct
+!CHECK:  OpenMPConstruct
+!CHECK:   CallStmt
+!CHECK:  End OpenMPConstruct
+!CHECK: End OpenMPConstruct
+
+!==============================================================================
+! multiple sections with clauses
+!==============================================================================
+!$omp sections PRIVATE(x) FIRSTPRIVATE(y)
+  !$omp section
+    call F1
+  !$omp section
+    call F2
+  !$omp section
+    call F3
+!$omp end sections NOWAIT
+
+!CHECK: OpenMPConstruct
+!CHECK:  OpenMPConstruct
+!CHECK:   CallStmt
+!CHECK:  End OpenMPConstruct
+!CHECK:  OpenMPConstruct
+!CHECK:   CallStmt
+!CHECK:  End OpenMPConstruct
+!CHECK:  OpenMPConstruct
+!CHECK:   CallStmt
+!CHECK:  End OpenMPConstruct
+!CHECK: End OpenMPConstruct
+
+end subroutine openmp_sections

diff  --git a/flang/test/Parser/omp-sections.f90 b/flang/test/Parser/omp-sections.f90
new file mode 100644
index 0000000000000..3752cef624329
--- /dev/null
+++ b/flang/test/Parser/omp-sections.f90
@@ -0,0 +1,121 @@
+! RUN: %flang_fc1 -fdebug-unparse -fopenmp %s | FileCheck --ignore-case %s
+! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+subroutine openmp_sections(x, y)
+
+  integer, intent(inout)::x, y
+
+!==============================================================================
+! empty construct
+!==============================================================================
+!CHECK: !$omp sections
+!$omp sections
+  !CHECK: !$omp section
+!CHECK: !$omp end sections
+!$omp end sections
+
+!PARSE-TREE: OpenMPConstruct -> OpenMPSectionsConstruct
+!PARSE-TREE: OmpBeginSectionsDirective
+!PARSE-TREE-NOT: ExecutionPartConstruct
+!PARSE-TREE: OmpEndSectionsDirective
+
+!==============================================================================
+! single section, without `!$omp section`
+!==============================================================================
+!CHECK: !$omp sections
+!$omp sections
+  !CHECK: !$omp section
+    !CHECK: CALL
+    call F1()
+!CHECK: !$omp end sections
+!$omp end sections
+
+!PARSE-TREE: OpenMPConstruct -> OpenMPSectionsConstruct
+!PARSE-TREE:  OmpBeginSectionsDirective
+!PARSE-TREE:   OpenMPConstruct -> OpenMPSectionConstruct -> Block
+!PARSE-TREE:    CallStmt
+!PARSE-TREE-NOT: ExecutionPartConstruct
+!PARSE-TREE:  OmpEndSectionsDirective
+
+!==============================================================================
+! single section with `!$omp section`
+!==============================================================================
+!CHECK: !$omp sections
+!$omp sections
+  !CHECK: !$omp section
+  !$omp section
+    !CHECK: CALL F1
+    call F1
+!CHECK: !$omp end sections
+!$omp end sections
+
+!PARSE-TREE: OpenMPConstruct -> OpenMPSectionsConstruct
+!PARSE-TREE:  OmpBeginSectionsDirective
+!PARSE-TREE:   OpenMPConstruct -> OpenMPSectionConstruct -> Block
+!PARSE-TREE:    CallStmt
+!PARSE-TREE-NOT: ExecutionPartConstruct
+!PARSE-TREE:  OmpEndSectionsDirective
+
+!==============================================================================
+! multiple sections
+!==============================================================================
+!CHECK: !$omp sections
+!$omp sections
+  !CHECK: !$omp section
+  !$omp section
+    !CHECK: CALL F1
+    call F1
+  !CHECK: !$omp section
+  !$omp section
+    !CHECK: CALL F2
+    call F2
+  !CHECK: !$omp section
+  !$omp section
+    !CHECK: CALL F3
+    call F3
+!CHECK: !$omp end sections
+!$omp end sections
+
+!PARSE-TREE: OpenMPConstruct -> OpenMPSectionsConstruct
+!PARSE-TREE:  OmpBeginSectionsDirective
+!PARSE-TREE:   OpenMPConstruct -> OpenMPSectionConstruct -> Block
+!PARSE-TREE:    CallStmt
+!PARSE-TREE:   OpenMPConstruct -> OpenMPSectionConstruct -> Block
+!PARSE-TREE:    CallStmt
+!PARSE-TREE:   OpenMPConstruct -> OpenMPSectionConstruct -> Block
+!PARSE-TREE:    CallStmt
+!PARSE-TREE-NOT: ExecutionPartConstruct
+!PARSE-TREE:  OmpEndSectionsDirective
+
+!==============================================================================
+! multiple sections with clauses
+!==============================================================================
+!CHECK: !$omp sections PRIVATE(x) FIRSTPRIVATE(y)
+!$omp sections PRIVATE(x) FIRSTPRIVATE(y)
+  !CHECK: !$omp section
+  !$omp section
+    !CHECK: CALL F1
+    call F1
+  !CHECK: !$omp section
+  !$omp section
+    !CHECK: CALL F2
+    call F2
+  !CHECK: !$omp section
+  !$omp section
+    !CHECK: CALL F3
+    call F3
+!CHECK: !$omp end sections NOWAIT
+!$omp end sections NOWAIT
+
+!PARSE-TREE: OpenMPConstruct -> OpenMPSectionsConstruct
+!PARSE-TREE:  OmpBeginSectionsDirective
+!PARSE-TREE:   OpenMPConstruct -> OpenMPSectionConstruct -> Block
+!PARSE-TREE:    CallStmt
+!PARSE-TREE:   OpenMPConstruct -> OpenMPSectionConstruct -> Block
+!PARSE-TREE:    CallStmt
+!PARSE-TREE:   OpenMPConstruct -> OpenMPSectionConstruct -> Block
+!PARSE-TREE:    CallStmt
+!PARSE-TREE-NOT: ExecutionPartConstruct
+!PARSE-TREE:  OmpEndSectionsDirective
+
+END subroutine openmp_sections


        


More information about the flang-commits mailing list