Skip to content

Commit 4ec4a8e

Browse files
kparzysztblah
andauthored
[Frontend][OpenMP] Privatizing clauses in construct decomposition (#92176)
Add remaining clauses with the "privatizing" property to construct decomposition, specifically to the part handling the `allocate` clause. --------- Co-authored-by: Tom Eccles <[email protected]>
1 parent 97a3044 commit 4ec4a8e

File tree

3 files changed

+139
-9
lines changed

3 files changed

+139
-9
lines changed

llvm/include/llvm/Frontend/OpenMP/ConstructCompositionT.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,13 +343,31 @@ template <typename C> void ConstructCompositionT<C>::mergeDSA() {
343343
}
344344
}
345345

346-
// Check reductions as well, clear "shared" if set.
346+
// Check other privatizing clauses as well, clear "shared" if set.
347+
for (auto &clause : clauseSets[llvm::omp::Clause::OMPC_in_reduction]) {
348+
using InReductionTy = tomp::clause::InReductionT<TypeTy, IdTy, ExprTy>;
349+
using ListTy = typename InReductionTy::List;
350+
for (auto &object : std::get<ListTy>(std::get<InReductionTy>(clause.u).t))
351+
getDsa(object).second &= ~DSA::Shared;
352+
}
353+
for (auto &clause : clauseSets[llvm::omp::Clause::OMPC_linear]) {
354+
using LinearTy = tomp::clause::LinearT<TypeTy, IdTy, ExprTy>;
355+
using ListTy = typename LinearTy::List;
356+
for (auto &object : std::get<ListTy>(std::get<LinearTy>(clause.u).t))
357+
getDsa(object).second &= ~DSA::Shared;
358+
}
347359
for (auto &clause : clauseSets[llvm::omp::Clause::OMPC_reduction]) {
348360
using ReductionTy = tomp::clause::ReductionT<TypeTy, IdTy, ExprTy>;
349361
using ListTy = typename ReductionTy::List;
350362
for (auto &object : std::get<ListTy>(std::get<ReductionTy>(clause.u).t))
351363
getDsa(object).second &= ~DSA::Shared;
352364
}
365+
for (auto &clause : clauseSets[llvm::omp::Clause::OMPC_task_reduction]) {
366+
using TaskReductionTy = tomp::clause::TaskReductionT<TypeTy, IdTy, ExprTy>;
367+
using ListTy = typename TaskReductionTy::List;
368+
for (auto &object : std::get<ListTy>(std::get<TaskReductionTy>(clause.u).t))
369+
getDsa(object).second &= ~DSA::Shared;
370+
}
353371

