]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
OpenMP: Add Fortran support for inoutset depend-kind
authorTobias Burnus <tobias@codesourcery.com>
Wed, 18 May 2022 10:04:21 +0000 (12:04 +0200)
committerTobias Burnus <tobias@codesourcery.com>
Wed, 18 May 2022 10:04:21 +0000 (12:04 +0200)
Fortran additions to the C/C++ + ME/libgomp commit
r13-556-g2c16eb3157f86ae561468c540caf8eb326106b5f

gcc/fortran/ChangeLog:

* gfortran.h (enum gfc_omp_depend_op): Add OMP_DEPEND_INOUTSET.
(gfc_omp_clauses): Enlarge ENUM_BITFIELD.
* dump-parse-tree.cc (show_omp_namelist, show_omp_clauses): Handle
'inoutset' depend modifier.
* openmp.cc (gfc_match_omp_clauses, gfc_match_omp_depobj): Likewise.
* trans-openmp.cc (gfc_trans_omp_clauses, gfc_trans_omp_depobj):
Likewise.

libgomp/ChangeLog:

* libgomp.texi (OpenMP 5.1): Set 'inoutset' to Y.
(OpenMP Context Selectors): Add missing comma.
* testsuite/libgomp.fortran/depend-5.f90: Add inoutset test.
* testsuite/libgomp.fortran/depend-6.f90: Likewise.
* testsuite/libgomp.fortran/depend-7.f90: Likewise.
* testsuite/libgomp.fortran/depend-inoutset-1.f90: New test.

gcc/testsuite/ChangeLog:

* gfortran.dg/gomp/all-memory-1.f90: Add inoutset test.
* gfortran.dg/gomp/all-memory-2.f90: Likewise.
* gfortran.dg/gomp/depobj-1.f90: Likewise.
* gfortran.dg/gomp/depobj-2.f90: Likewise.

13 files changed:
gcc/fortran/dump-parse-tree.cc
gcc/fortran/gfortran.h
gcc/fortran/openmp.cc
gcc/fortran/trans-openmp.cc
gcc/testsuite/gfortran.dg/gomp/all-memory-1.f90
gcc/testsuite/gfortran.dg/gomp/all-memory-2.f90
gcc/testsuite/gfortran.dg/gomp/depobj-1.f90
gcc/testsuite/gfortran.dg/gomp/depobj-2.f90
libgomp/libgomp.texi
libgomp/testsuite/libgomp.fortran/depend-5.f90
libgomp/testsuite/libgomp.fortran/depend-6.f90
libgomp/testsuite/libgomp.fortran/depend-7.f90
libgomp/testsuite/libgomp.fortran/depend-inoutset-1.f90 [new file with mode: 0644]

index a32992035a277fce04a2d9776426efd972165994..4e8986bd599d3f72fced9970b32d5d4806d5ff70 100644 (file)
@@ -1379,6 +1379,7 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n)
          case OMP_DEPEND_IN: fputs ("in:", dumpfile); break;
          case OMP_DEPEND_OUT: fputs ("out:", dumpfile); break;
          case OMP_DEPEND_INOUT: fputs ("inout:", dumpfile); break;
+         case OMP_DEPEND_INOUTSET: fputs ("inoutset:", dumpfile); break;
          case OMP_DEPEND_DEPOBJ: fputs ("depobj:", dumpfile); break;
          case OMP_DEPEND_MUTEXINOUTSET:
            fputs ("mutexinoutset:", dumpfile);
@@ -1898,6 +1899,7 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses)
        case OMP_DEPEND_IN: deptype = "IN"; break;
        case OMP_DEPEND_OUT: deptype = "OUT"; break;
        case OMP_DEPEND_INOUT: deptype = "INOUT"; break;
+       case OMP_DEPEND_INOUTSET: deptype = "INOUTSET"; break;
        case OMP_DEPEND_MUTEXINOUTSET: deptype = "MUTEXINOUTSET"; break;
        default: gcc_unreachable ();
        }
