-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[flang][OpenMP] Use OmpDirectiveSpecification in SECTIONS #159580
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-flang-fir-hlfir @llvm/pr-subscribers-flang-semantics Author: Krzysztof Parzyszek (kparzysz) ChangesFull diff: https://github.com/llvm/llvm-project/pull/159580.diff 9 Files Affected:
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 1c9fd7673e06d..c34b2190c6b77 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -662,7 +662,6 @@ class ParseTreeDumper {
NODE(parser, OmpScheduleClause)
NODE(OmpScheduleClause, Modifier)
NODE_ENUM(OmpScheduleClause, Kind)
- NODE(parser, OmpSectionsDirective)
NODE(parser, OmpSelfModifier)
NODE_ENUM(OmpSelfModifier, Value)
NODE(parser, OmpSeverityClause)
diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h
index 032fb8996fe48..98e849eef9bbc 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -80,8 +80,7 @@ struct DirectiveNameScope {
static OmpDirectiveName GetOmpDirectiveName(
const OmpBeginSectionsDirective &x) {
- auto &dir{std::get<OmpSectionsDirective>(x.t)};
- return MakeName(dir.source, dir.v);
+ return x.DirName();
}
template <typename T>
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 7307283eb91ec..72b5c27752e45 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4879,20 +4879,13 @@ struct OpenMPAssumeConstruct : public OmpBlockConstruct {
// 2.7.2 SECTIONS
// 2.11.2 PARALLEL SECTIONS
-struct OmpSectionsDirective {
- WRAPPER_CLASS_BOILERPLATE(OmpSectionsDirective, llvm::omp::Directive);
- CharBlock source;
+struct OmpBeginSectionsDirective : public OmpBeginDirective {
+ INHERITED_TUPLE_CLASS_BOILERPLATE(
+ OmpBeginSectionsDirective, OmpBeginDirective);
};
-struct OmpBeginSectionsDirective {
- TUPLE_CLASS_BOILERPLATE(OmpBeginSectionsDirective);
- std::tuple<OmpSectionsDirective, OmpClauseList> t;
- CharBlock source;
-};
-struct OmpEndSectionsDirective {
- TUPLE_CLASS_BOILERPLATE(OmpEndSectionsDirective);
- std::tuple<OmpSectionsDirective, OmpClauseList> t;
- CharBlock source;
+struct OmpEndSectionsDirective : public OmpEndDirective {
+ INHERITED_TUPLE_CLASS_BOILERPLATE(OmpEndSectionsDirective, OmpEndDirective);
};
// [!$omp section]
@@ -4909,6 +4902,12 @@ struct OpenMPSectionConstruct {
struct OpenMPSectionsConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPSectionsConstruct);
CharBlock source;
+ const OmpBeginSectionsDirective &BeginDir() const {
+ return std::get<OmpBeginSectionsDirective>(t);
+ }
+ const std::optional<OmpEndSectionsDirective> &EndDir() const {
+ return std::get<std::optional<OmpEndSectionsDirective>>(t);
+ }
// Each of the OpenMPConstructs in the list below contains an
// OpenMPSectionConstruct. This is guaranteed by the parser.
// The end sections directive is optional here because it is difficult to
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 3a59c0f5f5a90..5681be664d450 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3858,30 +3858,22 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
- const parser::OpenMPSectionsConstruct §ionsConstruct) {
- const auto &beginSectionsDirective =
- std::get<parser::OmpBeginSectionsDirective>(sectionsConstruct.t);
- List<Clause> clauses = makeClauses(
- std::get<parser::OmpClauseList>(beginSectionsDirective.t), semaCtx);
- const auto &endSectionsDirective =
- std::get<std::optional<parser::OmpEndSectionsDirective>>(
- sectionsConstruct.t);
- assert(endSectionsDirective &&
+ const parser::OpenMPSectionsConstruct &construct) {
+ const parser::OmpDirectiveSpecification &beginSpec{construct.BeginDir()};
+ List<Clause> clauses = makeClauses(beginSpec.Clauses(), semaCtx);
+ const auto &endSpec{construct.EndDir()};
+ assert(endSpec &&
"Missing end section directive should have been handled in semantics");
- clauses.append(makeClauses(
- std::get<parser::OmpClauseList>(endSectionsDirective->t), semaCtx));
+ clauses.append(makeClauses(endSpec->Clauses(), semaCtx));
mlir::Location currentLocation = converter.getCurrentLocation();
- llvm::omp::Directive directive =
- std::get<parser::OmpSectionsDirective>(beginSectionsDirective.t).v;
- const parser::CharBlock &source =
- std::get<parser::OmpSectionsDirective>(beginSectionsDirective.t).source;
+ const parser::OmpDirectiveName &beginName{beginSpec.DirName()};
ConstructQueue queue{
buildConstructQueue(converter.getFirOpBuilder().getModule(), semaCtx,
- eval, source, directive, clauses)};
+ eval, beginName.source, beginName.v, clauses)};
mlir::SaveStateStack<SectionsConstructStackFrame> saveStateStack{
- converter.getStateStack(), sectionsConstruct};
+ converter.getStateStack(), construct};
genOMPDispatch(converter, symTable, semaCtx, eval, currentLocation, queue,
queue.begin());
}
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index c6d4de108fb59..a8f2f0056fe4a 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1862,17 +1862,21 @@ TYPE_PARSER( //
#undef MakeBlockConstruct
// OMP SECTIONS Directive
-TYPE_PARSER(construct<OmpSectionsDirective>(first(
- "SECTIONS" >> pure(llvm::omp::Directive::OMPD_sections),
- "PARALLEL SECTIONS" >> pure(llvm::omp::Directive::OMPD_parallel_sections))))
+static constexpr DirectiveSet GetSectionsDirectives() {
+ using Directive = llvm::omp::Directive;
+ constexpr DirectiveSet sectionsDirectives{
+ unsigned(Directive::OMPD_sections),
+ unsigned(Directive::OMPD_parallel_sections),
+ };
+ return sectionsDirectives;
+}
// OMP BEGIN and END SECTIONS Directive
-TYPE_PARSER(sourced(construct<OmpBeginSectionsDirective>(
- sourced(Parser<OmpSectionsDirective>{}), Parser<OmpClauseList>{})))
-TYPE_PARSER(
- startOmpLine >> sourced(construct<OmpEndSectionsDirective>(
- sourced("END"_tok >> Parser<OmpSectionsDirective>{}),
- Parser<OmpClauseList>{})))
+TYPE_PARSER(construct<OmpBeginSectionsDirective>(
+ OmpBeginDirectiveParser(GetSectionsDirectives())))
+
+TYPE_PARSER(construct<OmpEndSectionsDirective>(
+ OmpEndDirectiveParser(GetSectionsDirectives())))
static constexpr auto sectionDir{
startOmpLine >> (predicated(OmpDirectiveNameParser{},
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 73bbbc04f46b1..9d73bcafa0e15 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2618,18 +2618,6 @@ class UnparseVisitor {
Word("!$OMP NOTHING");
Put("\n");
}
- void Unparse(const OmpSectionsDirective &x) {
- switch (x.v) {
- case llvm::omp::Directive::OMPD_sections:
- Word("SECTIONS ");
- break;
- case llvm::omp::Directive::OMPD_parallel_sections:
- Word("PARALLEL SECTIONS ");
- break;
- default:
- break;
- }
- }
void Unparse(const OpenMPSectionConstruct &x) {
if (auto &&dirSpec{
std::get<std::optional<OmpDirectiveSpecification>>(x.t)}) {
@@ -2641,18 +2629,16 @@ class UnparseVisitor {
}
Walk(std::get<Block>(x.t), "");
}
+ void Unparse(const OmpBeginSectionsDirective &x) {
+ Unparse(static_cast<const OmpBeginDirective &>(x));
+ }
+ void Unparse(const OmpEndSectionsDirective &x) {
+ Unparse(static_cast<const OmpEndDirective &>(x));
+ }
void Unparse(const OpenMPSectionsConstruct &x) {
- BeginOpenMP();
- Word("!$OMP ");
Walk(std::get<OmpBeginSectionsDirective>(x.t));
- Put("\n");
- EndOpenMP();
Walk(std::get<std::list<OpenMPConstruct>>(x.t), "");
- BeginOpenMP();
- Word("!$OMP END ");
Walk(std::get<std::optional<OmpEndSectionsDirective>>(x.t));
- Put("\n");
- EndOpenMP();
}
// Clause unparsers are usually generated by tablegen in the form
// CLAUSE(VALUE). Here we only want to print VALUE so a custom unparser is
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 4c7cd1734e0e7..18f78b39e5e70 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -596,10 +596,6 @@ template <typename Checker> struct DirectiveSpellingVisitor {
return std::get<parser::OmpBeginDirective>(t).DirName();
}
- bool Pre(const parser::OmpSectionsDirective &x) {
- checker_(x.source, x.v);
- return false;
- }
bool Pre(const parser::OpenMPDeclarativeAllocate &x) {
checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_allocate);
return false;
@@ -1154,34 +1150,30 @@ void OmpStructureChecker::Leave(const parser::OmpBeginDirective &) {
}
void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
- const auto &beginSectionsDir{
- std::get<parser::OmpBeginSectionsDirective>(x.t)};
- const auto &endSectionsDir{
- std::get<std::optional<parser::OmpEndSectionsDirective>>(x.t)};
- const auto &beginDir{
- std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
- PushContextAndClauseSets(beginDir.source, beginDir.v);
-
- if (!endSectionsDir) {
- context_.Say(beginSectionsDir.source,
+ const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
+ const parser::OmpDirectiveName &beginName{beginSpec.DirName()};
+ const auto &endSpec{x.EndDir()};
+ PushContextAndClauseSets(beginName.source, beginName.v);
+
+ if (!endSpec) {
+ context_.Say(beginName.source,
"Expected OpenMP END SECTIONS directive"_err_en_US);
// Following code assumes the option is present.
return;
}
- const auto &endDir{std::get<parser::OmpSectionsDirective>(endSectionsDir->t)};
- CheckMatching<parser::OmpSectionsDirective>(beginDir, endDir);
+ CheckMatching<parser::OmpDirectiveName>(beginName, endSpec->DirName());
- AddEndDirectiveClauses(std::get<parser::OmpClauseList>(endSectionsDir->t));
+ AddEndDirectiveClauses(endSpec->Clauses());
const auto §ionBlocks{std::get<std::list<parser::OpenMPConstruct>>(x.t)};
for (const parser::OpenMPConstruct &construct : sectionBlocks) {
auto §ion{std::get<parser::OpenMPSectionConstruct>(construct.u)};
CheckNoBranching(
- std::get<parser::Block>(section.t), beginDir.v, beginDir.source);
+ std::get<parser::Block>(section.t), beginName.v, beginName.source);
}
HasInvalidWorksharingNesting(
- beginDir.source, llvm::omp::nestedWorkshareErrSet);
+ beginName.source, llvm::omp::nestedWorkshareErrSet);
}
void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &) {
@@ -1189,13 +1181,13 @@ void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &) {
}
void OmpStructureChecker::Enter(const parser::OmpEndSectionsDirective &x) {
- const auto &dir{std::get<parser::OmpSectionsDirective>(x.t)};
- ResetPartialContext(dir.source);
- switch (dir.v) {
+ const parser::OmpDirectiveName &dirName{x.DirName()};
+ ResetPartialContext(dirName.source);
+ switch (dirName.v) {
// 2.7.2 end-sections -> END SECTIONS [nowait-clause]
case llvm::omp::Directive::OMPD_sections:
PushContextAndClauseSets(
- dir.source, llvm::omp::Directive::OMPD_end_sections);
+ dirName.source, llvm::omp::Directive::OMPD_end_sections);
break;
default:
// no clauses are allowed
@@ -4648,12 +4640,7 @@ void OmpStructureChecker::CheckWorkshareBlockStmts(
} else if (const auto *ompSectionsConstruct{
std::get_if<parser::OpenMPSectionsConstruct>(
&ompConstruct->u)}) {
- const auto &beginSectionsDir{
- std::get<parser::OmpBeginSectionsDirective>(
- ompSectionsConstruct->t)};
- const auto &beginDir{
- std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
- currentDir = beginDir.v;
+ currentDir = ompSectionsConstruct->BeginDir().DirId();
}
if (!llvm::omp::topParallelSet.test(currentDir)) {
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index abb8f6430b29b..2d1bec9968593 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2278,14 +2278,12 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPGroupprivate &x) {
}
bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) {
- const auto &beginSectionsDir{
- std::get<parser::OmpBeginSectionsDirective>(x.t)};
- const auto &beginDir{
- std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
- switch (beginDir.v) {
+ const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
+ const parser::OmpDirectiveName &beginName{beginSpec.DirName()};
+ switch (beginName.v) {
case llvm::omp::Directive::OMPD_parallel_sections:
case llvm::omp::Directive::OMPD_sections:
- PushContext(beginDir.source, beginDir.v);
+ PushContext(beginName.source, beginName.v);
GetContext().withinConstruct = true;
break;
default:
diff --git a/flang/test/Parser/OpenMP/sections.f90 b/flang/test/Parser/OpenMP/sections.f90
index 8ba2294fb0faa..76e6b90f05721 100644
--- a/flang/test/Parser/OpenMP/sections.f90
+++ b/flang/test/Parser/OpenMP/sections.f90
@@ -15,13 +15,15 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | Block
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!==============================================================================
! single section, without `!$omp section`
@@ -35,16 +37,18 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | Block
!PARSE-TREE: | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> CallStmt = 'CALL f1()'
!PARSE-TREE: | | | | Call
!PARSE-TREE: | | | | | ProcedureDesignator -> Name = 'f1'
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!==============================================================================
! single section with `!$omp section`
@@ -60,8 +64,9 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = section
@@ -72,8 +77,9 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: | | | | Call
!PARSE-TREE: | | | | | ProcedureDesignator -> Name = 'f1'
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!==============================================================================
! multiple sections
@@ -97,8 +103,9 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = section
@@ -127,8 +134,9 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: | | | | Call
!PARSE-TREE: | | | | | ProcedureDesignator -> Name = 'f3'
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!==============================================================================
! multiple sections with clauses
@@ -152,9 +160,10 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Private -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
!PARSE-TREE: | | OmpClause -> Firstprivate -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'y'
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = section
@@ -183,7 +192,8 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: | | | | Call
!PARSE-TREE: | | | | | ProcedureDesignator -> Name = 'f3'
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Nowait
+!PARSE-TREE: | | Flags = None
END subroutine openmp_sections
|
|
@llvm/pr-subscribers-flang-openmp Author: Krzysztof Parzyszek (kparzysz) ChangesFull diff: https://github.com/llvm/llvm-project/pull/159580.diff 9 Files Affected:
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 1c9fd7673e06d..c34b2190c6b77 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -662,7 +662,6 @@ class ParseTreeDumper {
NODE(parser, OmpScheduleClause)
NODE(OmpScheduleClause, Modifier)
NODE_ENUM(OmpScheduleClause, Kind)
- NODE(parser, OmpSectionsDirective)
NODE(parser, OmpSelfModifier)
NODE_ENUM(OmpSelfModifier, Value)
NODE(parser, OmpSeverityClause)
diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h
index 032fb8996fe48..98e849eef9bbc 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -80,8 +80,7 @@ struct DirectiveNameScope {
static OmpDirectiveName GetOmpDirectiveName(
const OmpBeginSectionsDirective &x) {
- auto &dir{std::get<OmpSectionsDirective>(x.t)};
- return MakeName(dir.source, dir.v);
+ return x.DirName();
}
template <typename T>
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 7307283eb91ec..72b5c27752e45 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4879,20 +4879,13 @@ struct OpenMPAssumeConstruct : public OmpBlockConstruct {
// 2.7.2 SECTIONS
// 2.11.2 PARALLEL SECTIONS
-struct OmpSectionsDirective {
- WRAPPER_CLASS_BOILERPLATE(OmpSectionsDirective, llvm::omp::Directive);
- CharBlock source;
+struct OmpBeginSectionsDirective : public OmpBeginDirective {
+ INHERITED_TUPLE_CLASS_BOILERPLATE(
+ OmpBeginSectionsDirective, OmpBeginDirective);
};
-struct OmpBeginSectionsDirective {
- TUPLE_CLASS_BOILERPLATE(OmpBeginSectionsDirective);
- std::tuple<OmpSectionsDirective, OmpClauseList> t;
- CharBlock source;
-};
-struct OmpEndSectionsDirective {
- TUPLE_CLASS_BOILERPLATE(OmpEndSectionsDirective);
- std::tuple<OmpSectionsDirective, OmpClauseList> t;
- CharBlock source;
+struct OmpEndSectionsDirective : public OmpEndDirective {
+ INHERITED_TUPLE_CLASS_BOILERPLATE(OmpEndSectionsDirective, OmpEndDirective);
};
// [!$omp section]
@@ -4909,6 +4902,12 @@ struct OpenMPSectionConstruct {
struct OpenMPSectionsConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPSectionsConstruct);
CharBlock source;
+ const OmpBeginSectionsDirective &BeginDir() const {
+ return std::get<OmpBeginSectionsDirective>(t);
+ }
+ const std::optional<OmpEndSectionsDirective> &EndDir() const {
+ return std::get<std::optional<OmpEndSectionsDirective>>(t);
+ }
// Each of the OpenMPConstructs in the list below contains an
// OpenMPSectionConstruct. This is guaranteed by the parser.
// The end sections directive is optional here because it is difficult to
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 3a59c0f5f5a90..5681be664d450 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3858,30 +3858,22 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
- const parser::OpenMPSectionsConstruct §ionsConstruct) {
- const auto &beginSectionsDirective =
- std::get<parser::OmpBeginSectionsDirective>(sectionsConstruct.t);
- List<Clause> clauses = makeClauses(
- std::get<parser::OmpClauseList>(beginSectionsDirective.t), semaCtx);
- const auto &endSectionsDirective =
- std::get<std::optional<parser::OmpEndSectionsDirective>>(
- sectionsConstruct.t);
- assert(endSectionsDirective &&
+ const parser::OpenMPSectionsConstruct &construct) {
+ const parser::OmpDirectiveSpecification &beginSpec{construct.BeginDir()};
+ List<Clause> clauses = makeClauses(beginSpec.Clauses(), semaCtx);
+ const auto &endSpec{construct.EndDir()};
+ assert(endSpec &&
"Missing end section directive should have been handled in semantics");
- clauses.append(makeClauses(
- std::get<parser::OmpClauseList>(endSectionsDirective->t), semaCtx));
+ clauses.append(makeClauses(endSpec->Clauses(), semaCtx));
mlir::Location currentLocation = converter.getCurrentLocation();
- llvm::omp::Directive directive =
- std::get<parser::OmpSectionsDirective>(beginSectionsDirective.t).v;
- const parser::CharBlock &source =
- std::get<parser::OmpSectionsDirective>(beginSectionsDirective.t).source;
+ const parser::OmpDirectiveName &beginName{beginSpec.DirName()};
ConstructQueue queue{
buildConstructQueue(converter.getFirOpBuilder().getModule(), semaCtx,
- eval, source, directive, clauses)};
+ eval, beginName.source, beginName.v, clauses)};
mlir::SaveStateStack<SectionsConstructStackFrame> saveStateStack{
- converter.getStateStack(), sectionsConstruct};
+ converter.getStateStack(), construct};
genOMPDispatch(converter, symTable, semaCtx, eval, currentLocation, queue,
queue.begin());
}
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index c6d4de108fb59..a8f2f0056fe4a 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1862,17 +1862,21 @@ TYPE_PARSER( //
#undef MakeBlockConstruct
// OMP SECTIONS Directive
-TYPE_PARSER(construct<OmpSectionsDirective>(first(
- "SECTIONS" >> pure(llvm::omp::Directive::OMPD_sections),
- "PARALLEL SECTIONS" >> pure(llvm::omp::Directive::OMPD_parallel_sections))))
+static constexpr DirectiveSet GetSectionsDirectives() {
+ using Directive = llvm::omp::Directive;
+ constexpr DirectiveSet sectionsDirectives{
+ unsigned(Directive::OMPD_sections),
+ unsigned(Directive::OMPD_parallel_sections),
+ };
+ return sectionsDirectives;
+}
// OMP BEGIN and END SECTIONS Directive
-TYPE_PARSER(sourced(construct<OmpBeginSectionsDirective>(
- sourced(Parser<OmpSectionsDirective>{}), Parser<OmpClauseList>{})))
-TYPE_PARSER(
- startOmpLine >> sourced(construct<OmpEndSectionsDirective>(
- sourced("END"_tok >> Parser<OmpSectionsDirective>{}),
- Parser<OmpClauseList>{})))
+TYPE_PARSER(construct<OmpBeginSectionsDirective>(
+ OmpBeginDirectiveParser(GetSectionsDirectives())))
+
+TYPE_PARSER(construct<OmpEndSectionsDirective>(
+ OmpEndDirectiveParser(GetSectionsDirectives())))
static constexpr auto sectionDir{
startOmpLine >> (predicated(OmpDirectiveNameParser{},
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 73bbbc04f46b1..9d73bcafa0e15 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2618,18 +2618,6 @@ class UnparseVisitor {
Word("!$OMP NOTHING");
Put("\n");
}
- void Unparse(const OmpSectionsDirective &x) {
- switch (x.v) {
- case llvm::omp::Directive::OMPD_sections:
- Word("SECTIONS ");
- break;
- case llvm::omp::Directive::OMPD_parallel_sections:
- Word("PARALLEL SECTIONS ");
- break;
- default:
- break;
- }
- }
void Unparse(const OpenMPSectionConstruct &x) {
if (auto &&dirSpec{
std::get<std::optional<OmpDirectiveSpecification>>(x.t)}) {
@@ -2641,18 +2629,16 @@ class UnparseVisitor {
}
Walk(std::get<Block>(x.t), "");
}
+ void Unparse(const OmpBeginSectionsDirective &x) {
+ Unparse(static_cast<const OmpBeginDirective &>(x));
+ }
+ void Unparse(const OmpEndSectionsDirective &x) {
+ Unparse(static_cast<const OmpEndDirective &>(x));
+ }
void Unparse(const OpenMPSectionsConstruct &x) {
- BeginOpenMP();
- Word("!$OMP ");
Walk(std::get<OmpBeginSectionsDirective>(x.t));
- Put("\n");
- EndOpenMP();
Walk(std::get<std::list<OpenMPConstruct>>(x.t), "");
- BeginOpenMP();
- Word("!$OMP END ");
Walk(std::get<std::optional<OmpEndSectionsDirective>>(x.t));
- Put("\n");
- EndOpenMP();
}
// Clause unparsers are usually generated by tablegen in the form
// CLAUSE(VALUE). Here we only want to print VALUE so a custom unparser is
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 4c7cd1734e0e7..18f78b39e5e70 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -596,10 +596,6 @@ template <typename Checker> struct DirectiveSpellingVisitor {
return std::get<parser::OmpBeginDirective>(t).DirName();
}
- bool Pre(const parser::OmpSectionsDirective &x) {
- checker_(x.source, x.v);
- return false;
- }
bool Pre(const parser::OpenMPDeclarativeAllocate &x) {
checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_allocate);
return false;
@@ -1154,34 +1150,30 @@ void OmpStructureChecker::Leave(const parser::OmpBeginDirective &) {
}
void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
- const auto &beginSectionsDir{
- std::get<parser::OmpBeginSectionsDirective>(x.t)};
- const auto &endSectionsDir{
- std::get<std::optional<parser::OmpEndSectionsDirective>>(x.t)};
- const auto &beginDir{
- std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
- PushContextAndClauseSets(beginDir.source, beginDir.v);
-
- if (!endSectionsDir) {
- context_.Say(beginSectionsDir.source,
+ const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
+ const parser::OmpDirectiveName &beginName{beginSpec.DirName()};
+ const auto &endSpec{x.EndDir()};
+ PushContextAndClauseSets(beginName.source, beginName.v);
+
+ if (!endSpec) {
+ context_.Say(beginName.source,
"Expected OpenMP END SECTIONS directive"_err_en_US);
// Following code assumes the option is present.
return;
}
- const auto &endDir{std::get<parser::OmpSectionsDirective>(endSectionsDir->t)};
- CheckMatching<parser::OmpSectionsDirective>(beginDir, endDir);
+ CheckMatching<parser::OmpDirectiveName>(beginName, endSpec->DirName());
- AddEndDirectiveClauses(std::get<parser::OmpClauseList>(endSectionsDir->t));
+ AddEndDirectiveClauses(endSpec->Clauses());
const auto §ionBlocks{std::get<std::list<parser::OpenMPConstruct>>(x.t)};
for (const parser::OpenMPConstruct &construct : sectionBlocks) {
auto §ion{std::get<parser::OpenMPSectionConstruct>(construct.u)};
CheckNoBranching(
- std::get<parser::Block>(section.t), beginDir.v, beginDir.source);
+ std::get<parser::Block>(section.t), beginName.v, beginName.source);
}
HasInvalidWorksharingNesting(
- beginDir.source, llvm::omp::nestedWorkshareErrSet);
+ beginName.source, llvm::omp::nestedWorkshareErrSet);
}
void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &) {
@@ -1189,13 +1181,13 @@ void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &) {
}
void OmpStructureChecker::Enter(const parser::OmpEndSectionsDirective &x) {
- const auto &dir{std::get<parser::OmpSectionsDirective>(x.t)};
- ResetPartialContext(dir.source);
- switch (dir.v) {
+ const parser::OmpDirectiveName &dirName{x.DirName()};
+ ResetPartialContext(dirName.source);
+ switch (dirName.v) {
// 2.7.2 end-sections -> END SECTIONS [nowait-clause]
case llvm::omp::Directive::OMPD_sections:
PushContextAndClauseSets(
- dir.source, llvm::omp::Directive::OMPD_end_sections);
+ dirName.source, llvm::omp::Directive::OMPD_end_sections);
break;
default:
// no clauses are allowed
@@ -4648,12 +4640,7 @@ void OmpStructureChecker::CheckWorkshareBlockStmts(
} else if (const auto *ompSectionsConstruct{
std::get_if<parser::OpenMPSectionsConstruct>(
&ompConstruct->u)}) {
- const auto &beginSectionsDir{
- std::get<parser::OmpBeginSectionsDirective>(
- ompSectionsConstruct->t)};
- const auto &beginDir{
- std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
- currentDir = beginDir.v;
+ currentDir = ompSectionsConstruct->BeginDir().DirId();
}
if (!llvm::omp::topParallelSet.test(currentDir)) {
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index abb8f6430b29b..2d1bec9968593 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2278,14 +2278,12 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPGroupprivate &x) {
}
bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) {
- const auto &beginSectionsDir{
- std::get<parser::OmpBeginSectionsDirective>(x.t)};
- const auto &beginDir{
- std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
- switch (beginDir.v) {
+ const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
+ const parser::OmpDirectiveName &beginName{beginSpec.DirName()};
+ switch (beginName.v) {
case llvm::omp::Directive::OMPD_parallel_sections:
case llvm::omp::Directive::OMPD_sections:
- PushContext(beginDir.source, beginDir.v);
+ PushContext(beginName.source, beginName.v);
GetContext().withinConstruct = true;
break;
default:
diff --git a/flang/test/Parser/OpenMP/sections.f90 b/flang/test/Parser/OpenMP/sections.f90
index 8ba2294fb0faa..76e6b90f05721 100644
--- a/flang/test/Parser/OpenMP/sections.f90
+++ b/flang/test/Parser/OpenMP/sections.f90
@@ -15,13 +15,15 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | Block
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!==============================================================================
! single section, without `!$omp section`
@@ -35,16 +37,18 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | Block
!PARSE-TREE: | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> CallStmt = 'CALL f1()'
!PARSE-TREE: | | | | Call
!PARSE-TREE: | | | | | ProcedureDesignator -> Name = 'f1'
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!==============================================================================
! single section with `!$omp section`
@@ -60,8 +64,9 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = section
@@ -72,8 +77,9 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: | | | | Call
!PARSE-TREE: | | | | | ProcedureDesignator -> Name = 'f1'
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!==============================================================================
! multiple sections
@@ -97,8 +103,9 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = section
@@ -127,8 +134,9 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: | | | | Call
!PARSE-TREE: | | | | | ProcedureDesignator -> Name = 'f3'
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!==============================================================================
! multiple sections with clauses
@@ -152,9 +160,10 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Private -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
!PARSE-TREE: | | OmpClause -> Firstprivate -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'y'
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = section
@@ -183,7 +192,8 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: | | | | Call
!PARSE-TREE: | | | | | ProcedureDesignator -> Name = 'f3'
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Nowait
+!PARSE-TREE: | | Flags = None
END subroutine openmp_sections
|
|
@llvm/pr-subscribers-flang-parser Author: Krzysztof Parzyszek (kparzysz) ChangesFull diff: https://github.com/llvm/llvm-project/pull/159580.diff 9 Files Affected:
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 1c9fd7673e06d..c34b2190c6b77 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -662,7 +662,6 @@ class ParseTreeDumper {
NODE(parser, OmpScheduleClause)
NODE(OmpScheduleClause, Modifier)
NODE_ENUM(OmpScheduleClause, Kind)
- NODE(parser, OmpSectionsDirective)
NODE(parser, OmpSelfModifier)
NODE_ENUM(OmpSelfModifier, Value)
NODE(parser, OmpSeverityClause)
diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h
index 032fb8996fe48..98e849eef9bbc 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -80,8 +80,7 @@ struct DirectiveNameScope {
static OmpDirectiveName GetOmpDirectiveName(
const OmpBeginSectionsDirective &x) {
- auto &dir{std::get<OmpSectionsDirective>(x.t)};
- return MakeName(dir.source, dir.v);
+ return x.DirName();
}
template <typename T>
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 7307283eb91ec..72b5c27752e45 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4879,20 +4879,13 @@ struct OpenMPAssumeConstruct : public OmpBlockConstruct {
// 2.7.2 SECTIONS
// 2.11.2 PARALLEL SECTIONS
-struct OmpSectionsDirective {
- WRAPPER_CLASS_BOILERPLATE(OmpSectionsDirective, llvm::omp::Directive);
- CharBlock source;
+struct OmpBeginSectionsDirective : public OmpBeginDirective {
+ INHERITED_TUPLE_CLASS_BOILERPLATE(
+ OmpBeginSectionsDirective, OmpBeginDirective);
};
-struct OmpBeginSectionsDirective {
- TUPLE_CLASS_BOILERPLATE(OmpBeginSectionsDirective);
- std::tuple<OmpSectionsDirective, OmpClauseList> t;
- CharBlock source;
-};
-struct OmpEndSectionsDirective {
- TUPLE_CLASS_BOILERPLATE(OmpEndSectionsDirective);
- std::tuple<OmpSectionsDirective, OmpClauseList> t;
- CharBlock source;
+struct OmpEndSectionsDirective : public OmpEndDirective {
+ INHERITED_TUPLE_CLASS_BOILERPLATE(OmpEndSectionsDirective, OmpEndDirective);
};
// [!$omp section]
@@ -4909,6 +4902,12 @@ struct OpenMPSectionConstruct {
struct OpenMPSectionsConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPSectionsConstruct);
CharBlock source;
+ const OmpBeginSectionsDirective &BeginDir() const {
+ return std::get<OmpBeginSectionsDirective>(t);
+ }
+ const std::optional<OmpEndSectionsDirective> &EndDir() const {
+ return std::get<std::optional<OmpEndSectionsDirective>>(t);
+ }
// Each of the OpenMPConstructs in the list below contains an
// OpenMPSectionConstruct. This is guaranteed by the parser.
// The end sections directive is optional here because it is difficult to
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 3a59c0f5f5a90..5681be664d450 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3858,30 +3858,22 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
- const parser::OpenMPSectionsConstruct §ionsConstruct) {
- const auto &beginSectionsDirective =
- std::get<parser::OmpBeginSectionsDirective>(sectionsConstruct.t);
- List<Clause> clauses = makeClauses(
- std::get<parser::OmpClauseList>(beginSectionsDirective.t), semaCtx);
- const auto &endSectionsDirective =
- std::get<std::optional<parser::OmpEndSectionsDirective>>(
- sectionsConstruct.t);
- assert(endSectionsDirective &&
+ const parser::OpenMPSectionsConstruct &construct) {
+ const parser::OmpDirectiveSpecification &beginSpec{construct.BeginDir()};
+ List<Clause> clauses = makeClauses(beginSpec.Clauses(), semaCtx);
+ const auto &endSpec{construct.EndDir()};
+ assert(endSpec &&
"Missing end section directive should have been handled in semantics");
- clauses.append(makeClauses(
- std::get<parser::OmpClauseList>(endSectionsDirective->t), semaCtx));
+ clauses.append(makeClauses(endSpec->Clauses(), semaCtx));
mlir::Location currentLocation = converter.getCurrentLocation();
- llvm::omp::Directive directive =
- std::get<parser::OmpSectionsDirective>(beginSectionsDirective.t).v;
- const parser::CharBlock &source =
- std::get<parser::OmpSectionsDirective>(beginSectionsDirective.t).source;
+ const parser::OmpDirectiveName &beginName{beginSpec.DirName()};
ConstructQueue queue{
buildConstructQueue(converter.getFirOpBuilder().getModule(), semaCtx,
- eval, source, directive, clauses)};
+ eval, beginName.source, beginName.v, clauses)};
mlir::SaveStateStack<SectionsConstructStackFrame> saveStateStack{
- converter.getStateStack(), sectionsConstruct};
+ converter.getStateStack(), construct};
genOMPDispatch(converter, symTable, semaCtx, eval, currentLocation, queue,
queue.begin());
}
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index c6d4de108fb59..a8f2f0056fe4a 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1862,17 +1862,21 @@ TYPE_PARSER( //
#undef MakeBlockConstruct
// OMP SECTIONS Directive
-TYPE_PARSER(construct<OmpSectionsDirective>(first(
- "SECTIONS" >> pure(llvm::omp::Directive::OMPD_sections),
- "PARALLEL SECTIONS" >> pure(llvm::omp::Directive::OMPD_parallel_sections))))
+static constexpr DirectiveSet GetSectionsDirectives() {
+ using Directive = llvm::omp::Directive;
+ constexpr DirectiveSet sectionsDirectives{
+ unsigned(Directive::OMPD_sections),
+ unsigned(Directive::OMPD_parallel_sections),
+ };
+ return sectionsDirectives;
+}
// OMP BEGIN and END SECTIONS Directive
-TYPE_PARSER(sourced(construct<OmpBeginSectionsDirective>(
- sourced(Parser<OmpSectionsDirective>{}), Parser<OmpClauseList>{})))
-TYPE_PARSER(
- startOmpLine >> sourced(construct<OmpEndSectionsDirective>(
- sourced("END"_tok >> Parser<OmpSectionsDirective>{}),
- Parser<OmpClauseList>{})))
+TYPE_PARSER(construct<OmpBeginSectionsDirective>(
+ OmpBeginDirectiveParser(GetSectionsDirectives())))
+
+TYPE_PARSER(construct<OmpEndSectionsDirective>(
+ OmpEndDirectiveParser(GetSectionsDirectives())))
static constexpr auto sectionDir{
startOmpLine >> (predicated(OmpDirectiveNameParser{},
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 73bbbc04f46b1..9d73bcafa0e15 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2618,18 +2618,6 @@ class UnparseVisitor {
Word("!$OMP NOTHING");
Put("\n");
}
- void Unparse(const OmpSectionsDirective &x) {
- switch (x.v) {
- case llvm::omp::Directive::OMPD_sections:
- Word("SECTIONS ");
- break;
- case llvm::omp::Directive::OMPD_parallel_sections:
- Word("PARALLEL SECTIONS ");
- break;
- default:
- break;
- }
- }
void Unparse(const OpenMPSectionConstruct &x) {
if (auto &&dirSpec{
std::get<std::optional<OmpDirectiveSpecification>>(x.t)}) {
@@ -2641,18 +2629,16 @@ class UnparseVisitor {
}
Walk(std::get<Block>(x.t), "");
}
+ void Unparse(const OmpBeginSectionsDirective &x) {
+ Unparse(static_cast<const OmpBeginDirective &>(x));
+ }
+ void Unparse(const OmpEndSectionsDirective &x) {
+ Unparse(static_cast<const OmpEndDirective &>(x));
+ }
void Unparse(const OpenMPSectionsConstruct &x) {
- BeginOpenMP();
- Word("!$OMP ");
Walk(std::get<OmpBeginSectionsDirective>(x.t));
- Put("\n");
- EndOpenMP();
Walk(std::get<std::list<OpenMPConstruct>>(x.t), "");
- BeginOpenMP();
- Word("!$OMP END ");
Walk(std::get<std::optional<OmpEndSectionsDirective>>(x.t));
- Put("\n");
- EndOpenMP();
}
// Clause unparsers are usually generated by tablegen in the form
// CLAUSE(VALUE). Here we only want to print VALUE so a custom unparser is
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 4c7cd1734e0e7..18f78b39e5e70 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -596,10 +596,6 @@ template <typename Checker> struct DirectiveSpellingVisitor {
return std::get<parser::OmpBeginDirective>(t).DirName();
}
- bool Pre(const parser::OmpSectionsDirective &x) {
- checker_(x.source, x.v);
- return false;
- }
bool Pre(const parser::OpenMPDeclarativeAllocate &x) {
checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_allocate);
return false;
@@ -1154,34 +1150,30 @@ void OmpStructureChecker::Leave(const parser::OmpBeginDirective &) {
}
void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
- const auto &beginSectionsDir{
- std::get<parser::OmpBeginSectionsDirective>(x.t)};
- const auto &endSectionsDir{
- std::get<std::optional<parser::OmpEndSectionsDirective>>(x.t)};
- const auto &beginDir{
- std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
- PushContextAndClauseSets(beginDir.source, beginDir.v);
-
- if (!endSectionsDir) {
- context_.Say(beginSectionsDir.source,
+ const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
+ const parser::OmpDirectiveName &beginName{beginSpec.DirName()};
+ const auto &endSpec{x.EndDir()};
+ PushContextAndClauseSets(beginName.source, beginName.v);
+
+ if (!endSpec) {
+ context_.Say(beginName.source,
"Expected OpenMP END SECTIONS directive"_err_en_US);
// Following code assumes the option is present.
return;
}
- const auto &endDir{std::get<parser::OmpSectionsDirective>(endSectionsDir->t)};
- CheckMatching<parser::OmpSectionsDirective>(beginDir, endDir);
+ CheckMatching<parser::OmpDirectiveName>(beginName, endSpec->DirName());
- AddEndDirectiveClauses(std::get<parser::OmpClauseList>(endSectionsDir->t));
+ AddEndDirectiveClauses(endSpec->Clauses());
const auto §ionBlocks{std::get<std::list<parser::OpenMPConstruct>>(x.t)};
for (const parser::OpenMPConstruct &construct : sectionBlocks) {
auto §ion{std::get<parser::OpenMPSectionConstruct>(construct.u)};
CheckNoBranching(
- std::get<parser::Block>(section.t), beginDir.v, beginDir.source);
+ std::get<parser::Block>(section.t), beginName.v, beginName.source);
}
HasInvalidWorksharingNesting(
- beginDir.source, llvm::omp::nestedWorkshareErrSet);
+ beginName.source, llvm::omp::nestedWorkshareErrSet);
}
void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &) {
@@ -1189,13 +1181,13 @@ void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &) {
}
void OmpStructureChecker::Enter(const parser::OmpEndSectionsDirective &x) {
- const auto &dir{std::get<parser::OmpSectionsDirective>(x.t)};
- ResetPartialContext(dir.source);
- switch (dir.v) {
+ const parser::OmpDirectiveName &dirName{x.DirName()};
+ ResetPartialContext(dirName.source);
+ switch (dirName.v) {
// 2.7.2 end-sections -> END SECTIONS [nowait-clause]
case llvm::omp::Directive::OMPD_sections:
PushContextAndClauseSets(
- dir.source, llvm::omp::Directive::OMPD_end_sections);
+ dirName.source, llvm::omp::Directive::OMPD_end_sections);
break;
default:
// no clauses are allowed
@@ -4648,12 +4640,7 @@ void OmpStructureChecker::CheckWorkshareBlockStmts(
} else if (const auto *ompSectionsConstruct{
std::get_if<parser::OpenMPSectionsConstruct>(
&ompConstruct->u)}) {
- const auto &beginSectionsDir{
- std::get<parser::OmpBeginSectionsDirective>(
- ompSectionsConstruct->t)};
- const auto &beginDir{
- std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
- currentDir = beginDir.v;
+ currentDir = ompSectionsConstruct->BeginDir().DirId();
}
if (!llvm::omp::topParallelSet.test(currentDir)) {
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index abb8f6430b29b..2d1bec9968593 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2278,14 +2278,12 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPGroupprivate &x) {
}
bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) {
- const auto &beginSectionsDir{
- std::get<parser::OmpBeginSectionsDirective>(x.t)};
- const auto &beginDir{
- std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
- switch (beginDir.v) {
+ const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
+ const parser::OmpDirectiveName &beginName{beginSpec.DirName()};
+ switch (beginName.v) {
case llvm::omp::Directive::OMPD_parallel_sections:
case llvm::omp::Directive::OMPD_sections:
- PushContext(beginDir.source, beginDir.v);
+ PushContext(beginName.source, beginName.v);
GetContext().withinConstruct = true;
break;
default:
diff --git a/flang/test/Parser/OpenMP/sections.f90 b/flang/test/Parser/OpenMP/sections.f90
index 8ba2294fb0faa..76e6b90f05721 100644
--- a/flang/test/Parser/OpenMP/sections.f90
+++ b/flang/test/Parser/OpenMP/sections.f90
@@ -15,13 +15,15 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | Block
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!==============================================================================
! single section, without `!$omp section`
@@ -35,16 +37,18 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | Block
!PARSE-TREE: | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> CallStmt = 'CALL f1()'
!PARSE-TREE: | | | | Call
!PARSE-TREE: | | | | | ProcedureDesignator -> Name = 'f1'
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!==============================================================================
! single section with `!$omp section`
@@ -60,8 +64,9 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = section
@@ -72,8 +77,9 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: | | | | Call
!PARSE-TREE: | | | | | ProcedureDesignator -> Name = 'f1'
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!==============================================================================
! multiple sections
@@ -97,8 +103,9 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = section
@@ -127,8 +134,9 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: | | | | Call
!PARSE-TREE: | | | | | ProcedureDesignator -> Name = 'f3'
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
!==============================================================================
! multiple sections with clauses
@@ -152,9 +160,10 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPSectionsConstruct
!PARSE-TREE: | OmpBeginSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Private -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
!PARSE-TREE: | | OmpClause -> Firstprivate -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'y'
+!PARSE-TREE: | | Flags = None
!PARSE-TREE: | OpenMPConstruct -> OpenMPSectionConstruct
!PARSE-TREE: | | OmpDirectiveSpecification
!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = section
@@ -183,7 +192,8 @@ subroutine openmp_sections(x, y)
!PARSE-TREE: | | | | Call
!PARSE-TREE: | | | | | ProcedureDesignator -> Name = 'f3'
!PARSE-TREE: | OmpEndSectionsDirective
-!PARSE-TREE: | | OmpSectionsDirective -> llvm::omp::Directive = sections
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = sections
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Nowait
+!PARSE-TREE: | | Flags = None
END subroutine openmp_sections
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
No description provided.