Skip to content

Commit

Permalink
[flang][Parser] Add a node for individual sections in sections construct
Browse files Browse the repository at this point in the history
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
  • Loading branch information
shraiysh committed Mar 18, 2022
1 parent 831ab35 commit ae1623b
Show file tree
Hide file tree
Showing 10 changed files with 278 additions and 10 deletions.
7 changes: 7 additions & 0 deletions flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions flang/include/flang/Parser/dump-parse-tree.h
Expand Up @@ -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)
Expand Down
16 changes: 12 additions & 4 deletions flang/include/flang/Parser/parse-tree.h
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
};

Expand Down
3 changes: 3 additions & 0 deletions flang/lib/Lower/OpenMP.cpp
Expand Up @@ -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");
},
Expand Down
10 changes: 7 additions & 3 deletions flang/lib/Parser/openmp-parsers.cpp
Expand Up @@ -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))
Expand Down
4 changes: 3 additions & 1 deletion flang/lib/Parser/unparse.cpp
Expand Up @@ -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) {
Expand Down
5 changes: 3 additions & 2 deletions flang/lib/Semantics/check-omp-structure.cpp
Expand Up @@ -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);
Expand Down
30 changes: 30 additions & 0 deletions 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
91 changes: 91 additions & 0 deletions 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
121 changes: 121 additions & 0 deletions 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

0 comments on commit ae1623b

Please sign in to comment.