[flang][OpenMP][FIX] Fix the worksharing nesting check with inclusion of more constru...
authorArnamoy Bhattacharyya <arnamoy.bhattacharyya@huawei.com>
Thu, 29 Apr 2021 20:12:28 +0000 (16:12 -0400)
committerArnamoy Bhattacharyya <arnamoy.bhattacharyya@huawei.com>
Thu, 29 Apr 2021 20:17:32 +0000 (16:17 -0400)
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/check-omp-structure.h
flang/test/Semantics/omp-do05.f90
flang/test/Semantics/omp-workshare01.f90
flang/test/Semantics/omp-workshare04.f90
flang/test/Semantics/omp-workshare05.f90

index 23a29ae..868c646 100644 (file)
@@ -267,16 +267,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
     //                    ordered-clause
 
     // nesting check
-    HasInvalidWorksharingNesting(beginDir.source,
-        {llvm::omp::Directive::OMPD_do, llvm::omp::Directive::OMPD_sections,
-            llvm::omp::Directive::OMPD_single,
-            llvm::omp::Directive::OMPD_workshare,
-            llvm::omp::Directive::OMPD_task,
-            llvm::omp::Directive::OMPD_taskloop,
-            llvm::omp::Directive::OMPD_critical,
-            llvm::omp::Directive::OMPD_ordered,
-            llvm::omp::Directive::OMPD_atomic,
-            llvm::omp::Directive::OMPD_master});
+    HasInvalidWorksharingNesting(
+        beginDir.source, llvm::omp::nestedWorkshareErrSet);
   }
   SetLoopInfo(x);
 
@@ -420,12 +412,6 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
 
   PushContextAndClauseSets(beginDir.source, beginDir.v);
 
