[flang-commits] [flang] a4a4c50 - [Flang][OpenMP] Add semantic checks for OpenMP copyin clause.
Praveen G via flang-commits
flang-commits at lists.llvm.org
Wed Nov 4 00:21:13 PST 2020
Author: Praveen G
Date: 2020-11-04T03:12:35-05:00
New Revision: a4a4c503708f8bbf539147187faf180a80b4eea9
URL: https://github.com/llvm/llvm-project/commit/a4a4c503708f8bbf539147187faf180a80b4eea9
DIFF: https://github.com/llvm/llvm-project/commit/a4a4c503708f8bbf539147187faf180a80b4eea9.diff
LOG: [Flang][OpenMP] Add semantic checks for OpenMP copyin clause.
Add the semantic checks for the OpenMP 4.5 - 2.15.4.1 copyin clause.
Resolve OpenMPThreadprivate directive since the list of items specified
in copyin clause should be threadprivate.
Test cases : omp-copyin01.f90, omp-copyin02.f90, omp-copyin03.f90,
omp-copyin04.f90, omp-copyin05.f90
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D89385
Added:
flang/test/Semantics/omp-copyin01.f90
flang/test/Semantics/omp-copyin02.f90
flang/test/Semantics/omp-copyin03.f90
flang/test/Semantics/omp-copyin04.f90
flang/test/Semantics/omp-copyin05.f90
Modified:
flang/include/flang/Semantics/symbol.h
flang/lib/Semantics/resolve-directives.cpp
flang/test/Semantics/omp-combined-constructs.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 5ac32ac59b16..eab88d2f4dac 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -503,6 +503,8 @@ class Symbol {
OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
// OpenMP data-mapping attribute
OmpMapTo, OmpMapFrom, OmpMapAlloc, OmpMapRelease, OmpMapDelete,
+ // OpenMP data-copying attribute
+ OmpCopyIn,
// OpenMP miscellaneous flags
OmpCommonBlock, OmpReduction, OmpAllocate, OmpDeclareSimd,
OmpDeclareTarget, OmpThreadprivate, OmpDeclareReduction, OmpFlushed,
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index f68bcd1e1fa8..130eb8e1c422 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -223,7 +223,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
bool Pre(const parser::SpecificationPart &x) {
Walk(std::get<std::list<parser::OpenMPDeclarativeConstruct>>(x.t));
- return false;
+ return true;
}
bool Pre(const parser::OpenMPBlockConstruct &);
@@ -269,6 +269,10 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
ResolveOmpObjectList(x.v, Symbol::Flag::OmpLastPrivate);
return false;
}
+ bool Pre(const parser::OmpClause::Copyin &x) {
+ ResolveOmpObjectList(x.v, Symbol::Flag::OmpCopyIn);
+ return false;
+ }
void Post(const parser::Name &);
@@ -292,6 +296,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
static constexpr Symbol::Flags ompFlagsRequireMark{
Symbol::Flag::OmpThreadprivate};
+ static constexpr Symbol::Flags dataCopyingAttributeFlags{
+ Symbol::Flag::OmpCopyIn};
+
std::vector<const parser::Name *> allocateNames_; // on one directive
SymbolSet privateDataSharingAttributeObjects_; // on one directive
@@ -320,6 +327,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
Symbol *DeclareOrMarkOtherAccessEntity(Symbol &, Symbol::Flag);
void CheckMultipleAppearances(
const parser::Name &, const Symbol &, Symbol::Flag);
+
+ void CheckDataCopyingClause(
+ const parser::Name &, const Symbol &, Symbol::Flag);
};
template <typename T>
@@ -869,7 +879,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPThreadprivate &x) {
PushContext(x.source, llvm::omp::Directive::OMPD_threadprivate);
const auto &list{std::get<parser::OmpObjectList>(x.t)};
ResolveOmpObjectList(list, Symbol::Flag::OmpThreadprivate);
- return false;
+ return true;
}
void OmpAttributeVisitor::Post(const parser::OmpDefaultClause &x) {
@@ -922,9 +932,14 @@ Symbol *OmpAttributeVisitor::ResolveOmpCommonBlockName(
: nullptr}) {
name->symbol = prev;
return prev;
- } else {
- return nullptr;
}
+ // Check if the Common Block is declared in the current scope
+ if (auto *commonBlockSymbol{
+ name ? GetContext().scope.FindCommonBlock(name->source) : nullptr}) {
+ name->symbol = commonBlockSymbol;
+ return commonBlockSymbol;
+ }
+ return nullptr;
}
void OmpAttributeVisitor::ResolveOmpObjectList(
@@ -941,12 +956,16 @@ void OmpAttributeVisitor::ResolveOmpObject(
[&](const parser::Designator &designator) {
if (const auto *name{GetDesignatorNameIfDataRef(designator)}) {
if (auto *symbol{ResolveOmp(*name, ompFlag, currScope())}) {
- AddToContextObjectWithDSA(*symbol, ompFlag);
- if (dataSharingAttributeFlags.test(ompFlag)) {
- CheckMultipleAppearances(*name, *symbol, ompFlag);
- }
- if (ompFlag == Symbol::Flag::OmpAllocate) {
- AddAllocateName(name);
+ if (dataCopyingAttributeFlags.test(ompFlag)) {
+ CheckDataCopyingClause(*name, *symbol, ompFlag);
+ } else {
+ AddToContextObjectWithDSA(*symbol, ompFlag);
+ if (dataSharingAttributeFlags.test(ompFlag)) {
+ CheckMultipleAppearances(*name, *symbol, ompFlag);
+ }
+ if (ompFlag == Symbol::Flag::OmpAllocate) {
+ AddAllocateName(name);
+ }
}
}
} else {
@@ -963,15 +982,21 @@ void OmpAttributeVisitor::ResolveOmpObject(
},
[&](const parser::Name &name) { // common block
if (auto *symbol{ResolveOmpCommonBlockName(&name)}) {
- CheckMultipleAppearances(
- name, *symbol, Symbol::Flag::OmpCommonBlock);
+ if (!dataCopyingAttributeFlags.test(ompFlag)) {
+ CheckMultipleAppearances(
+ name, *symbol, Symbol::Flag::OmpCommonBlock);
+ }
// 2.15.3 When a named common block appears in a list, it has the
// same meaning as if every explicit member of the common block
// appeared in the list
for (auto &object : symbol->get<CommonBlockDetails>().objects()) {
if (auto *resolvedObject{
ResolveOmp(*object, ompFlag, currScope())}) {
- AddToContextObjectWithDSA(*resolvedObject, ompFlag);
+ if (dataCopyingAttributeFlags.test(ompFlag)) {
+ CheckDataCopyingClause(name, *resolvedObject, ompFlag);
+ } else {
+ AddToContextObjectWithDSA(*resolvedObject, ompFlag);
+ }
}
}
} else {
@@ -1073,4 +1098,20 @@ void ResolveOmpParts(
}
}
+void OmpAttributeVisitor::CheckDataCopyingClause(
+ const parser::Name &name, const Symbol &symbol, Symbol::Flag ompFlag) {
+ const auto *checkSymbol{&symbol};
+ if (ompFlag == Symbol::Flag::OmpCopyIn) {
+ if (const auto *details{symbol.detailsIf<HostAssocDetails>()})
+ checkSymbol = &details->symbol();
+
+ // List of items/objects that can appear in a 'copyin' clause must be
+ // 'threadprivate'
+ if (!checkSymbol->test(Symbol::Flag::OmpThreadprivate))
+ context_.Say(name.source,
+ "Non-THREADPRIVATE object '%s' in COPYIN clause"_err_en_US,
+ checkSymbol->name());
+ }
+}
+
} // namespace Fortran::semantics
diff --git a/flang/test/Semantics/omp-combined-constructs.f90 b/flang/test/Semantics/omp-combined-constructs.f90
index 3a1956ef10db..78821cf0e06c 100644
--- a/flang/test/Semantics/omp-combined-constructs.f90
+++ b/flang/test/Semantics/omp-combined-constructs.f90
@@ -53,6 +53,7 @@ program main
!$omp end target parallel
!ERROR: COPYIN clause is not allowed on the TARGET PARALLEL directive
+ !ERROR: Non-THREADPRIVATE object 'a' in COPYIN clause
!$omp target parallel copyin(a)
do i = 1, N
a(i) = 3.14
@@ -98,6 +99,7 @@ program main
enddo
!$omp end target parallel do
+ !ERROR: Non-THREADPRIVATE object 'a' in COPYIN clause
!$omp target parallel do copyin(a)
do i = 1, N
a(i) = 3.14
diff --git a/flang/test/Semantics/omp-copyin01.f90 b/flang/test/Semantics/omp-copyin01.f90
new file mode 100644
index 000000000000..5cae90a8624c
--- /dev/null
+++ b/flang/test/Semantics/omp-copyin01.f90
@@ -0,0 +1,34 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.1 copyin Clause
+! A list item that appears in a copyin clause must be threadprivate
+
+program omp_copyin
+
+ integer :: i
+ integer, save :: k
+ integer :: a(10), b(10)
+ common /cmn/ j
+
+ k = 10
+
+ !ERROR: Non-THREADPRIVATE object 'k' in COPYIN clause
+ !$omp parallel do copyin(k)
+ do i = 1, 10
+ a(i) = k + i
+ j = j + a(i)
+ end do
+ !$omp end parallel do
+
+ print *, a
+
+ !ERROR: Non-THREADPRIVATE object 'j' in COPYIN clause
+ !$omp parallel do copyin(/cmn/)
+ do i = 1, 10
+ b(i) = a(i) + j
+ end do
+ !$omp end parallel do
+
+ print *, b
+
+end program omp_copyin
diff --git a/flang/test/Semantics/omp-copyin02.f90 b/flang/test/Semantics/omp-copyin02.f90
new file mode 100644
index 000000000000..80ce47f79b46
--- /dev/null
+++ b/flang/test/Semantics/omp-copyin02.f90
@@ -0,0 +1,23 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.1 copyin Clause
+! A common block name that appears in a copyin clause must be declared to be
+! a common block in the same scoping unit in which the copyin clause appears.
+
+subroutine copyin()
+ integer :: a = 10
+ common /cmn/ a
+
+ !$omp threadprivate(/cmn/)
+ call copyin_clause()
+
+ contains
+
+ subroutine copyin_clause()
+ !ERROR: COMMON block must be declared in the same scoping unit in which the OpenMP directive or clause appears
+ !$omp parallel copyin(/cmn/)
+ print *, a
+ !$omp end parallel
+ end subroutine copyin_clause
+
+end subroutine copyin
diff --git a/flang/test/Semantics/omp-copyin03.f90 b/flang/test/Semantics/omp-copyin03.f90
new file mode 100644
index 000000000000..64b26c52ea0a
--- /dev/null
+++ b/flang/test/Semantics/omp-copyin03.f90
@@ -0,0 +1,33 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.1 copyin Clause
+! A list item that appears in a copyin clause must be threadprivate.
+! Named variables appearing in a threadprivate common block may be specified
+! It is not necessary to specify the whole common block.
+
+program omp_copyin
+
+ integer :: a(10), b(10)
+ common /cmn/ j, k
+
+ !$omp threadprivate(/cmn/)
+
+ j = 20
+ k = 10
+
+ !$omp parallel copyin(/cmn/)
+ a(:5) = k
+ b(:5) = j
+ !$omp end parallel
+
+ j = j + k
+ k = k * j
+
+ !$omp parallel copyin(j, k)
+ a(6:) = j
+ b(6:) = k
+ !$omp end parallel
+
+ print *, a, b
+
+end program omp_copyin
diff --git a/flang/test/Semantics/omp-copyin04.f90 b/flang/test/Semantics/omp-copyin04.f90
new file mode 100644
index 000000000000..7c8017300fc4
--- /dev/null
+++ b/flang/test/Semantics/omp-copyin04.f90
@@ -0,0 +1,26 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.1 copyin Clause
+! A list item that appears in a copyin clause must be threadprivate
+
+program omp_copyin
+
+ integer :: i
+ integer, save :: j, k
+ integer :: a(10), b(10)
+
+ !$omp threadprivate(j, k)
+
+ j = 20
+ k = 10
+
+ !$omp parallel do copyin(j, k)
+ do i = 1, 10
+ a(i) = k + i
+ b(i) = j + i
+ end do
+ !$omp end parallel do
+
+ print *, a, b
+
+end program omp_copyin
diff --git a/flang/test/Semantics/omp-copyin05.f90 b/flang/test/Semantics/omp-copyin05.f90
new file mode 100644
index 000000000000..37269fe4eae8
--- /dev/null
+++ b/flang/test/Semantics/omp-copyin05.f90
@@ -0,0 +1,23 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.1 copyin Clause
+! A common block name that appears in a copyin clause must be declared to be
+! a common block in the same scoping unit in which the copyin clause appears.
+
+subroutine copyin()
+ call copyin_clause()
+
+ contains
+
+ subroutine copyin_clause()
+ integer :: a = 20
+ common /cmn/ a
+
+ !$omp threadprivate(/cmn/)
+
+ !$omp parallel copyin(/cmn/)
+ print *, a
+ !$omp end parallel
+ end subroutine copyin_clause
+
+end subroutine copyin
More information about the flang-commits
mailing list