diff options
author | Arnamoy Bhattacharyya <arnamoy.bhattacharyya@huawei.com> | 2021-04-08 14:33:04 -0400 |
---|---|---|
committer | Arnamoy Bhattacharyya <arnamoy10@gmail.com> | 2021-04-08 15:19:38 -0400 |
commit | 3a4c0354b6eb5484b9b0cff6f6a7df982b49414e (patch) | |
tree | 021c3a8776f645a71f488905bd5fe48644d3dd21 | |
parent | [mlir][StandardToSPIRV] Handle i1 case for lowering memref.load/store op (diff) | |
download | llvm-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.cpp | 43 | ||||
-rw-r--r-- | flang/lib/Semantics/check-omp-structure.h | 2 | ||||
-rw-r--r-- | flang/test/Semantics/omp-do05.f90 | 76 | ||||
-rw-r--r-- | flang/test/Semantics/omp-nested01.f90 | 26 | ||||
-rw-r--r-- | flang/test/Semantics/omp-reduction07.f90 | 13 |
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) |