index 1bce2833139793aa8b6e2c7d49f34b1d1cda894f..5d970bc1df018a78bcb84ddfc134b6b5a31bee71 100644 (file)
@@ -1271,6 +1271,7 @@ enum gfc_omp_depend_op
   OMP_DEPEND_IN,
   OMP_DEPEND_OUT,
   OMP_DEPEND_INOUT,
+  OMP_DEPEND_INOUTSET,
   OMP_DEPEND_MUTEXINOUTSET,
   OMP_DEPEND_DEPOBJ,
   OMP_DEPEND_SINK_FIRST,
@@ -1540,7 +1541,7 @@ typedef struct gfc_omp_clauses
   ENUM_BITFIELD (gfc_omp_memorder) fail:3;
   ENUM_BITFIELD (gfc_omp_cancel_kind) cancel:3;
   ENUM_BITFIELD (gfc_omp_proc_bind_kind) proc_bind:3;
-  ENUM_BITFIELD (gfc_omp_depend_op) depobj_update:3;
+  ENUM_BITFIELD (gfc_omp_depend_op) depobj_update:4;
   ENUM_BITFIELD (gfc_omp_bind_type) bind:2;
   ENUM_BITFIELD (gfc_omp_at_type) at:2;
   ENUM_BITFIELD (gfc_omp_severity_type) severity:2;
index 3061e5297b735253e8a85195da13d70bd5f29dc5..63fd4dd2767ad64b15a3473b8d166cb2dfbb0205 100644 (file)
@@ -1915,7 +1915,9 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
                break;
              m = MATCH_YES;
              gfc_omp_depend_op depend_op = OMP_DEPEND_OUT;
-             if (gfc_match ("inout") == MATCH_YES)
+             if (gfc_match ("inoutset") == MATCH_YES)
+               depend_op = OMP_DEPEND_INOUTSET;
+             else if (gfc_match ("inout") == MATCH_YES)
                depend_op = OMP_DEPEND_INOUT;
              else if (gfc_match ("in") == MATCH_YES)
                depend_op = OMP_DEPEND_IN;
@@ -3805,7 +3807,9 @@ gfc_match_omp_depobj (void)
   if (gfc_match ("update ( ") == MATCH_YES)
     {
       c = gfc_get_omp_clauses ();
-      if (gfc_match ("inout )") == MATCH_YES)
+      if (gfc_match ("inoutset )") == MATCH_YES)
+       c->depobj_update = OMP_DEPEND_INOUTSET;
+      else if (gfc_match ("inout )") == MATCH_YES)
        c->depobj_update = OMP_DEPEND_INOUT;
       else if (gfc_match ("in )") == MATCH_YES)
        c->depobj_update = OMP_DEPEND_IN;
@@ -3815,8 +3819,8 @@ gfc_match_omp_depobj (void)
        c->depobj_update = OMP_DEPEND_MUTEXINOUTSET;
       else
        {
-         gfc_error ("Expected IN, OUT, INOUT, MUTEXINOUTSET followed by "
-                    "%<)%> at %C");
+         gfc_error ("Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET "
+                    "followed by %<)%> at %C");
          goto error;
        }
     }
index 7633aee755c4059d19f4e63bbfca1b1eb9d7b20b..e1907a46d5a55a0445b7c15a8de91c68115ff6d7 100644 (file)
@@ -2937,6 +2937,9 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
                  case OMP_DEPEND_INOUT:
                    OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_INOUT;
                    break;
+                 case OMP_DEPEND_INOUTSET:
+                   OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_INOUTSET;
+                   break;
                  case OMP_DEPEND_MUTEXINOUTSET:
                    OMP_CLAUSE_DEPEND_KIND (node)
                      = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
@@ -5593,6 +5596,7 @@ gfc_trans_omp_depobj (gfc_code *code)
       case OMP_DEPEND_IN: k = GOMP_DEPEND_IN; break;
       case OMP_DEPEND_OUT: k = GOMP_DEPEND_OUT; break;
       case OMP_DEPEND_INOUT: k = GOMP_DEPEND_INOUT; break;
