-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Flang][OpenMP]Make Do concurrent indices private #93785
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-flang-semantics @llvm/pr-subscribers-flang-openmp Author: None (harishch4) ChangesFixes: #85538 Full diff: https://github.com/llvm/llvm-project/pull/93785.diff 2 Files Affected:
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index dbc531372c3f4..3992d527c7ae5 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1698,10 +1698,10 @@ void OmpAttributeVisitor::ResolveSeqLoopIndexInParallelOrTaskConstruct(
// Use of DO CONCURRENT inside OpenMP construct is unspecified behavior
// till OpenMP-5.0 standard.
// In above both cases we skip the privatization of iteration variables.
+// [OpenMP 5.1] DO CONCURRENT indices are private
bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) {
- // TODO:[OpenMP 5.1] DO CONCURRENT indices are private
- if (x.IsDoNormal()) {
- if (!dirContext_.empty() && GetContext().withinConstruct) {
+ if (!dirContext_.empty() && GetContext().withinConstruct) {
+ if (x.IsDoNormal()) {
const parser::Name *iv{GetLoopIndex(x)};
if (iv && iv->symbol) {
if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) {
@@ -1721,6 +1721,25 @@ bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) {
}
}
}
+ } else if (x.IsDoConcurrent()) {
+ const Fortran::parser::LoopControl *loopControl = &*x.GetLoopControl();
+ const Fortran::parser::LoopControl::Concurrent &concurrent =
+ std::get<Fortran::parser::LoopControl::Concurrent>(loopControl->u);
+ const Fortran::parser::ConcurrentHeader &concurrentHeader =
+ std::get<Fortran::parser::ConcurrentHeader>(concurrent.t);
+ const std::list<Fortran::parser::ConcurrentControl> &controls =
+ std::get<std::list<Fortran::parser::ConcurrentControl>>(
+ concurrentHeader.t);
+ for (const auto &control : controls) {
+ const parser::Name *iv{&std::get<0>(control.t)};
+ if (iv && iv->symbol) {
+ if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) {
+ ResolveSeqLoopIndexInParallelOrTaskConstruct(*iv);
+ } else {
+ // TODO: conflict checks with explicitly determined DSA
+ }
+ }
+ }
}
}
return true;
diff --git a/flang/test/Semantics/OpenMP/doconcurrent01.f90 b/flang/test/Semantics/OpenMP/doconcurrent01.f90
new file mode 100644
index 0000000000000..7e3bdce871dd4
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/doconcurrent01.f90
@@ -0,0 +1,17 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! OpenMP 5.1.1
+! DO Concurrent indices are private
+
+!DEF: /private_iv (Subroutine)Subprogram
+subroutine private_iv
+ !DEF: /private_iv/i ObjectEntity INTEGER(4)
+ integer i
+ !$omp parallel default(private)
+ !$omp single
+ !DEF: /private_iv/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do concurrent(i=1:2)
+ end do
+ !$omp end single
+ !$omp end parallel
+end subroutine
|
} else if (x.IsDoConcurrent()) { | ||
const Fortran::parser::LoopControl *loopControl = &*x.GetLoopControl(); | ||
const Fortran::parser::LoopControl::Concurrent &concurrent = | ||
std::get<Fortran::parser::LoopControl::Concurrent>(loopControl->u); | ||
const Fortran::parser::ConcurrentHeader &concurrentHeader = | ||
std::get<Fortran::parser::ConcurrentHeader>(concurrent.t); | ||
const std::list<Fortran::parser::ConcurrentControl> &controls = | ||
std::get<std::list<Fortran::parser::ConcurrentControl>>( | ||
concurrentHeader.t); | ||
for (const auto &control : controls) { | ||
const parser::Name *iv{&std::get<0>(control.t)}; | ||
if (iv && iv->symbol) { | ||
if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) { | ||
ResolveSeqLoopIndexInParallelOrTaskConstruct(*iv); | ||
} else { | ||
// TODO: conflict checks with explicitly determined DSA | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the threadprivate check not applicable here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loop iteration variable may not appear in a threadprivatedirective. Yeah, sorry I missed it. If it's okay, I'll store symbols in a list and move common code out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Due to a new symbol being declared here, the check won't work for DoConcurrent. I'll create an issue to try to handle it in a separate patch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG.
Fixes: #85538