[flang-commits] [flang] 0fd425a - [flang]Add Semantic Checks for OpenMP Allocate Clause
Caroline Concatto via flang-commits
flang-commits at lists.llvm.org
Wed Sep 9 04:09:36 PDT 2020
Author: Irina Dobrescu
Date: 2020-09-09T12:06:21+01:00
New Revision: 0fd425af071a9bc5c0891a4db09f4d9a466b7be9
URL: https://github.com/llvm/llvm-project/commit/0fd425af071a9bc5c0891a4db09f4d9a466b7be9
DIFF: https://github.com/llvm/llvm-project/commit/0fd425af071a9bc5c0891a4db09f4d9a466b7be9.diff
LOG: [flang]Add Semantic Checks for OpenMP Allocate Clause
Reviewed By: kiranchandramohan, clementval, kiranktp, raghavendhra
Differential Revision: https://reviews.llvm.org/D86051
Added:
flang/test/Semantics/omp-resolve06.f90
Modified:
flang/include/flang/Semantics/symbol.h
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/check-omp-structure.h
flang/lib/Semantics/resolve-directives.cpp
flang/test/Semantics/omp-clause-validity01.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 981abb8555f8..5f861d10332e 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -501,9 +501,9 @@ class Symbol {
// OpenMP data-mapping attribute
OmpMapTo, OmpMapFrom, OmpMapAlloc, OmpMapRelease, OmpMapDelete,
// OpenMP miscellaneous flags
- OmpCommonBlock, OmpReduction, OmpDeclareSimd, OmpDeclareTarget,
- OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
- OmpIfSpecified, OmpNone, OmpPreDetermined);
+ OmpCommonBlock, OmpReduction, OmpAllocate, OmpDeclareSimd,
+ OmpDeclareTarget, OmpThreadprivate, OmpDeclareReduction, OmpFlushed,
+ OmpCriticalLock, OmpIfSpecified, OmpNone, OmpPreDetermined);
using Flags = common::EnumSet<Flag, Flag_enumSize>;
const Scope &owner() const { return *owner_; }
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 6a4980ebcd54..3e360b8ec4ca 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -456,6 +456,9 @@ void OmpStructureChecker::Enter(const parser::OmpAlignedClause &x) {
}
// 2.8.1 TODO: list-item attribute check
}
+void OmpStructureChecker::Enter(const parser::OmpAllocateClause &) {
+ CheckAllowed(llvm::omp::Clause::OMPC_allocate);
+}
void OmpStructureChecker::Enter(const parser::OmpDefaultClause &) {
CheckAllowed(llvm::omp::Clause::OMPC_default);
}
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 9a0c1e2c0a2d..fbe95d0ee2e0 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -150,6 +150,7 @@ class OmpStructureChecker
void Enter(const parser::OmpClause::IsDevicePtr &);
void Enter(const parser::OmpAlignedClause &);
+ void Enter(const parser::OmpAllocateClause &);
void Enter(const parser::OmpDefaultClause &);
void Enter(const parser::OmpDefaultmapClause &);
void Enter(const parser::OmpDependClause &);
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index e73bfa7c37cc..f68bcd1e1fa8 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -13,6 +13,7 @@
#include "resolve-names-utils.h"
#include "flang/Common/idioms.h"
#include "flang/Evaluate/fold.h"
+#include "flang/Evaluate/type.h"
#include "flang/Parser/parse-tree-visitor.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Parser/tools.h"
@@ -226,7 +227,8 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
}
bool Pre(const parser::OpenMPBlockConstruct &);
- void Post(const parser::OpenMPBlockConstruct &) { PopContext(); }
+ void Post(const parser::OpenMPBlockConstruct &);
+
void Post(const parser::OmpBeginBlockDirective &) {
GetContext().withinConstruct = true;
}
@@ -254,6 +256,11 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
ResolveOmpObjectList(x.v, Symbol::Flag::OmpPrivate);
return false;
}
+ bool Pre(const parser::OmpAllocateClause &x) {
+ const auto &objectList{std::get<parser::OmpObjectList>(x.t)};
+ ResolveOmpObjectList(objectList, Symbol::Flag::OmpAllocate);
+ return false;
+ }
bool Pre(const parser::OmpClause::Firstprivate &x) {
ResolveOmpObjectList(x.v, Symbol::Flag::OmpFirstPrivate);
return false;
@@ -273,6 +280,10 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
Symbol::Flag::OmpFirstPrivate, Symbol::Flag::OmpLastPrivate,
Symbol::Flag::OmpReduction, Symbol::Flag::OmpLinear};
+ static constexpr Symbol::Flags privateDataSharingAttributeFlags{
+ Symbol::Flag::OmpPrivate, Symbol::Flag::OmpFirstPrivate,
+ Symbol::Flag::OmpLastPrivate};
+
static constexpr Symbol::Flags ompFlagsRequireNewSymbol{
Symbol::Flag::OmpPrivate, Symbol::Flag::OmpLinear,
Symbol::Flag::OmpFirstPrivate, Symbol::Flag::OmpLastPrivate,
@@ -281,6 +292,21 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
static constexpr Symbol::Flags ompFlagsRequireMark{
Symbol::Flag::OmpThreadprivate};
+ std::vector<const parser::Name *> allocateNames_; // on one directive
+ SymbolSet privateDataSharingAttributeObjects_; // on one directive
+
+ void AddAllocateName(const parser::Name *&object) {
+ allocateNames_.push_back(object);
+ }
+ void ClearAllocateNames() { allocateNames_.clear(); }
+
+ void AddPrivateDataSharingAttributeObjects(SymbolRef object) {
+ privateDataSharingAttributeObjects_.insert(object);
+ }
+ void ClearPrivateDataSharingAttributeObjects() {
+ privateDataSharingAttributeObjects_.clear();
+ }
+
// Predetermined DSA rules
void PrivatizeAssociatedLoopIndex(const parser::OpenMPLoopConstruct &);
void ResolveSeqLoopIndexInParallelOrTaskConstruct(const parser::Name &);
@@ -632,9 +658,49 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
break;
}
ClearDataSharingAttributeObjects();
+ ClearPrivateDataSharingAttributeObjects();
+ ClearAllocateNames();
return true;
}
+void OmpAttributeVisitor::Post(const parser::OpenMPBlockConstruct &x) {
+ const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
+ const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
+ switch (beginDir.v) {
+ case llvm::omp::Directive::OMPD_parallel:
+ case llvm::omp::Directive::OMPD_single:
+ case llvm::omp::Directive::OMPD_target:
+ case llvm::omp::Directive::OMPD_task:
+ case llvm::omp::Directive::OMPD_teams:
+ case llvm::omp::Directive::OMPD_parallel_workshare:
+ case llvm::omp::Directive::OMPD_target_teams:
+ case llvm::omp::Directive::OMPD_target_parallel: {
+ bool hasPrivate;
+ for (const auto *allocName : allocateNames_) {
+ hasPrivate = false;
+ for (auto privateObj : privateDataSharingAttributeObjects_) {
+ const Symbol &symbolPrivate{*privateObj};
+ if (allocName->source == symbolPrivate.name()) {
+ hasPrivate = true;
+ break;
+ }
+ }
+ if (!hasPrivate) {
+ context_.Say(allocName->source,
+ "The ALLOCATE clause requires that '%s' must be listed in a "
+ "private "
+ "data-sharing attribute clause on the same directive"_err_en_US,
+ allocName->ToString());
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ PopContext();
+}
+
bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
@@ -879,6 +945,9 @@ void OmpAttributeVisitor::ResolveOmpObject(
if (dataSharingAttributeFlags.test(ompFlag)) {
CheckMultipleAppearances(*name, *symbol, ompFlag);
}
+ if (ompFlag == Symbol::Flag::OmpAllocate) {
+ AddAllocateName(name);
+ }
}
} else {
// Array sections to be changed to substrings as needed
@@ -976,6 +1045,9 @@ void OmpAttributeVisitor::CheckMultipleAppearances(
name.ToString());
} else {
AddDataSharingAttributeObject(*target);
+ if (privateDataSharingAttributeFlags.test(ompFlag)) {
+ AddPrivateDataSharingAttributeObjects(*target);
+ }
}
}
diff --git a/flang/test/Semantics/omp-clause-validity01.f90 b/flang/test/Semantics/omp-clause-validity01.f90
index d3f77a432de8..07f55733c8dc 100644
--- a/flang/test/Semantics/omp-clause-validity01.f90
+++ b/flang/test/Semantics/omp-clause-validity01.f90
@@ -9,7 +9,7 @@
! TODO: all the internal errors
integer :: b = 128
- integer :: c = 32
+ integer :: z, c = 32
integer, parameter :: num = 16
real(8) :: arrayA(256), arrayB(512)
@@ -39,29 +39,54 @@
enddo
!$omp end parallel
- !$omp parallel allocate(b)
+ !$omp parallel private(b) allocate(b)
do i = 1, N
a = 3.14
enddo
!$omp end parallel
- !$omp parallel allocate(omp_default_mem_space : b, c)
+ !$omp parallel private(c, b) allocate(omp_default_mem_space : b, c)
do i = 1, N
a = 3.14
enddo
!$omp end parallel
- !$omp parallel allocate(b) allocate(c)
+ !$omp parallel allocate(b) allocate(c) private(b, c)
do i = 1, N
a = 3.14
enddo
!$omp end parallel
- !$omp parallel allocate(xy_alloc :b)
+ !$omp parallel allocate(xy_alloc :b) private(b)
do i = 1, N
a = 3.14
enddo
!$omp end parallel
+
+ !$omp task private(b) allocate(b)
+ do i = 1, N
+ z = 2
+ end do
+ !$omp end task
+
+ !$omp teams private(b) allocate(b)
+ do i = 1, N
+ z = 2
+ end do
+ !$omp end teams
+
+ !$omp target private(b) allocate(b)
+ do i = 1, N
+ z = 2
+ end do
+ !$omp end target
+
+ !ERROR: ALLOCATE clause is not allowed on the TARGET DATA directive
+ !$omp target data map(from: b) allocate(b)
+ do i = 1, N
+ z = 2
+ enddo
+ !$omp end target data
!ERROR: SCHEDULE clause is not allowed on the PARALLEL directive
!$omp parallel schedule(static)
diff --git a/flang/test/Semantics/omp-resolve06.f90 b/flang/test/Semantics/omp-resolve06.f90
new file mode 100644
index 000000000000..0909c0f54a57
--- /dev/null
+++ b/flang/test/Semantics/omp-resolve06.f90
@@ -0,0 +1,54 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+use omp_lib
+!2.11.4 Allocate Clause
+!For any list item that is specified in the allocate
+!clause on a directive, a data-sharing attribute clause
+!that may create a private copy of that list item must be
+!specified on the same directive.
+
+ integer :: N = 2
+
+ !ERROR: The ALLOCATE clause requires that 'x' must be listed in a private data-sharing attribute clause on the same directive
+ !$omp parallel allocate(omp_default_mem_space : x)
+ do i = 1, N
+ x = 2
+ enddo
+ !$omp end parallel
+
+ !ERROR: The ALLOCATE clause requires that 'y' must be listed in a private data-sharing attribute clause on the same directive
+ !$omp parallel allocate(omp_default_mem_space : y) firstprivate(x)
+ do i = 1, N
+ x = 2
+ enddo
+ !$omp end parallel
+
+ !ERROR: The ALLOCATE clause requires that 'x' must be listed in a private data-sharing attribute clause on the same directive
+ !ERROR: The ALLOCATE clause requires that 'x' must be listed in a private data-sharing attribute clause on the same directive
+ !$omp parallel allocate(omp_default_mem_space : x) allocate(omp_default_mem_space : x)
+ do i = 1, N
+ x = 2
+ enddo
+ !$omp end parallel
+
+ !ERROR: The ALLOCATE clause requires that 'f' must be listed in a private data-sharing attribute clause on the same directive
+ !$omp parallel allocate(omp_default_mem_space : f) shared(f)
+ do i = 1, N
+ x = 2
+ enddo
+ !$omp end parallel
+
+ !ERROR: The ALLOCATE clause requires that 'q' must be listed in a private data-sharing attribute clause on the same directive
+ !$omp parallel private(t) allocate(omp_default_mem_space : z, t, q, r) firstprivate(z, r)
+ do i = 1, N
+ x = 2
+ enddo
+ !$omp end parallel
+
+ !ERROR: The ALLOCATE clause requires that 'b' must be listed in a private data-sharing attribute clause on the same directive
+ !ERROR: The ALLOCATE clause requires that 'c' must be listed in a private data-sharing attribute clause on the same directive
+ !$omp parallel allocate(omp_default_mem_space : a, b, c, d) firstprivate(a, d)
+ do i = 1, N
+ x = 2
+ enddo
+ !$omp end parallel
+end
More information about the flang-commits
mailing list