Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion flang/examples/FeatureList/FeatureList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,6 @@ struct NodeVisitor {
READ_FEATURE(OmpChunkModifier::Value)
READ_FEATURE(OmpOrderingModifier)
READ_FEATURE(OmpOrderingModifier::Value)
READ_FEATURE(OmpSectionsDirective)
READ_FEATURE(Only)
READ_FEATURE(OpenACCAtomicConstruct)
READ_FEATURE(OpenACCBlockConstruct)
Expand Down
1 change: 0 additions & 1 deletion flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 1 addition & 2 deletions flang/include/flang/Parser/openmp-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
23 changes: 11 additions & 12 deletions flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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
Expand Down
26 changes: 9 additions & 17 deletions flang/lib/Lower/OpenMP/OpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 &sectionsConstruct) {
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());
}
Expand Down
22 changes: 13 additions & 9 deletions flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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{},
Expand Down
26 changes: 6 additions & 20 deletions flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)}) {
Expand All @@ -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
Expand Down
47 changes: 17 additions & 30 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1154,48 +1150,44 @@ 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,
"Expected OpenMP END SECTIONS directive"_err_en_US);
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 &sectionBlocks{std::get<std::list<parser::OpenMPConstruct>>(x.t)};
for (const parser::OpenMPConstruct &construct : sectionBlocks) {
auto &section{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 &) {
dirContext_.pop_back();
}

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
Expand Down Expand Up @@ -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)) {
Expand Down
10 changes: 4 additions & 6 deletions flang/lib/Semantics/resolve-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
30 changes: 20 additions & 10 deletions flang/test/Parser/OpenMP/sections.f90
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand All @@ -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`
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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