+      case OMP_DEPEND_INOUTSET: k = GOMP_DEPEND_INOUTSET; break;
       case OMP_DEPEND_MUTEXINOUTSET: k = GOMP_DEPEND_MUTEXINOUTSET; break;
       default: gcc_unreachable ();
       }
index 6d56473b1f391781590d98b0e814e96a98c0334d..f8f34f0c887b94e13abf5f2fe74724509797c53b 100644 (file)
@@ -44,6 +44,9 @@ subroutine f6
   !$omp target depend(mutexinoutset : omp_all_memory )  ! { dg-error "'omp_all_memory' used with DEPEND kind other than OUT or INOUT" }
   ! !$omp end target
 
+  !$omp target depend(inoutset : omp_all_memory )  ! { dg-error "'omp_all_memory' used with DEPEND kind other than OUT or INOUT" }
+  ! !$omp end target
+
   !$omp target depend ( depobj : omp_all_memory)  ! { dg-error "'omp_all_memory' used with DEPEND kind other than OUT or INOUT" }
   !!$omp end target
 
index f7ee34fedc8ebecc3242e955bb819ba4e8c8f31e..e7d51bef885f5ee8f63549507f011c6cab0b9d1b 100644 (file)
@@ -45,6 +45,9 @@ subroutine f6
   !$omp target depend(mutexinoutset : omp_all_memory )
   ! !$omp end target
 
+  !$omp target depend(inoutset : omp_all_memory )
+  ! !$omp end target
+
  !$omp target depend ( depobj : omp_all_memory)
  !$omp end target
 
index 66cfb61060ffa0195f3096293c87ee9a0e0e954e..73734bbb07ea7a84b8f7689332ca24a20d5c2dfc 100644 (file)
@@ -22,4 +22,7 @@ subroutine f1
   !$omp task depend(mutexinoutset: a)
   !$omp end task
   !$omp depobj(depobj2) destroy
+  !$omp depobj(depobj1) depend(inoutset: a)
+  !$omp depobj(depobj1) update(mutexinoutset)
+  !$omp depobj(depobj1) update(inoutset)
 end subroutine f1
index 3ffd3d5d01ba218bed177fc95f2969acaff2895f..cb67c3ce9d1b8f266d940618377ef76466def961 100644 (file)
@@ -23,9 +23,9 @@ subroutine f1
   !$omp depobj(depobj) depend(mutexinoutset : a)     ! OK
   !$omp depobj(depobj) depend(source)                ! { dg-error "DEPEND clause at .1. of OMP DEPOBJ construct shall not have dependence-type SOURCE, SINK or DEPOBJ" }
   !$omp depobj(depobj) depend(sink : i + 1)          ! { dg-error "DEPEND clause at .1. of OMP DEPOBJ construct shall not have dependence-type SOURCE, SINK or DEPOBJ" }
-  !$omp depobj(depobj) update(source)                ! { dg-error "Expected IN, OUT, INOUT, MUTEXINOUTSET followed by '\\)'" }
-  !$omp depobj(depobj) update(sink)                  ! { dg-error "Expected IN, OUT, INOUT, MUTEXINOUTSET followed by '\\)'" }
-  !$omp depobj(depobj) update(depobj)                ! { dg-error "Expected IN, OUT, INOUT, MUTEXINOUTSET followed by '\\)'" }
+  !$omp depobj(depobj) update(source)                ! { dg-error "Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET followed by '\\)'" }
+  !$omp depobj(depobj) update(sink)                  ! { dg-error "Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET followed by '\\)'" }
+  !$omp depobj(depobj) update(depobj)                ! { dg-error "Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET followed by '\\)'" }
 
   ! Valid in OpenMP 5.1:
   !$omp depobj(depobj5) depend(depobj: depobj3)      ! { dg-error "DEPEND clause at .1. of OMP DEPOBJ construct shall not have dependence-type SOURCE, SINK or DEPOBJ" }
