Skip to content

Commit 6d1c183

Browse files
committed
[Flang] [OpenMP] [Semantics] Add missing semantic check for MAP clause.
Added support for following semantic check for MAP clause. - A list item cannot appear in both a map clause and a data-sharing attribute clause on the same target construct. Reviewed By: NimishMishra Differential Revision: https://reviews.llvm.org/D158807
1 parent 1c567a5 commit 6d1c183

File tree

7 files changed

+167
-32
lines changed

7 files changed

+167
-32
lines changed

flang/include/flang/Semantics/symbol.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -643,8 +643,8 @@ class Symbol {
643643
// OpenMP data-sharing attribute
644644
OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
645645
// OpenMP data-mapping attribute
646-
OmpMapTo, OmpMapFrom, OmpMapAlloc, OmpMapRelease, OmpMapDelete,
647-
OmpUseDevicePtr, OmpUseDeviceAddr,
646+
OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapAlloc, OmpMapRelease,
647+
OmpMapDelete, OmpUseDevicePtr, OmpUseDeviceAddr,
648648
// OpenMP data-copying attribute
649649
OmpCopyIn, OmpCopyPrivate,
650650
// OpenMP miscellaneous flags
@@ -674,6 +674,7 @@ class Symbol {
674674
void set_offset(std::size_t offset) { offset_ = offset; }
675675
// Give the symbol a name with a different source location but same chars.
676676
void ReplaceName(const SourceName &);
677+
std::string OmpFlagToClauseName(Flag ompFlag);
677678

678679
// Does symbol have this type of details?
679680
template <typename D> bool has() const {

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 83 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -529,13 +529,45 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
529529
void Post(const parser::EorLabel &eorLabel) { CheckSourceLabel(eorLabel.v); }
530530

531531
void Post(const parser::OmpMapClause &x) {
532+
Symbol::Flag ompFlag = Symbol::Flag::OmpMapToFrom;
533+
if (const auto &maptype{std::get<std::optional<parser::OmpMapType>>(x.t)}) {
534+
using Type = parser::OmpMapType::Type;
535+
const Type &type{std::get<Type>(maptype->t)};
536+
switch (type) {
537+
case Type::To:
538+
ompFlag = Symbol::Flag::OmpMapTo;
539+
break;
540+
case Type::From:
541+
ompFlag = Symbol::Flag::OmpMapFrom;
542+
break;
543+
case Type::Tofrom:
544+
ompFlag = Symbol::Flag::OmpMapToFrom;
545+
break;
546+
case Type::Alloc:
547+
ompFlag = Symbol::Flag::OmpMapAlloc;
548+
break;
549+
case Type::Release:
550+
ompFlag = Symbol::Flag::OmpMapRelease;
551+
break;
552+
case Type::Delete:
553+
ompFlag = Symbol::Flag::OmpMapDelete;
554+
break;
555+
default:
556+
assert(false && "Unsupported map-type");
557+
break;
558+
}
559+
}
532560
const auto &ompObjList{std::get<parser::OmpObjectList>(x.t)};
533561
for (const auto &ompObj : ompObjList.v) {
534562
common::visit(
535563
common::visitors{
536564
[&](const parser::Designator &designator) {
537565
if (const auto *name{
538566
semantics::getDesignatorNameIfDataRef(designator)}) {
567+
if (name->symbol) {
568+
name->symbol->set(ompFlag);
569+
AddToContextObjectWithDSA(*name->symbol, ompFlag);
570+
}
539571
if (name->symbol &&
540572
semantics::IsAssumedSizeArray(*name->symbol)) {
541573
context_.Say(designator.source,
@@ -1908,6 +1940,27 @@ void OmpAttributeVisitor::ResolveOmpObject(
19081940
if (const auto *name{
19091941
semantics::getDesignatorNameIfDataRef(designator)}) {
19101942
if (auto *symbol{ResolveOmp(*name, ompFlag, currScope())}) {
1943+
auto checkExclusivelists =
1944+
[&](const Symbol *symbol1, Symbol::Flag firstOmpFlag,
1945+
Symbol *symbol2, Symbol::Flag secondOmpFlag) {
1946+
if ((symbol1->test(firstOmpFlag) &&
1947+
symbol2->test(secondOmpFlag)) ||
1948+
(symbol1->test(secondOmpFlag) &&
1949+
symbol2->test(firstOmpFlag))) {
1950+
context_.Say(designator.source,
1951+
"Variable '%s' may not "
1952+
"appear on both %s and %s "
1953+
"clauses on a %s construct"_err_en_US,
1954+
symbol2->name(),
1955+
const_cast<Symbol *>(symbol1)->OmpFlagToClauseName(
1956+
firstOmpFlag),
1957+
symbol2->OmpFlagToClauseName(secondOmpFlag),
1958+
parser::ToUpperCaseLetters(
1959+
llvm::omp::getOpenMPDirectiveName(
1960+
GetContext().directive)
1961+
.str()));
1962+
}
1963+
};
19111964
if (dataCopyingAttributeFlags.test(ompFlag)) {
19121965
CheckDataCopyingClause(*name, *symbol, ompFlag);
19131966
} else {
@@ -1943,28 +1996,37 @@ void OmpAttributeVisitor::ResolveOmpObject(
19431996
GetContext().directive)
19441997
.str()));
19451998
}
1946-
if ((GetContext().directive ==
1947-
llvm::omp::Directive::OMPD_target_data) &&
1948-
(((ompFlag == Symbol::Flag::OmpUseDevicePtr) &&
1949-
symbol->test(Symbol::Flag::OmpUseDeviceAddr)) ||
1950-
((ompFlag == Symbol::Flag::OmpUseDeviceAddr) &&
1951-
symbol->test(Symbol::Flag::OmpUseDevicePtr)))) {
1952-
context_.Say(designator.source,
1953-
"Variable '%s' may not "
1954-
"appear on both USE_DEVICE_PTR and USE_DEVICE_ADDR "
1955-
"clauses on a TARGET DATA construct"_err_en_US,
1956-
symbol->name());
1999+
if (GetContext().directive ==
2000+
llvm::omp::Directive::OMPD_target_data) {
2001+
checkExclusivelists(symbol, Symbol::Flag::OmpUseDevicePtr,
2002+
symbol, Symbol::Flag::OmpUseDeviceAddr);
19572003
}
1958-
if (llvm::omp::allDistributeSet.test(GetContext().directive) &&
1959-
(((ompFlag == Symbol::Flag::OmpFirstPrivate) &&
1960-
symbol->test(Symbol::Flag::OmpLastPrivate)) ||
1961-
((ompFlag == Symbol::Flag::OmpLastPrivate) &&
1962-
symbol->test(Symbol::Flag::OmpFirstPrivate)))) {
1963-
context_.Say(designator.source,
1964-
"Variable '%s' may not "
1965-
"appear on both FIRSTPRIVATE and LASTPRIVATE "
1966-
"clauses on a DISTRIBUTE construct"_err_en_US,
1967-
symbol->name());
2004+
if (llvm::omp::allDistributeSet.test(GetContext().directive)) {
2005+
checkExclusivelists(symbol, Symbol::Flag::OmpFirstPrivate,
2006+
symbol, Symbol::Flag::OmpLastPrivate);
2007+
}
2008+
if (llvm::omp::allTargetSet.test(GetContext().directive)) {
2009+
const auto *hostAssocSym{symbol};
2010+
if (const auto *details{
2011+
symbol->detailsIf<HostAssocDetails>()}) {
2012+
hostAssocSym = &details->symbol();
2013+
}
2014+
Symbol::Flag dataMappingAttributeFlags[] = {
2015+
Symbol::Flag::OmpMapTo, Symbol::Flag::OmpMapFrom,
2016+
Symbol::Flag::OmpMapToFrom, Symbol::Flag::OmpMapAlloc,
2017+
Symbol::Flag::OmpMapRelease, Symbol::Flag::OmpMapDelete};
2018+
2019+
Symbol::Flag dataSharingAttributeFlags[] = {
2020+
Symbol::Flag::OmpPrivate, Symbol::Flag::OmpFirstPrivate,
2021+
Symbol::Flag::OmpLastPrivate, Symbol::Flag::OmpShared,
2022+
Symbol::Flag::OmpLinear};
2023+
2024+
for (Symbol::Flag ompFlag1 : dataMappingAttributeFlags) {
2025+
for (Symbol::Flag ompFlag2 : dataSharingAttributeFlags) {
2026+
checkExclusivelists(
2027+
hostAssocSym, ompFlag1, symbol, ompFlag2);
2028+
}
2029+
}
19682030
}
19692031
}
19702032
} else {

flang/lib/Semantics/symbol.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,51 @@ bool GenericKind::Is(GenericKind::OtherKind x) const {
757757
return y && *y == x;
758758
}
759759

760+
std::string Symbol::OmpFlagToClauseName(Symbol::Flag ompFlag) {
761+
std::string clauseName;
762+
switch (ompFlag) {
763+
case Symbol::Flag::OmpShared:
764+
clauseName = "SHARED";
765+
break;
766+
case Symbol::Flag::OmpPrivate:
767+
clauseName = "PRIVATE";
768+
break;
769+
case Symbol::Flag::OmpLinear:
770+
clauseName = "LINEAR";
771+
break;
772+
case Symbol::Flag::OmpFirstPrivate:
773+
clauseName = "FIRSTPRIVATE";
774+
break;
775+
case Symbol::Flag::OmpLastPrivate:
776+
clauseName = "LASTPRIVATE";
777+
break;
778+
case Symbol::Flag::OmpMapTo:
779+
case Symbol::Flag::OmpMapFrom:
780+
case Symbol::Flag::OmpMapToFrom:
781+
case Symbol::Flag::OmpMapAlloc:
782+
case Symbol::Flag::OmpMapRelease:
783+
case Symbol::Flag::OmpMapDelete:
784+
clauseName = "MAP";
785+
break;
786+
case Symbol::Flag::OmpUseDevicePtr:
787+
clauseName = "USE_DEVICE_PTR";
788+
break;
789+
case Symbol::Flag::OmpUseDeviceAddr:
790+
clauseName = "USE_DEVICE_ADDR";
791+
break;
792+
case Symbol::Flag::OmpCopyIn:
793+
clauseName = "COPYIN";
794+
break;
795+
case Symbol::Flag::OmpCopyPrivate:
796+
clauseName = "COPYPRIVATE";
797+
break;
798+
default:
799+
clauseName = "";
800+
break;
801+
}
802+
return clauseName;
803+
}
804+
760805
bool SymbolOffsetCompare::operator()(
761806
const SymbolRef &x, const SymbolRef &y) const {
762807
const Symbol *xCommon{FindCommonBlockContaining(*x)};

flang/test/Semantics/OpenMP/firstprivate01.f90

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,27 @@ program omp_firstprivate
3838
a(i) = a(i) + b(i) - i
3939
end do
4040
!$omp end teams distribute
41-
!ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a DISTRIBUTE construct
41+
!ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
4242
!$omp teams distribute firstprivate(a,b) lastprivate(b)
4343
do i = 1, 10
4444
a(i) = a(i) + b(i) - i
4545
end do
4646
!$omp end teams distribute
47-
!ERROR: Variable 'a' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a DISTRIBUTE construct
48-
!ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a DISTRIBUTE construct
47+
!ERROR: Variable 'a' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
48+
!ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
4949
!$omp teams distribute firstprivate(a,b) lastprivate(a,b)
5050
do i = 1, 10
5151
a(i) = a(i) + b(i) - i
5252
end do
5353
!$omp end teams distribute
54-
!ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a DISTRIBUTE construct
54+
!ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
5555
!$omp teams distribute lastprivate(a,b) firstprivate(b)
5656
do i = 1, 10
5757
a(i) = a(i) + b(i) - i
5858
end do
5959
!$omp end teams distribute
60-
!ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a DISTRIBUTE construct
61-
!ERROR: Variable 'a' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a DISTRIBUTE construct
60+
!ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
61+
!ERROR: Variable 'a' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
6262
!$omp teams distribute lastprivate(a,b) firstprivate(b,a)
6363
do i = 1, 10
6464
a(i) = a(i) + b(i) - i

flang/test/Semantics/OpenMP/symbol08.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ end subroutine test_taskloop
106106
! Rule a); OpenMP 4.5 Examples teams.2.f90
107107
! TODO: reduction; data-mapping attributes
108108
!DEF: /dotprod (Subroutine) Subprogram
109-
!DEF: /dotprod/b ObjectEntity REAL(4)
110-
!DEF: /dotprod/c ObjectEntity REAL(4)
109+
!DEF: /dotprod/b (OmpMapTo) ObjectEntity REAL(4)
110+
!DEF: /dotprod/c (OmpMapTo) ObjectEntity REAL(4)
111111
!DEF: /dotprod/n ObjectEntity INTEGER(4)
112112
!DEF: /dotprod/block_size ObjectEntity INTEGER(4)
113113
!DEF: /dotprod/num_teams ObjectEntity INTEGER(4)
@@ -119,7 +119,7 @@ subroutine dotprod (b, c, n, block_size, num_teams, block_threads)
119119
!REF: /dotprod/b
120120
!REF: /dotprod/n
121121
!REF: /dotprod/c
122-
!DEF: /dotprod/sum ObjectEntity REAL(4)
122+
!DEF: /dotprod/sum (OmpMapToFrom) ObjectEntity REAL(4)
123123
real b(n), c(n), sum
124124
!REF: /dotprod/block_size
125125
!REF: /dotprod/num_teams
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
2+
! OpenMP Version 4.5
3+
4+
integer :: x
5+
!ERROR: Variable 'x' may not appear on both MAP and PRIVATE clauses on a TARGET construct
6+
!$omp target map(x) private(x)
7+
x = x + 1
8+
!$omp end target
9+
10+
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
2+
! OpenMP Version 4.5
3+
4+
program p
5+
integer :: y
6+
!ERROR: Variable 'y' may not appear on both MAP and FIRSTPRIVATE clauses on a TARGET construct
7+
!$omp target map(y) firstprivate(y)
8+
y = y + 1
9+
!$omp end target
10+
!ERROR: Variable 'y' may not appear on both MAP and FIRSTPRIVATE clauses on a TARGET SIMD construct
11+
!$omp target simd map(y) firstprivate(y)
12+
do i=1,1
13+
y = y + 1
14+
end do
15+
!$omp end target simd
16+
17+
end program p

0 commit comments

Comments
 (0)