aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnamoy Bhattacharyya <arnamoy.bhattacharyya@huawei.com>2021-04-08 14:33:04 -0400
committerArnamoy Bhattacharyya <arnamoy10@gmail.com>2021-04-08 15:19:38 -0400
commit3a4c0354b6eb5484b9b0cff6f6a7df982b49414e (patch)
tree021c3a8776f645a71f488905bd5fe48644d3dd21
parent[mlir][StandardToSPIRV] Handle i1 case for lowering memref.load/store op (diff)
downloadllvm-project-3a4c0354b6eb5484b9b0cff6f6a7df982b49414e.tar.gz
llvm-project-3a4c0354b6eb5484b9b0cff6f6a7df982b49414e.tar.bz2
llvm-project-3a4c0354b6eb5484b9b0cff6f6a7df982b49414e.zip
[flang][OpenMP] Add functionality to check "close nesting" of regions, which can be used for Semantic checks. Also adding more test cases.
Reviewed By: kiranchandramohan Differential Revision: https://reviews.llvm.org/D99970
-rw-r--r--flang/lib/Semantics/check-omp-structure.cpp43
-rw-r--r--flang/lib/Semantics/check-omp-structure.h2
-rw-r--r--flang/test/Semantics/omp-do05.f9076
-rw-r--r--flang/test/Semantics/omp-nested01.f9026
-rw-r--r--flang/test/Semantics/omp-reduction07.f9013
5 files changed, 157 insertions, 3 deletions
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 892ce2ff4487..ec872d20691b 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -127,11 +127,52 @@ private:
std::map<std::string, std::int64_t> labelNamesandLevels_;
};
+bool OmpStructureChecker::IsCloselyNestedRegion(const OmpDirectiveSet &set) {
+ // Definition of close nesting:
+ //
+ // `A region nested inside another region with no parallel region nested
+ // between them`
+ //
+ // Examples:
+ // non-parallel construct 1
+ // non-parallel construct 2
+ // parallel construct
+ // construct 3
+ // In the above example, construct 3 is NOT closely nested inside construct 1
+ // or 2
+ //
+ // non-parallel construct 1
+ // non-parallel construct 2
+ // construct 3
+ // In the above example, construct 3 is closely nested inside BOTH construct 1
+ // and 2
+ //
+ // Algorithm:
+ // Starting from the parent context, Check in a bottom-up fashion, each level
+ // of the context stack. If we have a match for one of the (supplied)
+ // violating directives, `close nesting` is satisfied. If no match is there in
+ // the entire stack, `close nesting` is not satisfied. If at any level, a
+ // `parallel` region is found, `close nesting` is not satisfied.
+
+ if (CurrentDirectiveIsNested()) {
+ int index = dirContext_.size() - 2;
+ while (index != -1) {
+ if (set.test(dirContext_[index].directive)) {
+ return true;
+ } else if (llvm::omp::parallelSet.test(dirContext_[index].directive)) {
+ return false;
+ }
+ index--;
+ }
+ }
+ return false;
+}
+
bool OmpStructureChecker::HasInvalidWorksharingNesting(
const parser::CharBlock &source, const OmpDirectiveSet &set) {
// set contains all the invalid closely nested directives
// for the given directive (`source` here)
- if (CurrentDirectiveIsNested() && set.test(GetContextParent().directive)) {
+ if (IsCloselyNestedRegion(set)) {
context_.Say(source,
"A worksharing region may not be closely nested inside a "
"worksharing, explicit task, taskloop, critical, ordered, atomic, or "
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 0d11f72b5bc8..66a8c99cbcd6 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -166,7 +166,7 @@ public:
private:
bool HasInvalidWorksharingNesting(
const parser::CharBlock &, const OmpDirectiveSet &);
-
+ bool IsCloselyNestedRegion(const OmpDirectiveSet &set);
// specific clause related
bool ScheduleModifierHasType(const parser::OmpScheduleClause &,
const parser::OmpScheduleModifierType::ModType &);
diff --git a/flang/test/Semantics/omp-do05.f90 b/flang/test/Semantics/omp-do05.f90
index 07b952b6ad09..345bf15e3dce 100644
--- a/flang/test/Semantics/omp-do05.f90
+++ b/flang/test/Semantics/omp-do05.f90
@@ -6,7 +6,7 @@
program omp_do
integer n
- integer i,j
+ integer i,j,k
!$omp do
do i=1,10
!ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
@@ -18,6 +18,65 @@ program omp_do
end do
!$omp end do
+ !$omp do
+ do i=1,10
+ !$omp task
+ do j=1,10
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do k=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end task
+ end do
+ !$omp end do
+
+ !$omp do
+ do i=1,10
+ !$omp parallel
+ do j=1,10
+ !$omp single
+ do k=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end parallel
+ end do
+ !$omp end do
+
+!$omp do
+do i=1,10
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do j=1,10
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do k=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end single
+
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do k=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp do
+ do k=1,10
+ print *,"hello"
+ end do
+ !$omp end do
+end do
+!$omp end do
+
!$omp parallel default(shared)
!$omp do
do i = 1, n
@@ -29,4 +88,19 @@ program omp_do
!$omp end do
!$omp end parallel
+ !$omp parallel default(shared)
+ !$omp do
+ do i = 1, n
+ !$omp task
+ do j=1,10
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ call work(i, 1)
+ !$omp end single
+ end do
+ !$omp end task
+ end do
+ !$omp end do
+ !$omp end parallel
+
end program omp_do
diff --git a/flang/test/Semantics/omp-nested01.f90 b/flang/test/Semantics/omp-nested01.f90
index c84c9da1f4b8..010b5fd4ade7 100644
--- a/flang/test/Semantics/omp-nested01.f90
+++ b/flang/test/Semantics/omp-nested01.f90
@@ -11,4 +11,30 @@
a = 3.14
enddo
enddo
+
+ !$omp do
+ do i = 1, N
+ !$omp target
+ do k = 1,N
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp do
+ do j = 1, N
+ a = 3.14
+ enddo
+ enddo
+ !$omp end target
+ enddo
+
+
+ !$omp do
+ do i = 1, N
+ !$omp parallel
+ do k = 1,N
+ !$omp do
+ do j = 1, N
+ a = 3.14
+ enddo
+ enddo
+ !$omp end parallel
+ enddo
end
diff --git a/flang/test/Semantics/omp-reduction07.f90 b/flang/test/Semantics/omp-reduction07.f90
index 30dc5c5de3a4..1123c9084897 100644
--- a/flang/test/Semantics/omp-reduction07.f90
+++ b/flang/test/Semantics/omp-reduction07.f90
@@ -54,6 +54,19 @@ program omp_reduction
!$omp end do
!$omp end sections
+!$omp sections private(k)
+ !$omp target
+ do j = 1,10
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp do reduction(+:k) reduction(max:j)
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end do
+ end do
+ !$omp end target
+!$omp end sections
+
!$omp parallel reduction(+:a)
!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind.
!$omp sections reduction(-:a)