index 9f40bae1247a39f3aa5b43a59b3390ef15ae8138..c9d01cd8a5c5d7e0d024a9ec55a77a951991b571 100644 (file)
@@ -306,7 +306,7 @@ The OpenMP 4.5 specification is fully supported.
 @item @code{nowait} clause in @code{taskwait} directive @tab N @tab
 @item Extensions to the @code{atomic} directive @tab Y @tab
 @item @code{seq_cst} clause on a @code{flush} construct @tab Y @tab
-@item @code{inoutset} argument to the @code{depend} clause @tab N @tab
+@item @code{inoutset} argument to the @code{depend} clause @tab Y @tab
 @item @code{private} and @code{firstprivate} argument to @code{default}
       clause in C and C++ @tab Y @tab
 @item @code{present} argument to @code{defaultmap} clause @tab N @tab
@@ -4279,7 +4279,7 @@ The following sections present notes on the offload-target specifics.
       @code{i586}, @code{i686}, @code{ia32}
       @tab @code{host}
       @tab See @code{-m...} flags in ``x86 Options'' (without @code{-m})
-@item @code{amdgcn} @code{gcn}
+@item @code{amdgcn}, @code{gcn}
       @tab @code{gpu}
       @tab See @code{-march=} in ``AMD GCN Options''
 @item @code{nvptx}
index a350e793623bb5ce240b74748a59552e8334689e..b812b6dab53f46087eced9ba003212349a6da9ab 100644 (file)
@@ -59,6 +59,12 @@ subroutine test (ifval)
       call usleep (5000)
       b(4) = 48
     end block
+    !$omp task shared(b) depend(inoutset: b(5))
+    block
+      call usleep (5000)
+      b(5) = 49
+    end block
+
     ! None of the above tasks depend on each other.
     ! The following task depends on all but the a(4) = 46; one.
     !$omp task shared(a, b) depend(out: omp_all_memory) private(i) if(ifval)
@@ -66,7 +72,7 @@ subroutine test (ifval)
       if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45       &
           .or. a(5) /= 5 .or. a(6) /= 6 .or. a(7) /= 7                     &
           .or. b(0) /= 47 .or. b(1) /= 2 .or. b(2) /= 4 .or. b(3) /= 6     &
-          .or. b(4) /= 48 .or. b(5) /= 10 .or. b(6) /= 12 .or. b(7) /= 14) &
+          .or. b(4) /= 48 .or. b(5) /= 49 .or. b(6) /= 12 .or. b(7) /= 14) &
         error stop
       do i = 0, 7
         if (i /= 4) &
index edea8571bba0d840f69a8598be0291dc59b543f7..b5032e98a2f5761e1e6de10c40b77d3cfc8b16c7 100644 (file)
@@ -62,6 +62,12 @@ subroutine test (ifval)
       call usleep (5000)
       b(4) = 48
     end block
+    !$omp task shared(b) depend(inoutset: b(5))
+    block
+      call usleep (5000)
+      b(5) = 49
+    end block
+
     ! None of the above tasks depend on each other.
     ! The following task depends on all but the a(4) = 46; one.
     !$omp task shared(a, b) depend(depobj: d1) private(i) if(ifval)
@@ -69,7 +75,7 @@ subroutine test (ifval)
       if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45       &
           .or. a(5) /= 5 .or. a(6) /= 6 .or. a(7) /= 7                     &
           .or. b(0) /= 47 .or. b(1) /= 2 .or. b(2) /= 4 .or. b(3) /= 6     &
-          .or. b(4) /= 48 .or. b(5) /= 10 .or. b(6) /= 12 .or. b(7) /= 14) &
+          .or. b(4) /= 48 .or. b(5) /= 49 .or. b(6) /= 12 .or. b(7) /= 14) &
         error stop
       do i = 0, 7
         if (i /= 4) &
