Skip to content

Commit bd54233

Browse files
authored
[Frontend][OpenMP] Move isPrivatizingConstruct from flang (#155477)
The check of whether a construct can privatize is a general utility, not dependent on language-specific definitions.
1 parent f3b542e commit bd54233

File tree

3 files changed

+41
-39
lines changed

3 files changed

+41
-39
lines changed

flang/lib/Lower/OpenMP/DataSharingProcessor.cpp

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "flang/Semantics/tools.h"
3131
#include "llvm/ADT/Sequence.h"
3232
#include "llvm/ADT/SmallSet.h"
33+
#include "llvm/Frontend/OpenMP/OMP.h"
3334
#include <variant>
3435

3536
namespace Fortran {
@@ -422,47 +423,10 @@ static parser::CharBlock getSource(const semantics::SemanticsContext &semaCtx,
422423
});
423424
}
424425

425-
static void collectPrivatizingConstructs(
426-
llvm::SmallSet<llvm::omp::Directive, 16> &constructs, unsigned version) {
427-
using Clause = llvm::omp::Clause;
428-
using Directive = llvm::omp::Directive;
429-
430-
static const Clause privatizingClauses[] = {
431-
Clause::OMPC_private,
432-
Clause::OMPC_lastprivate,
433-
Clause::OMPC_firstprivate,
434-
Clause::OMPC_in_reduction,
435-
Clause::OMPC_reduction,
436-
Clause::OMPC_linear,
437-
// TODO: Clause::OMPC_induction,
438-
Clause::OMPC_task_reduction,
439-
Clause::OMPC_detach,
440-
Clause::OMPC_use_device_ptr,
441-
Clause::OMPC_is_device_ptr,
442-
};
443-
444-
for (auto dir : llvm::enum_seq_inclusive<Directive>(Directive::First_,
445-
Directive::Last_)) {
446-
bool allowsPrivatizing = llvm::any_of(privatizingClauses, [&](Clause cls) {
447-
return llvm::omp::isAllowedClauseForDirective(dir, cls, version);
448-
});
449-
if (allowsPrivatizing)
450-
constructs.insert(dir);
451-
}
452-
}
453-
454426
bool DataSharingProcessor::isOpenMPPrivatizingConstruct(
455427
const parser::OpenMPConstruct &omp, unsigned version) {
456-
static llvm::SmallSet<llvm::omp::Directive, 16> privatizing;
457-
[[maybe_unused]] static bool init =
458-
(collectPrivatizingConstructs(privatizing, version), true);
459-
460-
// As of OpenMP 6.0, privatizing constructs (with the test being if they
461-
// allow a privatizing clause) are: dispatch, distribute, do, for, loop,
462-
// parallel, scope, sections, simd, single, target, target_data, task,
463-
// taskgroup, taskloop, and teams.
464-
return llvm::is_contained(privatizing,
465-
parser::omp::GetOmpDirectiveName(omp).v);
428+
return llvm::omp::isPrivatizingConstruct(
429+
parser::omp::GetOmpDirectiveName(omp).v, version);
466430
}
467431

468432
bool DataSharingProcessor::isOpenMPPrivatizingEvaluation(

llvm/include/llvm/Frontend/OpenMP/OMP.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ static constexpr inline bool isPrivatizingClause(Clause C) {
7171
static constexpr unsigned FallbackVersion = 52;
7272
LLVM_ABI ArrayRef<unsigned> getOpenMPVersions();
7373

74+
/// Can directive D, under some circumstances, create a private copy
75+
/// of a variable in given OpenMP version?
76+
bool isPrivatizingConstruct(Directive D, unsigned Version);
77+
7478
/// Create a nicer version of a function name for humans to look at.
7579
LLVM_ABI std::string prettifyFunctionName(StringRef FunctionName);
7680

llvm/lib/Frontend/OpenMP/OMP.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "llvm/Frontend/OpenMP/OMP.h"
1010

1111
#include "llvm/ADT/ArrayRef.h"
12+
#include "llvm/ADT/Sequence.h"
13+
#include "llvm/ADT/SmallSet.h"
1214
#include "llvm/ADT/SmallVector.h"
1315
#include "llvm/ADT/StringRef.h"
1416
#include "llvm/Demangle/Demangle.h"
@@ -75,6 +77,26 @@ getFirstCompositeRange(iterator_range<ArrayRef<Directive>::iterator> Leafs) {
7577
return llvm::make_range(Begin, End);
7678
}
7779

80+
static void
81+
collectPrivatizingConstructs(llvm::SmallSet<Directive, 16> &Constructs,
82+
unsigned Version) {
83+
llvm::SmallSet<Clause, 16> Privatizing;
84+
for (auto C :
85+
llvm::enum_seq_inclusive<Clause>(Clause::First_, Clause::Last_)) {
86+
if (isPrivatizingClause(C))
87+
Privatizing.insert(C);
88+
}
89+
90+
for (auto D : llvm::enum_seq_inclusive<Directive>(Directive::First_,
91+
Directive::Last_)) {
92+
bool AllowsPrivatizing = llvm::any_of(Privatizing, [&](Clause C) {
93+
return isAllowedClauseForDirective(D, C, Version);
94+
});
95+
if (AllowsPrivatizing)
96+
Constructs.insert(D);
97+
}
98+
}
99+
78100
namespace llvm::omp {
79101
ArrayRef<Directive> getLeafConstructs(Directive D) {
80102
auto Idx = static_cast<std::size_t>(D);
@@ -194,6 +216,18 @@ ArrayRef<unsigned> getOpenMPVersions() {
194216
return Versions;
195217
}
196218

219+
bool isPrivatizingConstruct(Directive D, unsigned Version) {
220+
static llvm::SmallSet<Directive, 16> Privatizing;
221+
[[maybe_unused]] static bool Init =
222+
(collectPrivatizingConstructs(Privatizing, Version), true);
223+
224+
// As of OpenMP 6.0, privatizing constructs (with the test being if they
225+
// allow a privatizing clause) are: dispatch, distribute, do, for, loop,
226+
// parallel, scope, sections, simd, single, target, target_data, task,
227+
// taskgroup, taskloop, and teams.
228+
return llvm::is_contained(Privatizing, D);
229+
}
230+
197231
std::string prettifyFunctionName(StringRef FunctionName) {
198232
// Internalized functions have the right name, but simply a suffix.
199233
if (FunctionName.ends_with(".internalized"))

0 commit comments

Comments
 (0)