diff --git a/clang/docs/tools/clang-formatted-files.txt b/clang/docs/tools/clang-formatted-files.txt index 27aab1e130524..e22f01e8c150e 100644 --- a/clang/docs/tools/clang-formatted-files.txt +++ b/clang/docs/tools/clang-formatted-files.txt @@ -2185,6 +2185,8 @@ flang/include/flang/Runtime/time-intrinsic.h flang/include/flang/Runtime/transformational.h flang/include/flang/Runtime/type-code.h flang/include/flang/Semantics/attr.h +flang/include/flang/Semantics/expression.h +flang/include/flang/Semantics/openmp-directive-sets.h flang/include/flang/Semantics/runtime-type-info.h flang/include/flang/Semantics/scope.h flang/include/flang/Semantics/semantics.h diff --git a/flang/include/flang/Semantics/openmp-directive-sets.h b/flang/include/flang/Semantics/openmp-directive-sets.h new file mode 100644 index 0000000000000..29bec4994a3d5 --- /dev/null +++ b/flang/include/flang/Semantics/openmp-directive-sets.h @@ -0,0 +1,283 @@ +//===-- include/flang/Semantics/openmp-directive-sets.h ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_SEMANTICS_OPENMP_DIRECTIVE_SETS_H_ +#define FORTRAN_SEMANTICS_OPENMP_DIRECTIVE_SETS_H_ + +#include "flang/Common/enum-set.h" +#include "llvm/Frontend/OpenMP/OMPConstants.h" + +using OmpDirectiveSet = Fortran::common::EnumSet; + +namespace llvm::omp { +//===----------------------------------------------------------------------===// +// Directive sets for single directives +//===----------------------------------------------------------------------===// +// - topSet: The directive appears alone or as the first in a +// combined construct. +// - allSet: All standalone or combined uses of the directive. + +static const OmpDirectiveSet topParallelSet{ + Directive::OMPD_parallel, + Directive::OMPD_parallel_do, + Directive::OMPD_parallel_do_simd, + Directive::OMPD_parallel_sections, + Directive::OMPD_parallel_workshare, +}; + +static const OmpDirectiveSet allParallelSet{ + Directive::OMPD_distribute_parallel_do, + Directive::OMPD_distribute_parallel_do_simd, + Directive::OMPD_parallel, + Directive::OMPD_parallel_do, + Directive::OMPD_parallel_do_simd, + Directive::OMPD_parallel_sections, + Directive::OMPD_parallel_workshare, + Directive::OMPD_target_parallel, + Directive::OMPD_target_parallel_do, + Directive::OMPD_target_parallel_do_simd, + Directive::OMPD_target_teams_distribute_parallel_do, + Directive::OMPD_target_teams_distribute_parallel_do_simd, + Directive::OMPD_teams_distribute_parallel_do, + Directive::OMPD_teams_distribute_parallel_do_simd, +}; + +static const OmpDirectiveSet topDoSet{ + Directive::OMPD_do, + Directive::OMPD_do_simd, +}; + +static const OmpDirectiveSet allDoSet{ + Directive::OMPD_distribute_parallel_do, + Directive::OMPD_distribute_parallel_do_simd, + Directive::OMPD_parallel_do, + Directive::OMPD_parallel_do_simd, + Directive::OMPD_do, + Directive::OMPD_do_simd, + Directive::OMPD_target_parallel_do, + Directive::OMPD_target_parallel_do_simd, + Directive::OMPD_target_teams_distribute_parallel_do, + Directive::OMPD_target_teams_distribute_parallel_do_simd, + Directive::OMPD_teams_distribute_parallel_do, + Directive::OMPD_teams_distribute_parallel_do_simd, +}; + +static const OmpDirectiveSet topTaskloopSet{ + Directive::OMPD_taskloop, + Directive::OMPD_taskloop_simd, +}; + +static const OmpDirectiveSet allTaskloopSet{topTaskloopSet}; + +static const OmpDirectiveSet topTargetSet{ + Directive::OMPD_target, + Directive::OMPD_target_parallel, + Directive::OMPD_target_parallel_do, + Directive::OMPD_target_parallel_do_simd, + Directive::OMPD_target_simd, + Directive::OMPD_target_teams, + Directive::OMPD_target_teams_distribute, + Directive::OMPD_target_teams_distribute_parallel_do, + Directive::OMPD_target_teams_distribute_parallel_do_simd, + Directive::OMPD_target_teams_distribute_simd, +}; + +static const OmpDirectiveSet allTargetSet{topTargetSet}; + +static const OmpDirectiveSet topSimdSet{ + Directive::OMPD_simd, +}; + +static const OmpDirectiveSet allSimdSet{ + Directive::OMPD_distribute_parallel_do_simd, + Directive::OMPD_distribute_simd, + Directive::OMPD_do_simd, + Directive::OMPD_parallel_do_simd, + Directive::OMPD_simd, + Directive::OMPD_target_parallel_do_simd, + Directive::OMPD_target_simd, + Directive::OMPD_target_teams_distribute_parallel_do_simd, + Directive::OMPD_target_teams_distribute_simd, + Directive::OMPD_taskloop_simd, + Directive::OMPD_teams_distribute_parallel_do_simd, + Directive::OMPD_teams_distribute_simd, +}; + +static const OmpDirectiveSet topTeamsSet{ + Directive::OMPD_teams, + Directive::OMPD_teams_distribute, + Directive::OMPD_teams_distribute_parallel_do, + Directive::OMPD_teams_distribute_parallel_do_simd, + Directive::OMPD_teams_distribute_simd, +}; + +static const OmpDirectiveSet allTeamsSet{ + llvm::omp::OMPD_target_teams, + llvm::omp::OMPD_target_teams_distribute, + llvm::omp::OMPD_target_teams_distribute_parallel_do, + llvm::omp::OMPD_target_teams_distribute_parallel_do_simd, + llvm::omp::OMPD_target_teams_distribute_simd, + llvm::omp::OMPD_teams, + llvm::omp::OMPD_teams_distribute, + llvm::omp::OMPD_teams_distribute_parallel_do, + llvm::omp::OMPD_teams_distribute_parallel_do_simd, + llvm::omp::OMPD_teams_distribute_simd, +}; + +static const OmpDirectiveSet topDistributeSet{ + Directive::OMPD_distribute, + Directive::OMPD_distribute_parallel_do, + Directive::OMPD_distribute_parallel_do_simd, + Directive::OMPD_distribute_simd, +}; + +static const OmpDirectiveSet allDistributeSet{ + llvm::omp::OMPD_distribute, + llvm::omp::OMPD_distribute_parallel_do, + llvm::omp::OMPD_distribute_parallel_do_simd, + llvm::omp::OMPD_distribute_simd, + llvm::omp::OMPD_target_teams_distribute, + llvm::omp::OMPD_target_teams_distribute_parallel_do, + llvm::omp::OMPD_target_teams_distribute_parallel_do_simd, + llvm::omp::OMPD_target_teams_distribute_simd, + llvm::omp::OMPD_teams_distribute, + llvm::omp::OMPD_teams_distribute_parallel_do, + llvm::omp::OMPD_teams_distribute_parallel_do_simd, + llvm::omp::OMPD_teams_distribute_simd, +}; + +//===----------------------------------------------------------------------===// +// Directive sets for groups of multiple directives +//===----------------------------------------------------------------------===// + +static const OmpDirectiveSet allDoSimdSet{allDoSet & allSimdSet}; + +static const OmpDirectiveSet workShareSet{ + OmpDirectiveSet{ + Directive::OMPD_workshare, + Directive::OMPD_parallel_workshare, + Directive::OMPD_parallel_sections, + Directive::OMPD_sections, + Directive::OMPD_single, + } | allDoSet, +}; + +static const OmpDirectiveSet taskGeneratingSet{ + OmpDirectiveSet{ + Directive::OMPD_task, + } | allTaskloopSet, +}; + +static const OmpDirectiveSet nonPartialVarSet{ + Directive::OMPD_allocate, + Directive::OMPD_allocators, + Directive::OMPD_threadprivate, + Directive::OMPD_declare_target, +}; + +//===----------------------------------------------------------------------===// +// Directive sets for allowed/not allowed nested directives +//===----------------------------------------------------------------------===// + +static const OmpDirectiveSet nestedOrderedErrSet{ + Directive::OMPD_critical, + Directive::OMPD_ordered, + Directive::OMPD_atomic, + Directive::OMPD_task, + Directive::OMPD_taskloop, +}; + +static const OmpDirectiveSet nestedWorkshareErrSet{ + OmpDirectiveSet{ + Directive::OMPD_task, + Directive::OMPD_taskloop, + Directive::OMPD_critical, + Directive::OMPD_ordered, + Directive::OMPD_atomic, + Directive::OMPD_master, + } | workShareSet, +}; + +static const OmpDirectiveSet nestedMasterErrSet{ + OmpDirectiveSet{ + Directive::OMPD_atomic, + } | taskGeneratingSet | + workShareSet, +}; + +static const OmpDirectiveSet nestedBarrierErrSet{ + OmpDirectiveSet{ + Directive::OMPD_critical, + Directive::OMPD_ordered, + Directive::OMPD_atomic, + Directive::OMPD_master, + } | taskGeneratingSet | + workShareSet, +}; + +static const OmpDirectiveSet nestedTeamsAllowedSet{ + Directive::OMPD_parallel, + Directive::OMPD_parallel_do, + Directive::OMPD_parallel_do_simd, + Directive::OMPD_parallel_master, + Directive::OMPD_parallel_master_taskloop, + Directive::OMPD_parallel_master_taskloop_simd, + Directive::OMPD_parallel_sections, + Directive::OMPD_parallel_workshare, + Directive::OMPD_distribute, + Directive::OMPD_distribute_parallel_do, + Directive::OMPD_distribute_parallel_do_simd, + Directive::OMPD_distribute_simd, +}; + +static const OmpDirectiveSet nestedOrderedParallelErrSet{ + Directive::OMPD_parallel, + Directive::OMPD_target_parallel, + Directive::OMPD_parallel_sections, + Directive::OMPD_parallel_workshare, +}; + +static const OmpDirectiveSet nestedOrderedDoAllowedSet{ + Directive::OMPD_do, + Directive::OMPD_parallel_do, + Directive::OMPD_target_parallel_do, +}; + +static const OmpDirectiveSet nestedCancelTaskgroupAllowedSet{ + Directive::OMPD_task, + Directive::OMPD_taskloop, +}; + +static const OmpDirectiveSet nestedCancelSectionsAllowedSet{ + Directive::OMPD_sections, + Directive::OMPD_parallel_sections, +}; + +static const OmpDirectiveSet nestedCancelDoAllowedSet{ + Directive::OMPD_do, + Directive::OMPD_distribute_parallel_do, + Directive::OMPD_parallel_do, + Directive::OMPD_target_parallel_do, + Directive::OMPD_target_teams_distribute_parallel_do, + Directive::OMPD_teams_distribute_parallel_do, +}; + +static const OmpDirectiveSet nestedCancelParallelAllowedSet{ + Directive::OMPD_parallel, + Directive::OMPD_target_parallel, +}; + +static const OmpDirectiveSet nestedReduceWorkshareAllowedSet{ + Directive::OMPD_do, + Directive::OMPD_sections, + Directive::OMPD_do_simd, +}; +} // namespace llvm::omp + +#endif // FORTRAN_SEMANTICS_OPENMP_DIRECTIVE_SETS_H_ diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 0accfa5083a9d..7a04d28bfa8ad 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -161,7 +161,7 @@ bool OmpStructureChecker::IsCloselyNestedRegion(const OmpDirectiveSet &set) { while (index != -1) { if (set.test(dirContext_[index].directive)) { return true; - } else if (llvm::omp::parallelSet.test(dirContext_[index].directive)) { + } else if (llvm::omp::allParallelSet.test(dirContext_[index].directive)) { return false; } index--; @@ -251,23 +251,15 @@ bool OmpStructureChecker::HasInvalidWorksharingNesting( void OmpStructureChecker::HasInvalidDistributeNesting( const parser::OpenMPLoopConstruct &x) { bool violation{false}; - - OmpDirectiveSet distributeSet{llvm::omp::Directive::OMPD_distribute, - llvm::omp::Directive::OMPD_distribute_parallel_do, - llvm::omp::Directive::OMPD_distribute_parallel_do_simd, - llvm::omp::Directive::OMPD_distribute_parallel_for, - llvm::omp::Directive::OMPD_distribute_parallel_for_simd, - llvm::omp::Directive::OMPD_distribute_simd}; - const auto &beginLoopDir{std::get(x.t)}; const auto &beginDir{std::get(beginLoopDir.t)}; - if (distributeSet.test(beginDir.v)) { + if (llvm::omp::topDistributeSet.test(beginDir.v)) { // `distribute` region has to be nested if (!CurrentDirectiveIsNested()) { violation = true; } else { // `distribute` region has to be strictly nested inside `teams` - if (!llvm::omp::teamSet.test(GetContextParent().directive)) { + if (!llvm::omp::topTeamsSet.test(GetContextParent().directive)) { violation = true; } } @@ -281,24 +273,7 @@ void OmpStructureChecker::HasInvalidDistributeNesting( void OmpStructureChecker::HasInvalidTeamsNesting( const llvm::omp::Directive &dir, const parser::CharBlock &source) { - OmpDirectiveSet allowedSet{llvm::omp::Directive::OMPD_parallel, - llvm::omp::Directive::OMPD_parallel_do, - llvm::omp::Directive::OMPD_parallel_do_simd, - llvm::omp::Directive::OMPD_parallel_for, - llvm::omp::Directive::OMPD_parallel_for_simd, - llvm::omp::Directive::OMPD_parallel_master, - llvm::omp::Directive::OMPD_parallel_master_taskloop, - llvm::omp::Directive::OMPD_parallel_master_taskloop_simd, - llvm::omp::Directive::OMPD_parallel_sections, - llvm::omp::Directive::OMPD_parallel_workshare, - llvm::omp::Directive::OMPD_distribute, - llvm::omp::Directive::OMPD_distribute_parallel_do, - llvm::omp::Directive::OMPD_distribute_parallel_do_simd, - llvm::omp::Directive::OMPD_distribute_parallel_for, - llvm::omp::Directive::OMPD_distribute_parallel_for_simd, - llvm::omp::Directive::OMPD_distribute_simd}; - - if (!allowedSet.test(dir)) { + if (!llvm::omp::nestedTeamsAllowedSet.test(dir)) { context_.Say(source, "Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly " "nested inside `TEAMS` region."_err_en_US); @@ -421,7 +396,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) { } PushContextAndClauseSets(beginDir.source, beginDir.v); - if (llvm::omp::simdSet.test(GetContext().directive)) { + if (llvm::omp::allSimdSet.test(GetContext().directive)) { EnterDirectiveNest(SIMDNest); } @@ -451,7 +426,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) { CheckCycleConstraints(x); HasInvalidDistributeNesting(x); if (CurrentDirectiveIsNested() && - llvm::omp::teamSet.test(GetContextParent().directive)) { + llvm::omp::topTeamsSet.test(GetContextParent().directive)) { HasInvalidTeamsNesting(beginDir.v, beginDir.source); } if ((beginDir.v == llvm::omp::Directive::OMPD_distribute_parallel_do_simd) || @@ -750,7 +725,7 @@ void OmpStructureChecker::CheckDistLinear( } void OmpStructureChecker::Leave(const parser::OpenMPLoopConstruct &) { - if (llvm::omp::simdSet.test(GetContext().directive)) { + if (llvm::omp::allSimdSet.test(GetContext().directive)) { ExitDirectiveNest(SIMDNest); } dirContext_.pop_back(); @@ -787,7 +762,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) { } if (CurrentDirectiveIsNested()) { - if (llvm::omp::teamSet.test(GetContextParent().directive)) { + if (llvm::omp::topTeamsSet.test(GetContextParent().directive)) { HasInvalidTeamsNesting(beginDir.v, beginDir.source); } if (GetContext().directive == llvm::omp::Directive::OMPD_master) { @@ -871,10 +846,6 @@ void OmpStructureChecker::ChecksOnOrderedAsBlock() { return; } - OmpDirectiveSet notAllowedParallelSet{llvm::omp::Directive::OMPD_parallel, - llvm::omp::Directive::OMPD_target_parallel, - llvm::omp::Directive::OMPD_parallel_sections, - llvm::omp::Directive::OMPD_parallel_workshare}; bool isNestedInDo{false}; bool isNestedInDoSIMD{false}; bool isNestedInSIMD{false}; @@ -888,9 +859,10 @@ void OmpStructureChecker::ChecksOnOrderedAsBlock() { "`ORDERED` region may not be closely nested inside of `CRITICAL`, " "`ORDERED`, explicit `TASK` or `TASKLOOP` region."_err_en_US); break; - } else if (llvm::omp::doSet.test(dirContext_[i].directive)) { + } else if (llvm::omp::allDoSet.test(dirContext_[i].directive)) { isNestedInDo = true; - isNestedInDoSIMD = llvm::omp::doSimdSet.test(dirContext_[i].directive); + isNestedInDoSIMD = + llvm::omp::allDoSimdSet.test(dirContext_[i].directive); if (const auto *clause{ FindClause(dirContext_[i], llvm::omp::Clause::OMPC_ordered)}) { const auto &orderedClause{ @@ -901,10 +873,11 @@ void OmpStructureChecker::ChecksOnOrderedAsBlock() { noOrderedClause = true; } break; - } else if (llvm::omp::simdSet.test(dirContext_[i].directive)) { + } else if (llvm::omp::allSimdSet.test(dirContext_[i].directive)) { isNestedInSIMD = true; break; - } else if (notAllowedParallelSet.test(dirContext_[i].directive)) { + } else if (llvm::omp::nestedOrderedParallelErrSet.test( + dirContext_[i].directive)) { isCloselyNestedRegion = false; break; } @@ -1340,12 +1313,9 @@ void OmpStructureChecker::ChecksOnOrderedAsStandalone() { } } - OmpDirectiveSet allowedDoSet{llvm::omp::Directive::OMPD_do, - llvm::omp::Directive::OMPD_parallel_do, - llvm::omp::Directive::OMPD_target_parallel_do}; bool isNestedInDoOrderedWithPara{false}; if (CurrentDirectiveIsNested() && - allowedDoSet.test(GetContextParent().directive)) { + llvm::omp::nestedOrderedDoAllowedSet.test(GetContextParent().directive)) { if (const auto *clause{ FindClause(GetContextParent(), llvm::omp::Clause::OMPC_ordered)}) { const auto &orderedClause{ @@ -1503,24 +1473,11 @@ void OmpStructureChecker::CheckCancellationNest( // cancellation construct must be closely nested inside an OpenMP construct // that matches the type specified in construct-type-clause of the // cancellation construct. - - OmpDirectiveSet allowedTaskgroupSet{ - llvm::omp::Directive::OMPD_task, llvm::omp::Directive::OMPD_taskloop}; - OmpDirectiveSet allowedSectionsSet{llvm::omp::Directive::OMPD_sections, - llvm::omp::Directive::OMPD_parallel_sections}; - OmpDirectiveSet allowedDoSet{llvm::omp::Directive::OMPD_do, - llvm::omp::Directive::OMPD_distribute_parallel_do, - llvm::omp::Directive::OMPD_parallel_do, - llvm::omp::Directive::OMPD_target_parallel_do, - llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do, - llvm::omp::Directive::OMPD_teams_distribute_parallel_do}; - OmpDirectiveSet allowedParallelSet{llvm::omp::Directive::OMPD_parallel, - llvm::omp::Directive::OMPD_target_parallel}; - bool eligibleCancellation{false}; switch (type) { case parser::OmpCancelType::Type::Taskgroup: - if (allowedTaskgroupSet.test(GetContextParent().directive)) { + if (llvm::omp::nestedCancelTaskgroupAllowedSet.test( + GetContextParent().directive)) { eligibleCancellation = true; if (dirContext_.size() >= 3) { // Check if the cancellation region is closely nested inside a @@ -1533,7 +1490,8 @@ void OmpStructureChecker::CheckCancellationNest( llvm::omp::Directive::OMPD_taskgroup) { break; } - if (allowedParallelSet.test(dirContext_[i].directive)) { + if (llvm::omp::nestedCancelParallelAllowedSet.test( + dirContext_[i].directive)) { eligibleCancellation = false; break; } @@ -1552,17 +1510,20 @@ void OmpStructureChecker::CheckCancellationNest( } return; case parser::OmpCancelType::Type::Sections: - if (allowedSectionsSet.test(GetContextParent().directive)) { + if (llvm::omp::nestedCancelSectionsAllowedSet.test( + GetContextParent().directive)) { eligibleCancellation = true; } break; case Fortran::parser::OmpCancelType::Type::Do: - if (allowedDoSet.test(GetContextParent().directive)) { + if (llvm::omp::nestedCancelDoAllowedSet.test( + GetContextParent().directive)) { eligibleCancellation = true; } break; case parser::OmpCancelType::Type::Parallel: - if (allowedParallelSet.test(GetContextParent().directive)) { + if (llvm::omp::nestedCancelParallelAllowedSet.test( + GetContextParent().directive)) { eligibleCancellation = true; } break; @@ -1819,7 +1780,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPAtomicConstruct &) { void OmpStructureChecker::Leave(const parser::OmpClauseList &) { // 2.7.1 Loop Construct Restriction - if (llvm::omp::doSet.test(GetContext().directive)) { + if (llvm::omp::allDoSet.test(GetContext().directive)) { if (auto *clause{FindClause(llvm::omp::Clause::OMPC_schedule)}) { // only one schedule clause is allowed const auto &schedClause{std::get(clause->u)}; @@ -1870,7 +1831,7 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) { } // doSet // 2.8.1 Simd Construct Restriction - if (llvm::omp::simdSet.test(GetContext().directive)) { + if (llvm::omp::allSimdSet.test(GetContext().directive)) { if (auto *clause{FindClause(llvm::omp::Clause::OMPC_simdlen)}) { if (auto *clause2{FindClause(llvm::omp::Clause::OMPC_safelen)}) { const auto &simdlenClause{ @@ -2111,9 +2072,7 @@ void OmpStructureChecker::CheckReductionTypeList( CheckReductionArraySection(ompObjectList); // If this is a worksharing construct then ensure the reduction variable // is not private in the parallel region that it binds to. - OmpDirectiveSet workshareSet{llvm::omp::Directive::OMPD_do, - llvm::omp::Directive::OMPD_sections, llvm::omp::Directive::OMPD_do_simd}; - if (workshareSet.test(GetContext().directive)) { + if (llvm::omp::nestedReduceWorkshareAllowedSet.test(GetContext().directive)) { CheckSharedBindingInOuterContext(ompObjectList); } } @@ -2209,7 +2168,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) { if (const auto &expr{x.v}) { RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_ordered, *expr); // 2.8.3 Loop SIMD Construct Restriction - if (llvm::omp::doSimdSet.test(GetContext().directive)) { + if (llvm::omp::allDoSimdSet.test(GetContext().directive)) { context_.Say(GetContext().clauseSource, "No ORDERED clause with a parameter can be specified " "on the %s directive"_err_en_US, @@ -2250,10 +2209,6 @@ bool OmpStructureChecker::IsDataRefTypeParamInquiry( void OmpStructureChecker::CheckIsVarPartOfAnotherVar( const parser::CharBlock &source, const parser::OmpObjectList &objList) { - OmpDirectiveSet nonPartialVarSet{llvm::omp::Directive::OMPD_allocate, - llvm::omp::Directive::OMPD_allocators, - llvm::omp::Directive::OMPD_threadprivate, - llvm::omp::Directive::OMPD_declare_target}; for (const auto &ompObject : objList.v) { common::visit( common::visitors{ @@ -2268,7 +2223,8 @@ void OmpStructureChecker::CheckIsVarPartOfAnotherVar( } else if (parser::Unwrap( ompObject) || parser::Unwrap(ompObject)) { - if (nonPartialVarSet.test(GetContext().directive)) { + if (llvm::omp::nonPartialVarSet.test( + GetContext().directive)) { context_.Say(source, "A variable that is part of another variable (as an " "array or structure element) cannot appear on the %s " @@ -2397,22 +2353,10 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) { using dirNameModifier = parser::OmpIfClause::DirectiveNameModifier; // TODO Check that, when multiple 'if' clauses are applied to a combined // construct, at most one of them applies to each directive. - // Need to define set here because llvm::omp::teamSet does not include target - // teams combined constructs. - OmpDirectiveSet teamSet{llvm::omp::Directive::OMPD_target_teams, - llvm::omp::Directive::OMPD_target_teams_distribute, - llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do, - llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd, - llvm::omp::Directive::OMPD_target_teams_distribute_simd, - llvm::omp::Directive::OMPD_teams, - llvm::omp::Directive::OMPD_teams_distribute, - llvm::omp::Directive::OMPD_teams_distribute_parallel_do, - llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd, - llvm::omp::Directive::OMPD_teams_distribute_simd}; static std::unordered_map - dirNameModifierMap{{dirNameModifier::Parallel, llvm::omp::parallelSet}, - {dirNameModifier::Simd, llvm::omp::simdSet}, - {dirNameModifier::Target, llvm::omp::targetSet}, + dirNameModifierMap{{dirNameModifier::Parallel, llvm::omp::allParallelSet}, + {dirNameModifier::Simd, llvm::omp::allSimdSet}, + {dirNameModifier::Target, llvm::omp::allTargetSet}, {dirNameModifier::TargetData, {llvm::omp::Directive::OMPD_target_data}}, {dirNameModifier::TargetEnterData, @@ -2422,8 +2366,8 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) { {dirNameModifier::TargetUpdate, {llvm::omp::Directive::OMPD_target_update}}, {dirNameModifier::Task, {llvm::omp::Directive::OMPD_task}}, - {dirNameModifier::Taskloop, llvm::omp::taskloopSet}, - {dirNameModifier::Teams, teamSet}}; + {dirNameModifier::Taskloop, llvm::omp::allTaskloopSet}, + {dirNameModifier::Teams, llvm::omp::allTeamsSet}}; if (const auto &directiveName{ std::get>(x.v.t)}) { auto search{dirNameModifierMap.find(*directiveName)}; @@ -2444,7 +2388,8 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) { CheckAllowed(llvm::omp::Clause::OMPC_linear); // 2.7 Loop Construct Restriction - if ((llvm::omp::doSet | llvm::omp::simdSet).test(GetContext().directive)) { + if ((llvm::omp::allDoSet | llvm::omp::allSimdSet) + .test(GetContext().directive)) { if (std::holds_alternative(x.v.u)) { context_.Say(GetContext().clauseSource, "A modifier may not be specified in a LINEAR clause " @@ -2524,7 +2469,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) { const parser::OmpScheduleClause &scheduleClause = x.v; // 2.7 Loop Construct Restriction - if (llvm::omp::doSet.test(GetContext().directive)) { + if (llvm::omp::allDoSet.test(GetContext().directive)) { const auto &kind{std::get<1>(scheduleClause.t)}; const auto &chunk{std::get<2>(scheduleClause.t)}; if (chunk) { @@ -2941,13 +2886,6 @@ void OmpStructureChecker::CheckWorkshareBlockStmts( // Check if OpenMP constructs enclosed in the Workshare construct are // 'Parallel' constructs auto currentDir{llvm::omp::Directive::OMPD_unknown}; - const OmpDirectiveSet parallelDirSet{ - llvm::omp::Directive::OMPD_parallel, - llvm::omp::Directive::OMPD_parallel_do, - llvm::omp::Directive::OMPD_parallel_sections, - llvm::omp::Directive::OMPD_parallel_workshare, - llvm::omp::Directive::OMPD_parallel_do_simd}; - if (const auto *ompBlockConstruct{ std::get_if(&ompConstruct->u)}) { const auto &beginBlockDir{ @@ -2974,7 +2912,7 @@ void OmpStructureChecker::CheckWorkshareBlockStmts( currentDir = beginDir.v; } - if (!parallelDirSet.test(currentDir)) { + if (!llvm::omp::topParallelSet.test(currentDir)) { context_.Say(source, "OpenMP constructs enclosed in WORKSHARE construct may consist " "of ATOMIC, CRITICAL or PARALLEL constructs only"_err_en_US); diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index 60411a4624b76..d165834196aef 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -17,12 +17,10 @@ #include "check-directive-structure.h" #include "flang/Common/enum-set.h" #include "flang/Parser/parse-tree.h" +#include "flang/Semantics/openmp-directive-sets.h" #include "flang/Semantics/semantics.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" -using OmpDirectiveSet = Fortran::common::EnumSet; - using OmpClauseSet = Fortran::common::EnumSet; @@ -31,85 +29,6 @@ using OmpClauseSet = namespace llvm { namespace omp { -static OmpDirectiveSet parallelSet{Directive::OMPD_distribute_parallel_do, - Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_parallel, - Directive::OMPD_parallel_do, Directive::OMPD_parallel_do_simd, - Directive::OMPD_parallel_sections, Directive::OMPD_parallel_workshare, - Directive::OMPD_target_parallel, Directive::OMPD_target_parallel_do, - Directive::OMPD_target_parallel_do_simd, - Directive::OMPD_target_teams_distribute_parallel_do, - Directive::OMPD_target_teams_distribute_parallel_do_simd, - Directive::OMPD_teams_distribute_parallel_do, - Directive::OMPD_teams_distribute_parallel_do_simd}; -static OmpDirectiveSet doSet{Directive::OMPD_distribute_parallel_do, - Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_parallel_do, - Directive::OMPD_parallel_do_simd, Directive::OMPD_do, - Directive::OMPD_do_simd, Directive::OMPD_target_parallel_do, - Directive::OMPD_target_parallel_do_simd, - Directive::OMPD_target_teams_distribute_parallel_do, - Directive::OMPD_target_teams_distribute_parallel_do_simd, - Directive::OMPD_teams_distribute_parallel_do, - Directive::OMPD_teams_distribute_parallel_do_simd}; -static OmpDirectiveSet doSimdSet{Directive::OMPD_distribute_parallel_do_simd, - Directive::OMPD_parallel_do_simd, Directive::OMPD_do_simd, - Directive::OMPD_target_parallel_do_simd, - Directive::OMPD_target_teams_distribute_parallel_do_simd, - Directive::OMPD_teams_distribute_parallel_do_simd}; -static OmpDirectiveSet workShareSet{ - OmpDirectiveSet{Directive::OMPD_workshare, - Directive::OMPD_parallel_workshare, Directive::OMPD_parallel_sections, - Directive::OMPD_sections, Directive::OMPD_single} | - doSet}; -static OmpDirectiveSet taskloopSet{ - Directive::OMPD_taskloop, Directive::OMPD_taskloop_simd}; -static OmpDirectiveSet targetSet{Directive::OMPD_target, - Directive::OMPD_target_parallel, Directive::OMPD_target_parallel_do, - Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_simd, - Directive::OMPD_target_teams, Directive::OMPD_target_teams_distribute, - Directive::OMPD_target_teams_distribute_parallel_do, - Directive::OMPD_target_teams_distribute_parallel_do_simd, - Directive::OMPD_target_teams_distribute_simd}; -static OmpDirectiveSet simdSet{Directive::OMPD_distribute_parallel_do_simd, - Directive::OMPD_distribute_simd, Directive::OMPD_do_simd, - Directive::OMPD_parallel_do_simd, Directive::OMPD_simd, - Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_simd, - Directive::OMPD_target_teams_distribute_parallel_do_simd, - Directive::OMPD_target_teams_distribute_simd, Directive::OMPD_taskloop_simd, - Directive::OMPD_teams_distribute_parallel_do_simd, - Directive::OMPD_teams_distribute_simd}; -static OmpDirectiveSet teamSet{Directive::OMPD_teams, - Directive::OMPD_teams_distribute, - Directive::OMPD_teams_distribute_parallel_do, - Directive::OMPD_teams_distribute_parallel_do_simd, - Directive::OMPD_teams_distribute_simd}; -static OmpDirectiveSet distributeSet{Directive::OMPD_distribute, - Directive::OMPD_distribute_parallel_do, - Directive::OMPD_distribute_parallel_do_simd, - Directive::OMPD_distribute_simd, Directive::OMPD_target_teams_distribute, - Directive::OMPD_target_teams_distribute_parallel_do, - Directive::OMPD_target_teams_distribute_parallel_do_simd, - Directive::OMPD_target_teams_distribute_simd, - Directive::OMPD_teams_distribute, - Directive::OMPD_teams_distribute_parallel_do, - Directive::OMPD_teams_distribute_parallel_do_simd, - Directive::OMPD_teams_distribute_simd}; -static OmpDirectiveSet taskGeneratingSet{ - OmpDirectiveSet{Directive::OMPD_task} | taskloopSet}; -static OmpDirectiveSet nestedOrderedErrSet{Directive::OMPD_critical, - Directive::OMPD_ordered, Directive::OMPD_atomic, Directive::OMPD_task, - Directive::OMPD_taskloop}; -static OmpDirectiveSet nestedWorkshareErrSet{ - OmpDirectiveSet{Directive::OMPD_task, Directive::OMPD_taskloop, - Directive::OMPD_critical, Directive::OMPD_ordered, - Directive::OMPD_atomic, Directive::OMPD_master} | - workShareSet}; -static OmpDirectiveSet nestedMasterErrSet{ - OmpDirectiveSet{llvm::omp::Directive::OMPD_atomic} | taskGeneratingSet | - workShareSet}; -static OmpDirectiveSet nestedBarrierErrSet{ - OmpDirectiveSet{Directive::OMPD_critical, Directive::OMPD_ordered, - Directive::OMPD_atomic, Directive::OMPD_master} | - taskGeneratingSet | workShareSet}; static OmpClauseSet privateSet{ Clause::OMPC_private, Clause::OMPC_firstprivate, Clause::OMPC_lastprivate}; static OmpClauseSet privateReductionSet{ diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 9c5a8e4fec2ee..2ecdfca18c6b4 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -1370,7 +1370,7 @@ void OmpAttributeVisitor::ResolveSeqLoopIndexInParallelOrTaskConstruct( if (targetIt == dirContext_.rend()) { return; } - if (llvm::omp::parallelSet.test(targetIt->directive) || + if (llvm::omp::allParallelSet.test(targetIt->directive) || llvm::omp::taskGeneratingSet.test(targetIt->directive)) { break; } @@ -1471,7 +1471,7 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel( return; } Symbol::Flag ivDSA; - if (!llvm::omp::simdSet.test(GetContext().directive)) { + if (!llvm::omp::allSimdSet.test(GetContext().directive)) { ivDSA = Symbol::Flag::OmpPrivate; } else if (level == 1) { ivDSA = Symbol::Flag::OmpLinear; @@ -1866,7 +1866,7 @@ void OmpAttributeVisitor::ResolveOmpObject( "clauses on a TARGET DATA construct"_err_en_US, symbol->name()); } - if (llvm::omp::distributeSet.test(GetContext().directive) && + if (llvm::omp::allDistributeSet.test(GetContext().directive) && (((ompFlag == Symbol::Flag::OmpFirstPrivate) && symbol->test(Symbol::Flag::OmpLastPrivate)) || ((ompFlag == Symbol::Flag::OmpLastPrivate) &&