index d3f3988f0da4ed0458a59e47d446beb48684a4b8..771a59c50f032a317431abecc2065c1b075c04d9 100644 (file)
@@ -57,6 +57,12 @@ program main
       call usleep (5000)
       b(4) = 48
     end block
+    !$omp task shared(b) depend(inoutset: b(5))
+    block
+      call usleep (5000)
+      b(5) = 49
+    end block
+
     ! None of the above tasks depend on each other.
     ! The following task depends on all but the a(4) = 46; one.
     !$omp task shared(a, b) depend(iterator (j=0:7), inout: omp_all_memory) private(i)
@@ -64,7 +70,7 @@ program main
       if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45       &
           .or. a(5) /= 5 .or. a(6) /= 6 .or. a(7) /= 7                     &
           .or. b(0) /= 47 .or. b(1) /= 2 .or. b(2) /= 4 .or. b(3) /= 6     &
-          .or. b(4) /= 48 .or. b(5) /= 10 .or. b(6) /= 12 .or. b(7) /= 14) &
+          .or. b(4) /= 48 .or. b(5) /= 49 .or. b(6) /= 12 .or. b(7) /= 14) &
         error stop
       do i = 0, 7
         if (i /= 4) &
diff --git a/libgomp/testsuite/libgomp.fortran/depend-inoutset-1.f90 b/libgomp/testsuite/libgomp.fortran/depend-inoutset-1.f90
new file mode 100644 (file)
index 0000000..46161c3
--- /dev/null
@@ -0,0 +1,170 @@
+! { dg-additional-sources my-usleep.c }
+! { dg-prune-output "command-line option '-fintrinsic-modules-path=.*' is valid for Fortran but not for C" }
+
+program main
+  use omp_lib
+  implicit none (type, external)
+
+  interface
+    subroutine usleep(t) bind(C, name="my_usleep")
+      use iso_c_binding
+      integer(c_int), value :: t
+    end subroutine
+  end interface
+
+  integer :: a(0:7) = 0
+  integer(omp_depend_kind) :: d1, d2
+
+  !$omp depobj (d1) depend(inoutset: a)
+  !$omp depobj (d2) depend(inout: a)
+  !$omp depobj (d2) update(inoutset)
+
+  !$omp parallel
+   !$omp barrier
+   !$omp master
+    !$omp task shared(a) depend(out: a)
+    block
+      call usleep (5000)
+      a(0) = 1; a(1) = 2; a(2) = 3; a(3) = 4
+    end block
+    ! The above task needs to finish first.
+    !$omp task shared(a) depend(in: a)
+    block
+      if (a(0) /= 1 .or. a(1) /= 2 .or. a(2) /= 3 .or. a(3) /= 4) &
+        error stop
+      call usleep (5000)
+      a(4) = 42
+    end block
+    !$omp task shared(a) depend(in: a)
+    block
+      if (a(0) /= 1 .or. a(1) /= 2 .or. a(2) /= 3 .or. a(3) /= 4) &
+        error stop
+      call usleep (5000);
+      a(5) = 43
+    end block
+    !$omp task shared(a) depend(in: a)
+    block
+      if (a(0) /= 1 .or. a(1) /= 2 .or. a(2) /= 3 .or. a(3) /= 4) &
+        error stop
+      call usleep (5000)
+      a(6) = 44
+    end block
+    !$omp task shared(a) depend(in: a)
+    block
+      if (a(0) /= 1 .or. a(1) /= 2 .or. a(2) /= 3 .or. a(3) /= 4) &
+        error stop
+      call usleep (5000)
+      a(7) = 45
+    end block
+    ! The above 4 tasks can be scheduled in any order but need to wait
+    ! for the depend(out: a) task.
+    !$omp task shared(a) depend(inoutset: a)
+    block
+      if (a(4) /= 42 .or. a(5) /= 43 .or. a(6) /= 44 .or. a(7) /= 45) &
+        error stop
+      call usleep (5000)
+      a(0) = 42
+    end block
+    !$omp task shared(a) depend(iterator(i=1:3:2), inoutset: a)
+    block
+      if (a(4) /= 42 .or. a(5) /= 43 .or. a(6) /= 44 .or. a(7) /= 45) &
+        error stop
+      call usleep (5000)
+      a(1) = 43
+    end block
+    !$omp task shared(a) depend(depobj: d1)
+    block
+      if (a(4) /= 42 .or. a(5) /= 43 .or. a(6) /= 44 .or. a(7) /= 45) &
+        error stop
+      call usleep (5000)
+      a(2) = 44
+    end block
+    !$omp task shared(a) depend(depobj: d2)
+    block
+      if (a(4) /= 42 .or. a(5) /= 43 .or. a(6) /= 44 .or. a(7) /= 45) &
+        error stop
+      call usleep (5000)
+      a(3) = 45
+    end block
+    ! The above 4 tasks can be scheduled in any order but need to wait
+    ! for all the above depend(in: a) tasks.
+    !$omp task shared(a) depend(in: a)
+    block
+      if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45) &
+        error stop
+      call usleep (5000)
+      a(4) = 46
+    end block
+    !$omp task shared(a) depend(in: a)
+    block
+      if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45) &
+        error stop
+      call usleep (5000)
+      a(5) = 47
+    end block
+    !$omp task shared(a) depend(in: a)
+    block
+      if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45) &
+        error stop
+      call usleep (5000)
+      a(6) = 48
+    end block
+    !$omp task shared(a) depend(in: a)
+    block
+      if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45) &
+        error stop
+      call usleep (5000)
+      a(7) = 49
+    end block
+    ! The above 4 tasks can be scheduled in any order but need to wait
+    ! for all the above depend(inoutset: a),
+    !  depend(iterator(i=1:3:2), inoutset: a), depend(depobj: d1) and
+    !  depend(depobj: d2) tasks.
+    !$omp task shared(a) depend(inoutset: a)
+    block
+      if (a(4) /= 46.or. a(5) /= 47 .or. a(6) /= 48 .or. a(7) /= 49) &
+        error stop
+      call usleep (5000)
+      a(0) = 50
+    end block
+    ! The above task needs to wait for all the above 4 depend(in: a)
+    ! tasks.
+    !$omp task shared(a) depend(out: a)
+    block
+      if (a(0) /= 50 .or. a(4) /= 46.or. a(5) /= 47 .or. a(6) /= 48 .or. a(7) /= 49) &
+        error stop
+      call usleep (5000)
+      a(0) = 51
+    end block
+    ! The above task needs to wait for the above depend(inoutset: a) task.
+    !$omp task shared(a) depend(inoutset: a)
+    block
+      if (a(0) /= 51 .or. a(4) /= 46.or. a(5) /= 47 .or. a(6) /= 48 .or. a(7) /= 49) &
+        error stop
+      call usleep (5000)
+      a(0) = 52
+    end block
+    ! The above task needs to wait for the above depend(out: a) task.
+    !$omp task shared(a) depend(mutexinoutset: a)
+    block
+      if (a(0) /= 52 .or. a(4) /= 46.or. a(5) /= 47 .or. a(6) /= 48 .or. a(7) /= 49) &
+        error stop
+      call usleep (5000)
+      a(0) = 53
+    end block
+    ! The above task needs to wait for the above depend(inoutset: a) task.
+    !$omp task shared(a) depend(inoutset: a)
+    block
+      if (a(0) /= 53 .or. a(4) /= 46.or. a(5) /= 47 .or. a(6) /= 48 .or. a(7) /= 49) &
+        error stop
+      call usleep (5000)
+      a(0) = 54
+    end block
+    ! The above task needs to wait for the above
+    ! depend(mutexinoutset: a) task.
+   !$omp end master
+  !$omp end parallel
+  if (a(0) /= 54 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45 &
+      .or. a(4) /= 46.or. a(5) /= 47 .or. a(6) /= 48 .or. a(7) /= 49) &
+    error stop
+end