[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
This commit is contained in:
Shraiysh Vaishay 2022-03-18 20:37:25 +05:30
parent 831ab35b2f
commit ae1623b306
10 changed files with 279 additions and 11 deletions

View File

@ -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

View File

@ -562,6 +562,7 @@ public:
NODE(parser, OpenMPExecutableAllocate)
NODE(parser, OpenMPSimpleStandaloneConstruct)
NODE(parser, OpenMPStandaloneConstruct)
NODE(parser, OpenMPSectionConstruct)
NODE(parser, OpenMPSectionsConstruct)
NODE(parser, OpenMPThreadprivate)
NODE(parser, OpenStmt)

View File

@ -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;
};

View File

@ -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");
},

View File

@ -529,11 +529,15 @@ TYPE_PARSER(
Parser<OmpClauseList>{})))
// OMP SECTION-BLOCK
TYPE_PARSER(maybe(startOmpLine >> "SECTION"_tok / endOmpLine) >>
construct<OmpSectionBlocks>(
nonemptySeparated(block, startOmpLine >> "SECTION"_tok / endOmpLine)))
// OMP SECTIONS (2.7.2), PARALLEL SECTIONS (2.11.2)
TYPE_PARSER(construct<OpenMPSectionConstruct>(block))
TYPE_PARSER(maybe(startOmpLine >> "SECTION"_tok / endOmpLine) >>
construct<OmpSectionBlocks>(nonemptySeparated(
construct<OpenMPConstruct>(sourced(Parser<OpenMPSectionConstruct>{})),
startOmpLine >> "SECTION"_tok / endOmpLine)))
// 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))

View File

@ -2405,7 +2405,9 @@ public:
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) {

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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