-  // TODO: This check needs to be extended while implementing nesting of regions
-  // checks.
-  if (beginDir.v == llvm::omp::Directive::OMPD_single) {
-    HasInvalidWorksharingNesting(
-        beginDir.source, {llvm::omp::Directive::OMPD_do});
-  }
   if (CurrentDirectiveIsNested()) {
     CheckIfDoOrderedClause(beginDir);
     if (llvm::omp::teamSet.test(GetContextParent().directive)) {
@@ -439,6 +425,14 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
   case llvm::omp::OMPD_workshare:
   case llvm::omp::OMPD_parallel_workshare:
     CheckWorkshareBlockStmts(block, beginDir.source);
+    HasInvalidWorksharingNesting(
+        beginDir.source, llvm::omp::nestedWorkshareErrSet);
+    break;
+  case llvm::omp::Directive::OMPD_single:
+    // TODO: This check needs to be extended while implementing nesting of
+    // regions checks.
+    HasInvalidWorksharingNesting(
+        beginDir.source, llvm::omp::nestedWorkshareErrSet);
     break;
   default:
     break;
@@ -484,6 +478,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
   for (const auto &block : sectionBlocks.v) {
     CheckNoBranching(block, beginDir.v, beginDir.source);
   }
+  HasInvalidWorksharingNesting(
+      beginDir.source, llvm::omp::nestedWorkshareErrSet);
 }
 
 void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &) {
index ad3d406..8c76530 100644 (file)
@@ -42,10 +42,10 @@ static OmpDirectiveSet parallelSet{Directive::OMPD_distribute_parallel_do,
     Directive::OMPD_teams_distribute_parallel_do,
     Directive::OMPD_teams_distribute_parallel_do_simd};
 static OmpDirectiveSet doSet{Directive::OMPD_distribute_parallel_do,
-    Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_parallel,
-    Directive::OMPD_parallel_do, Directive::OMPD_parallel_do_simd,
-    Directive::OMPD_do, Directive::OMPD_do_simd,
-    Directive::OMPD_target_parallel_do, Directive::OMPD_target_parallel_do_simd,
+    Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_parallel_do,
+    Directive::OMPD_parallel_do_simd, Directive::OMPD_do,
+    Directive::OMPD_do_simd, Directive::OMPD_target_parallel_do,
+    Directive::OMPD_target_parallel_do_simd,
     Directive::OMPD_target_teams_distribute_parallel_do,
     Directive::OMPD_target_teams_distribute_parallel_do_simd,
     Directive::OMPD_teams_distribute_parallel_do,
@@ -55,6 +55,11 @@ static OmpDirectiveSet doSimdSet{Directive::OMPD_distribute_parallel_do_simd,
     Directive::OMPD_target_parallel_do_simd,
     Directive::OMPD_target_teams_distribute_parallel_do_simd,
     Directive::OMPD_teams_distribute_parallel_do_simd};
+static OmpDirectiveSet workShareSet{
+    OmpDirectiveSet{Directive::OMPD_workshare,
+        Directive::OMPD_parallel_workshare, Directive::OMPD_parallel_sections,
+        Directive::OMPD_sections, Directive::OMPD_single} |
+    doSet};
 static OmpDirectiveSet taskloopSet{
     Directive::OMPD_taskloop, Directive::OMPD_taskloop_simd};
 static OmpDirectiveSet targetSet{Directive::OMPD_target,
@@ -83,6 +88,11 @@ static OmpDirectiveSet taskGeneratingSet{
 static OmpDirectiveSet nestedOrderedErrSet{Directive::OMPD_critical,
     Directive::OMPD_ordered, Directive::OMPD_atomic, Directive::OMPD_task,
     Directive::OMPD_taskloop};
+static OmpDirectiveSet nestedWorkshareErrSet{
+    OmpDirectiveSet{Directive::OMPD_task, Directive::OMPD_taskloop,
+        Directive::OMPD_critical, Directive::OMPD_ordered,
+        Directive::OMPD_atomic, Directive::OMPD_master} |
+    workShareSet};
 static OmpClauseSet privateSet{
     Clause::OMPC_private, Clause::OMPC_firstprivate, Clause::OMPC_lastprivate};
 static OmpClauseSet privateReductionSet{
index 345bf15..e2e8999 100644 (file)
@@ -18,6 +18,96 @@ program omp_do
   end do
   !$omp end do
 
+  !$omp parallel 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
+      print *,"hello"
+    end do
+    !$omp end single
+  end do
+  !$omp end parallel do
+
+  !$omp parallel do simd
+  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
+      print *,"hello"
+    end do
+    !$omp end single
+  end do
+  !$omp end parallel do simd
+
+  !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+  !$omp distribute parallel 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
+      print *,"hello"
+    end do
+    !$omp end single
+  end do
+  !$omp end distribute parallel do
+
+  !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+  !$omp distribute parallel do simd
+  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
+      print *,"hello"
+    end do
+    !$omp end single
+  end do
+  !$omp end distribute parallel do simd
+
+  !$omp target parallel 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
+      print *,"hello"
+    end do
+    !$omp end single
+  end do
+  !$omp end target parallel do
+
+  !$omp target parallel do simd
+  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
+      print *,"hello"
+    end do
+    !$omp end single
+  end do
+  !$omp end target parallel do simd
+
+  !$omp target teams distribute parallel 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
+      print *,"hello"
+    end do
+    !$omp end single
+  end do
+  !$omp end target teams distribute parallel do
+
+    !$omp target teams distribute parallel do simd
+  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
+      print *,"hello"
+    end do
+    !$omp end single
+  end do
+  !$omp end target teams distribute parallel do simd
+
   !$omp do
   do i=1,10
     !$omp task
index 1a1f194..2f8a48b 100644 (file)
@@ -15,6 +15,7 @@ subroutine workshare(aa, bb, cc, dd, ee, ff, n)
   end do
 
   !$omp critical
+  !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
   !$omp single
   aa = bb
   !$omp end single
index 6742174..ab8ec03 100644 (file)
@@ -18,7 +18,9 @@ subroutine omp_workshare(aa, bb, cc, dd, ee, ff, n)
   !$omp end parallel
 
   !ERROR: OpenMP constructs enclosed in WORKSHARE construct may consist of ATOMIC, CRITICAL or PARALLEL constructs only
+  !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
   !$omp parallel workshare
+  !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
   !$omp single
   ee = ff
   !$omp end single
index ab0f6d0..372df32 100644 (file)
@@ -40,6 +40,7 @@ program omp_workshare
   !$omp end single
   !$omp end parallel
 
+  !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
   !$omp parallel sections
   !$omp section
   aa = my_func()