354372
tomp::ListT<ObjectTy> privateObj, sharedObj, firstpObj, lastpObj, lastpcObj;
355373
for (auto &[object, dsa] : objectDsa) {

llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,9 +793,14 @@ bool ConstructDecompositionT<C, H>::applyClause(
793793
// [5.2:340:33]
794794
auto canMakePrivateCopy = [](llvm::omp::Clause id) {
795795
switch (id) {
796+
// Clauses with "privatization" property:
796797
case llvm::omp::Clause::OMPC_firstprivate:
798+
case llvm::omp::Clause::OMPC_in_reduction:
797799
case llvm::omp::Clause::OMPC_lastprivate:
800+
case llvm::omp::Clause::OMPC_linear:
798801
case llvm::omp::Clause::OMPC_private:
802+
case llvm::omp::Clause::OMPC_reduction:
803+
case llvm::omp::Clause::OMPC_task_reduction:
799804
return true;
800805
default:
801806
return false;

llvm/unittests/Frontend/OpenMPDecompositionTest.cpp

Lines changed: 115 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,14 @@ std::string stringify(const omp::DirectiveWithClauses &DWC) {
288288

289289
// --- Tests ----------------------------------------------------------
290290

291+
namespace red {
292+
// Make it easier to construct reduction operators from built-in intrinsics.
293+
omp::clause::ReductionOperator
294+
makeOp(omp::clause::DefinedOperator::IntrinsicOperator Op) {
295+
return omp::clause::ReductionOperator{omp::clause::DefinedOperator{Op}};
296+
}
297+
} // namespace red
298+
291299
namespace {
292300
using namespace llvm::omp;
293301

@@ -699,6 +707,92 @@ TEST_F(OpenMPDecompositionTest, Order1) {
699707
TEST_F(OpenMPDecompositionTest, Allocate1) {
700708
omp::Object x{"x"};
701709

710+
// Allocate + firstprivate
711+
omp::List<omp::Clause> Clauses{
712+
{OMPC_allocate,
713+
omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
714+
{OMPC_firstprivate, omp::clause::Firstprivate{{x}}},
715+
};
716+
717+
omp::ConstructDecomposition Dec(AnyVersion, Helper, OMPD_parallel_sections,
718+
Clauses);
719+
ASSERT_EQ(Dec.output.size(), 2u);
720+
721+
std::string Dir0 = stringify(Dec.output[0]);
722+
std::string Dir1 = stringify(Dec.output[1]);
723+
ASSERT_EQ(Dir0, "parallel shared(x)"); // (33)
724+
ASSERT_EQ(Dir1, "sections firstprivate(x) allocate(, , , (x))"); // (33)
725+
}
726+
727+
TEST_F(OpenMPDecompositionTest, Allocate2) {
728+
omp::Object x{"x"};
729+
auto Add = red::makeOp(omp::clause::DefinedOperator::IntrinsicOperator::Add);
730+
731+
// Allocate + in_reduction
732+
omp::List<omp::Clause> Clauses{
733+
{OMPC_allocate,
734+
omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
735+
{OMPC_in_reduction, omp::clause::InReduction{{{Add}, {x}}}},
736+
};
737+
738+
omp::ConstructDecomposition Dec(AnyVersion, Helper, OMPD_target_parallel,
739+
Clauses);
740+
ASSERT_EQ(Dec.output.size(), 2u);
741+
742+
std::string Dir0 = stringify(Dec.output[0]);
743+
std::string Dir1 = stringify(Dec.output[1]);
744+
ASSERT_EQ(Dir0, "target in_reduction((3), (x)) allocate(, , , (x))"); // (33)
745+
ASSERT_EQ(Dir1, "parallel"); // (33)
746+
}
747+
748+
TEST_F(OpenMPDecompositionTest, Allocate3) {
749+
omp::Object x{"x"};
750+
751+
// Allocate + linear
752+
omp::List<omp::Clause> Clauses{
753+
{OMPC_allocate,
754+
omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
755+
{OMPC_linear,
756+
omp::clause::Linear{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
757+
};
758+
759+
omp::ConstructDecomposition Dec(AnyVersion, Helper, OMPD_parallel_for,
760+
Clauses);
761+
ASSERT_EQ(Dec.output.size(), 2u);
762+
763+
std::string Dir0 = stringify(Dec.output[0]);
764+
std::string Dir1 = stringify(Dec.output[1]);
765+
// The "shared" clause is duplicated---this isn't harmful, but it
766+
// should be fixed eventually.
767+
ASSERT_EQ(Dir0, "parallel shared(x) shared(x)"); // (33)
768+
ASSERT_EQ(Dir1, "for linear(, , , (x)) firstprivate(x) lastprivate(, (x)) "
769+
"allocate(, , , (x))"); // (33)
770+
}
771+
772+
TEST_F(OpenMPDecompositionTest, Allocate4) {
773+
omp::Object x{"x"};
774+
775+
// Allocate + lastprivate
776+
omp::List<omp::Clause> Clauses{
777+
{OMPC_allocate,
778+
omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
779+
{OMPC_lastprivate, omp::clause::Lastprivate{{std::nullopt, {x}}}},
780+
};
781+
782+
omp::ConstructDecomposition Dec(AnyVersion, Helper, OMPD_parallel_sections,
783+
Clauses);
784+
ASSERT_EQ(Dec.output.size(), 2u);
785+
786+
std::string Dir0 = stringify(Dec.output[0]);
787+
std::string Dir1 = stringify(Dec.output[1]);
788+
ASSERT_EQ(Dir0, "parallel shared(x)"); // (33)
789+
ASSERT_EQ(Dir1, "sections lastprivate(, (x)) allocate(, , , (x))"); // (33)
790+
}
791+
792+
TEST_F(OpenMPDecompositionTest, Allocate5) {
793+
omp::Object x{"x"};
794+
795+
// Allocate + private
702796
omp::List<omp::Clause> Clauses{
703797
{OMPC_allocate,
704798
omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
@@ -715,6 +809,27 @@ TEST_F(OpenMPDecompositionTest, Allocate1) {
715809
ASSERT_EQ(Dir1, "sections private(x) allocate(, , , (x))"); // (33)
716810
}
717811

812+
TEST_F(OpenMPDecompositionTest, Allocate6) {
813+
omp::Object x{"x"};
814+
auto Add = red::makeOp(omp::clause::DefinedOperator::IntrinsicOperator::Add);
815+
816+
// Allocate + reduction
817+
omp::List<omp::Clause> Clauses{
818+
{OMPC_allocate,
819+
omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
820+
{OMPC_reduction, omp::clause::Reduction{{std::nullopt, {Add}, {x}}}},
821+
};
822+
823+
omp::ConstructDecomposition Dec(AnyVersion, Helper, OMPD_parallel_sections,
824+
Clauses);
825+
ASSERT_EQ(Dec.output.size(), 2u);
826+
827+
std::string Dir0 = stringify(Dec.output[0]);
828+
std::string Dir1 = stringify(Dec.output[1]);
829+
ASSERT_EQ(Dir0, "parallel shared(x)"); // (33)
830+
ASSERT_EQ(Dir1, "sections reduction(, (3), (x)) allocate(, , , (x))"); // (33)
831+
}
832+
718833
// REDUCTION
719834
// [5.2:134:17-18]
720835
// Directives: do, for, loop, parallel, scope, sections, simd, taskloop, teams
@@ -741,14 +856,6 @@ TEST_F(OpenMPDecompositionTest, Allocate1) {
741856
// clause on the construct, then the effect is as if the list item in the
742857
// reduction clause appears as a list item in a map clause with a map-type of
743858
// tofrom.
744-
namespace red {
745-
// Make is easier to construct reduction operators from built-in intrinsics.
746-
omp::clause::ReductionOperator
747-
makeOp(omp::clause::DefinedOperator::IntrinsicOperator Op) {
748-
return omp::clause::ReductionOperator{omp::clause::DefinedOperator{Op}};
749-
}
750-
} // namespace red
751-
752859
TEST_F(OpenMPDecompositionTest, Reduction1) {
753860
omp::Object x{"x"};
754861
auto Add = red::makeOp(omp::clause::DefinedOperator::IntrinsicOperator::Add);

0 commit comments

Comments
 (0)