[flang] [llvm] [Frontend][OpenMP] Move isPrivatizingConstruct from flang (PR #155477)
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 26 12:34:36 PDT 2025
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/155477
The check of whether a construct can privatize is a general utility, not dependent on language-specific definitions.
>From 800d99c1559c3375e5d3d7aae09e773e97d34289 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Tue, 26 Aug 2025 14:23:59 -0500
Subject: [PATCH] [Frontend][OpenMP] Move isPrivatizingConstruct from flang
The check of whether a construct can privatize is a general utility,
not dependent on language-specific definitions.
---
.../lib/Lower/OpenMP/DataSharingProcessor.cpp | 42 ++-----------------
llvm/include/llvm/Frontend/OpenMP/OMP.h | 4 ++
llvm/lib/Frontend/OpenMP/OMP.cpp | 34 +++++++++++++++
3 files changed, 41 insertions(+), 39 deletions(-)
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 <variant>
namespace Fortran {
@@ -422,47 +423,10 @@ static parser::CharBlock getSource(const semantics::SemanticsContext &semaCtx,
});
}
-static void collectPrivatizingConstructs(
- llvm::SmallSet<llvm::omp::Directive, 16> &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>(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<llvm::omp::Directive, 16> 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<unsigned> 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<ArrayRef<Directive>::iterator> Leafs) {
return llvm::make_range(Begin, End);
}
+static void
+collectPrivatizingConstructs(llvm::SmallSet<Directive, 16> &Constructs,
+ unsigned Version) {
+ llvm::SmallSet<Clause, 16> Privatizing;
+ for (auto C :
+ llvm::enum_seq_inclusive<Clause>(Clause::First_, Clause::Last_)) {
+ if (isPrivatizingClause(C))
+ Privatizing.insert(C);
+ }
+
+ for (auto D : llvm::enum_seq_inclusive<Directive>(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<Directive> getLeafConstructs(Directive D) {
auto Idx = static_cast<std::size_t>(D);
@@ -194,6 +216,18 @@ ArrayRef<unsigned> getOpenMPVersions() {
return Versions;
}
+bool isPrivatizingConstruct(Directive D, unsigned Version) {
+ static llvm::SmallSet<Directive, 16> 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"))
More information about the llvm-commits
mailing list