-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
[flang][semantics][OpenMP] no privatisation of stmt functions #106550
Conversation
@llvm/pr-subscribers-flang-fir-hlfir @llvm/pr-subscribers-flang-semantics Author: Tom Eccles (tblah) ChangesOpenMP prohibits privatisation of variables that appear in expressions for statement functions. This is a re-working of an old patch https://reviews.llvm.org/D93213 by @praveen-g-ctt. The old patch couldn't be landed because of ordering concerns. Statement functions are rewritten during parse tree rewriting, but this was done after resolve-directives and so some array expressions were incorrectly identified as statement functions. For this reason I have opted to re-order the semantics driver so that resolve-directives is run after parse tree rewriting. Closes #64677 Full diff: https://github.com/llvm/llvm-project/pull/106550.diff 3 Files Affected:
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 4aecb8b8e7b479..8e21dead15bf9c 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -717,7 +717,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
void CheckDataCopyingClause(
const parser::Name &, const Symbol &, Symbol::Flag);
void CheckAssocLoopLevel(std::int64_t level, const parser::OmpClause *clause);
- void CheckObjectInNamelist(
+ void CheckPrivateDSAObject(
const parser::Name &, const Symbol &, Symbol::Flag);
void CheckSourceLabel(const parser::Label &);
void CheckLabelContext(const parser::CharBlock, const parser::CharBlock,
@@ -2349,7 +2349,7 @@ void OmpAttributeVisitor::ResolveOmpObject(
CheckMultipleAppearances(*name, *symbol, ompFlag);
}
if (privateDataSharingAttributeFlags.test(ompFlag)) {
- CheckObjectInNamelist(*name, *symbol, ompFlag);
+ CheckPrivateDSAObject(*name, *symbol, ompFlag);
}
if (ompFlag == Symbol::Flag::OmpAllocate) {
@@ -2706,7 +2706,7 @@ void OmpAttributeVisitor::CheckDataCopyingClause(
}
}
-void OmpAttributeVisitor::CheckObjectInNamelist(
+void OmpAttributeVisitor::CheckPrivateDSAObject(
const parser::Name &name, const Symbol &symbol, Symbol::Flag ompFlag) {
const auto &ultimateSymbol{symbol.GetUltimate()};
llvm::StringRef clauseName{"PRIVATE"};
@@ -2721,6 +2721,14 @@ void OmpAttributeVisitor::CheckObjectInNamelist(
"Variable '%s' in NAMELIST cannot be in a %s clause"_err_en_US,
name.ToString(), clauseName.str());
}
+
+ if (stmtFunctionExprSymbols_.find(ultimateSymbol) !=
+ stmtFunctionExprSymbols_.end()) {
+ context_.Say(name.source,
+ "Variable '%s' in STATEMENT FUNCTION expression cannot be in a "
+ "%s clause"_err_en_US,
+ name.ToString(), clauseName.str());
+ }
}
void OmpAttributeVisitor::CheckSourceLabel(const parser::Label &label) {
diff --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp
index f7a277d1b414f6..2f1b9c139396a8 100644
--- a/flang/lib/Semantics/semantics.cpp
+++ b/flang/lib/Semantics/semantics.cpp
@@ -641,8 +641,8 @@ bool Semantics::Perform() {
CanonicalizeAcc(context_.messages(), program_) &&
CanonicalizeOmp(context_.messages(), program_) &&
CanonicalizeCUDA(program_) &&
- CanonicalizeDirectives(context_.messages(), program_) &&
PerformStatementSemantics(context_, program_) &&
+ CanonicalizeDirectives(context_.messages(), program_) &&
ModFileWriter{context_}
.set_hermeticModuleFileOutput(hermeticModuleFileOutput_)
.WriteAll();
diff --git a/flang/test/Semantics/OpenMP/private03.f90 b/flang/test/Semantics/OpenMP/private03.f90
new file mode 100644
index 00000000000000..3ce9cf81bb73a5
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/private03.f90
@@ -0,0 +1,39 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! Variables that appear in expressions for statement function definitions
+! may not appear in private, firstprivate or lastprivate clauses.
+
+subroutine stmt_function(temp)
+
+ integer :: i, p, q, r
+ real :: c, f, s, v, t(10)
+ real, intent(in) :: temp
+
+ c(temp) = p * (temp - q) / r
+ f(temp) = q + (temp * r/p)
+ v(temp) = c(temp) + f(temp)/2 - s
+
+ p = 5
+ q = 32
+ r = 9
+
+ !ERROR: Variable 'p' in STATEMENT FUNCTION expression cannot be in a PRIVATE clause
+ !$omp parallel private(p)
+ s = c(temp)
+ !$omp end parallel
+
+ !ERROR: Variable 's' in STATEMENT FUNCTION expression cannot be in a FIRSTPRIVATE clause
+ !$omp parallel firstprivate(s)
+ s = s + f(temp)
+ !$omp end parallel
+
+ !ERROR: Variable 's' in STATEMENT FUNCTION expression cannot be in a LASTPRIVATE clause
+ !$omp parallel do lastprivate(s, t)
+ do i = 1, 10
+ t(i) = v(temp) + i - s
+ end do
+ !$omp end parallel do
+
+ print *, t
+
+end subroutine stmt_function
|
24c4455
to
fb8b074
Compare
if (stmtFunctionExprSymbols_.find(ultimateSymbol) != | ||
stmtFunctionExprSymbols_.end()) { | ||
context_.Say(name.source, | ||
"Variable '%s' in STATEMENT FUNCTION expression cannot be in a " |
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.
"statement function" isn't literal Fortran syntax, don't capitali[sz]e things that are not keywords.
And please don't break error message strings across multiple lines -- that makes it much more difficult to find them with grep.
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.
Thanks for taking a look. I have removed the capitalization of "statement function" here.
I left the error message string across multiple lines because the next word in the string is %s
anyway.
What about implicit privatisation, such as This means that #103390 would need to be reverted, even though |
Good point about gfortran and ifort behavior. I'll bring it up on the OpenMP call this week. |
An RFC to discuss whether to proceed with this: https://discourse.llvm.org/t/rfc-openmp-remove-support-for-privatisation-of-statement-function-variables/81138 |
OpenMP prohibits privatisation of variables that appear in expressions for statement functions. This is a re-working of an old patch https://reviews.llvm.org/D93213 by @praveen-g-ctt. The old patch couldn't be landed because of ordering concerns. Statement functions are rewritten during parse tree rewriting, but this was done after resolve-directives and so some array expressions were incorrectly identified as statement functions. For this reason **I have opted to re-order the semantics driver so that resolve-directives is run after parse tree rewriting**. Closes llvm#54677 Co-authored-by: Praveen <praveen@compilertree.com>
25f6a9f
to
d3aa6da
Compare
The conclusion of the RFC was that we should move forward with this. Ping for review |
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.
OmpAttributeVisitor::Post(const parser::Name &name)
and DataSharingProcessor::collectSymbols
also need to be changed, to avoid implicit privatisation of stmt functions.
But this can be done in a separate patch.
if (stmtFunctionExprSymbols_.find(ultimateSymbol) != | ||
stmtFunctionExprSymbols_.end()) { | ||
context_.Say(name.source, | ||
"Variable '%s' in statement function expression cannot be in a " | ||
"%s clause"_err_en_US, | ||
name.ToString(), clauseName.str()); | ||
} |
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.
It would be better to change the name of this member function, to something like CheckObjectIsPrivatizable
, now that it also checks for statement functions.
Thanks for reminding me. I lost track amongst all of the discussions. Quite a bit of context changed since your initial commit so a straightforward revert would have been challenging. Please let me know if I missed anything. |
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.
LGTM, thanks for undoing the implicit privatization of statement functions. I agree that it is better than a revert at this point.
nit: the OmpFromStmtFunction
flag should also be removed.
@@ -718,7 +718,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> { | |||
void CheckDataCopyingClause( | |||
const parser::Name &, const Symbol &, Symbol::Flag); | |||
void CheckAssocLoopLevel(std::int64_t level, const parser::OmpClause *clause); | |||
void CheckObjectInNamelistOrAssociate( | |||
void CheckObjectIsPrivatisable( |
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.
I've noticed that sometimes privatisable
(British English) is used and other times it's privatizable
.
It would be nice to standardize one of the two in the code.
I suggest the latter, because that's how it's written in the OpenMP standard, that uses words such as privatization
and privatized
.
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.
I agree we should use the American spelling.
…06550) OpenMP prohibits privatisation of variables that appear in expressions for statement functions. This is a re-working of an old patch https://reviews.llvm.org/D93213 by @praveen-g-ctt. The old patch couldn't be landed because of ordering concerns. Statement functions are rewritten during parse tree rewriting, but this was done after resolve-directives and so some array expressions were incorrectly identified as statement functions. For this reason **I have opted to re-order the semantics driver so that resolve-directives is run after parse tree rewriting**. Closes llvm#54677 --------- Co-authored-by: Praveen <praveen@compilertree.com>
OpenMP prohibits privatisation of variables that appear in expressions for statement functions.
This is a re-working of an old patch https://reviews.llvm.org/D93213 by @praveen-g-ctt.
The old patch couldn't be landed because of ordering concerns. Statement functions are rewritten during parse tree rewriting, but this was done after resolve-directives and so some array expressions were incorrectly identified as statement functions. For this reason I have opted to re-order the semantics driver so that resolve-directives is run after parse tree rewriting.
Closes #54677