diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp index 9d1c730b38edd..c4054ef0fc961 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp @@ -30,6 +30,7 @@ #include "flang/Semantics/tools.h" #include "llvm/ADT/Sequence.h" #include "llvm/ADT/SmallSet.h" +#include "llvm/Frontend/OpenMP/OMP.h" #include namespace Fortran { @@ -422,47 +423,10 @@ static parser::CharBlock getSource(const semantics::SemanticsContext &semaCtx, }); } -static void collectPrivatizingConstructs( - llvm::SmallSet &constructs, unsigned version) { - using Clause = llvm::omp::Clause; - using Directive = llvm::omp::Directive; - - static const Clause privatizingClauses[] = { - Clause::OMPC_private, - Clause::OMPC_lastprivate, - Clause::OMPC_firstprivate, - Clause::OMPC_in_reduction, - Clause::OMPC_reduction, - Clause::OMPC_linear, - // TODO: Clause::OMPC_induction, - Clause::OMPC_task_reduction, - Clause::OMPC_detach, - Clause::OMPC_use_device_ptr, - Clause::OMPC_is_device_ptr, - }; - - for (auto dir : llvm::enum_seq_inclusive(Directive::First_, - Directive::Last_)) { - bool allowsPrivatizing = llvm::any_of(privatizingClauses, [&](Clause cls) { - return llvm::omp::isAllowedClauseForDirective(dir, cls, version); - }); - if (allowsPrivatizing) - constructs.insert(dir); - } -} - bool DataSharingProcessor::isOpenMPPrivatizingConstruct( const parser::OpenMPConstruct &omp, unsigned version) { - static llvm::SmallSet privatizing; - [[maybe_unused]] static bool init = - (collectPrivatizingConstructs(privatizing, version), true); - - // As of OpenMP 6.0, privatizing constructs (with the test being if they - // allow a privatizing clause) are: dispatch, distribute, do, for, loop, - // parallel, scope, sections, simd, single, target, target_data, task, - // taskgroup, taskloop, and teams. - return llvm::is_contained(privatizing, - parser::omp::GetOmpDirectiveName(omp).v); + return llvm::omp::isPrivatizingConstruct( + parser::omp::GetOmpDirectiveName(omp).v, version); } bool DataSharingProcessor::isOpenMPPrivatizingEvaluation( diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.h b/llvm/include/llvm/Frontend/OpenMP/OMP.h index 9d0a55432e1ae..d5d08aed76e12 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.h @@ -71,6 +71,10 @@ static constexpr inline bool isPrivatizingClause(Clause C) { static constexpr unsigned FallbackVersion = 52; LLVM_ABI ArrayRef getOpenMPVersions(); +/// Can directive D, under some circumstances, create a private copy +/// of a variable in given OpenMP version? +bool isPrivatizingConstruct(Directive D, unsigned Version); + /// Create a nicer version of a function name for humans to look at. LLVM_ABI std::string prettifyFunctionName(StringRef FunctionName); diff --git a/llvm/lib/Frontend/OpenMP/OMP.cpp b/llvm/lib/Frontend/OpenMP/OMP.cpp index 9e625b809de9e..f12941492547e 100644 --- a/llvm/lib/Frontend/OpenMP/OMP.cpp +++ b/llvm/lib/Frontend/OpenMP/OMP.cpp @@ -9,6 +9,8 @@ #include "llvm/Frontend/OpenMP/OMP.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Sequence.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Demangle/Demangle.h" @@ -75,6 +77,26 @@ getFirstCompositeRange(iterator_range::iterator> Leafs) { return llvm::make_range(Begin, End); } +static void +collectPrivatizingConstructs(llvm::SmallSet &Constructs, + unsigned Version) { + llvm::SmallSet Privatizing; + for (auto C : + llvm::enum_seq_inclusive(Clause::First_, Clause::Last_)) { + if (isPrivatizingClause(C)) + Privatizing.insert(C); + } + + for (auto D : llvm::enum_seq_inclusive(Directive::First_, + Directive::Last_)) { + bool AllowsPrivatizing = llvm::any_of(Privatizing, [&](Clause C) { + return isAllowedClauseForDirective(D, C, Version); + }); + if (AllowsPrivatizing) + Constructs.insert(D); + } +} + namespace llvm::omp { ArrayRef getLeafConstructs(Directive D) { auto Idx = static_cast(D); @@ -194,6 +216,18 @@ ArrayRef getOpenMPVersions() { return Versions; } +bool isPrivatizingConstruct(Directive D, unsigned Version) { + static llvm::SmallSet Privatizing; + [[maybe_unused]] static bool Init = + (collectPrivatizingConstructs(Privatizing, Version), true); + + // As of OpenMP 6.0, privatizing constructs (with the test being if they + // allow a privatizing clause) are: dispatch, distribute, do, for, loop, + // parallel, scope, sections, simd, single, target, target_data, task, + // taskgroup, taskloop, and teams. + return llvm::is_contained(Privatizing, D); +} + std::string prettifyFunctionName(StringRef FunctionName) { // Internalized functions have the right name, but simply a suffix. if (FunctionName.ends_with(".internalized"))