Hi!

This patch adds parsing of mutexinoutset depend kind, which is similar to
out/inout, except that there is no ordering between the tasks with
mutexinoutset dependencies, just requirement of mutual exclusivity.
For now the patch implements it like out/inout, which is valid (because
mutexinoutset is essentially a relaxed out/inout), but undesirable for
performance.

Will need to do something on the libgomp/task.c side to improve this.

2018-05-07  Jakub Jelinek  <ja...@redhat.com>

        * tree-core.h (enum omp_clause_depend_kind): Add
        OMP_CLAUSE_DEPEND_MUTEXINOUTSET.
        * omp-low.c (lower_depend_clauses): For now handle
        OMP_CLAUSE_DEPEND_MUTEXINOUTSET like OMP_CLAUSE_DEPEND_OUT.
        * tree-pretty-print.c (dump_omp_clause): Handle
        OMP_CLAUSE_DEPEND_MUTEXINOUTSET.

        * c-parser.c (c_parser_omp_clause_depend): Parse mutexinoutset kind.

        * parser.c (cp_parser_omp_clause_depend): Parse mutexinoutset kind.

        * testsuite/libgomp.c-c++-common/depend-mutexinout-1.c: New test.
        * testsuite/libgomp.c-c++-common/depend-mutexinout-2.c: New test.

--- gcc/tree-core.h.jj  2018-05-04 15:13:22.384614499 +0200
+++ gcc/tree-core.h     2018-05-07 14:47:37.710983431 +0200
@@ -1408,6 +1408,7 @@ enum omp_clause_depend_kind
   OMP_CLAUSE_DEPEND_IN,
   OMP_CLAUSE_DEPEND_OUT,
   OMP_CLAUSE_DEPEND_INOUT,
+  OMP_CLAUSE_DEPEND_MUTEXINOUTSET,
   OMP_CLAUSE_DEPEND_SOURCE,
   OMP_CLAUSE_DEPEND_SINK,
   OMP_CLAUSE_DEPEND_LAST
--- gcc/omp-low.c.jj    2018-05-04 19:08:55.309273302 +0200
+++ gcc/omp-low.c       2018-05-07 14:49:25.989113885 +0200
@@ -7351,6 +7351,7 @@ lower_depend_clauses (tree *pclauses, gi
          break;
        case OMP_CLAUSE_DEPEND_OUT:
        case OMP_CLAUSE_DEPEND_INOUT:
+       case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
          n_out++;
          break;
        case OMP_CLAUSE_DEPEND_SOURCE:
--- gcc/tree-pretty-print.c.jj  2018-05-04 20:28:35.808700817 +0200
+++ gcc/tree-pretty-print.c     2018-05-07 14:48:58.490080754 +0200
@@ -658,6 +658,9 @@ dump_omp_clause (pretty_printer *pp, tre
        case OMP_CLAUSE_DEPEND_INOUT:
          pp_string (pp, "inout");
          break;
+       case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
+         pp_string (pp, "mutexinoutset");
+         break;
        case OMP_CLAUSE_DEPEND_SOURCE:
          pp_string (pp, "source)");
          return;
--- gcc/c/c-parser.c.jj 2018-05-04 20:28:36.220701129 +0200
+++ gcc/c/c-parser.c    2018-05-07 14:53:05.722338632 +0200
@@ -13822,6 +13822,8 @@ c_parser_omp_clause_depend (c_parser *pa
        kind = OMP_CLAUSE_DEPEND_IN;
       else if (strcmp ("inout", p) == 0)
        kind = OMP_CLAUSE_DEPEND_INOUT;
+      else if (strcmp ("mutexinoutset", p) == 0)
+       kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
       else if (strcmp ("out", p) == 0)
        kind = OMP_CLAUSE_DEPEND_OUT;
       else if (strcmp ("source", p) == 0)
--- gcc/cp/parser.c.jj  2018-05-04 19:28:11.231064426 +0200
+++ gcc/cp/parser.c     2018-05-07 14:52:36.717319042 +0200
@@ -33541,6 +33541,8 @@ cp_parser_omp_clause_depend (cp_parser *
        kind = OMP_CLAUSE_DEPEND_IN;
       else if (strcmp ("inout", p) == 0)
        kind = OMP_CLAUSE_DEPEND_INOUT;
+      else if (strcmp ("mutexinoutset", p) == 0)
+       kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
       else if (strcmp ("out", p) == 0)
        kind = OMP_CLAUSE_DEPEND_OUT;
       else if (strcmp ("source", p) == 0)
--- libgomp/testsuite/libgomp.c-c++-common/depend-mutexinout-1.c.jj     
2018-05-07 15:39:16.499253498 +0200
+++ libgomp/testsuite/libgomp.c-c++-common/depend-mutexinout-1.c        
2018-05-07 16:17:21.068853111 +0200
@@ -0,0 +1,28 @@
+int
+main ()
+{
+  int a, b, c, d;
+  #pragma omp parallel num_threads (6)
+  #pragma omp single
+  {
+    #pragma omp task depend(out: c)
+      c = 1;
+    #pragma omp task depend(out: a)
+      a = 2;
+    #pragma omp task depend(out: b)
+      b = 3;
+    /* The above 3 tasks can be scheduled in any order.  */
+    #pragma omp task depend(in: a) depend(mutexinoutset: c)
+      c += a;
+    #pragma omp task depend(in: b) depend(mutexinoutset: c)
+      c += b;
+    /* The above 2 tasks are mutually exclusive and need to wait
+       for the first and second or first and third tasks respectively.  */
+    #pragma omp task depend(in: c)
+      d = c;
+    /* The above task needs to wait for the mutexinoutset tasks.  */
+  }
+  if (d != 6)
+    __builtin_abort ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c-c++-common/depend-mutexinout-2.c.jj     
2018-05-07 16:03:55.085289182 +0200
+++ libgomp/testsuite/libgomp.c-c++-common/depend-mutexinout-2.c        
2018-05-07 16:16:27.632815556 +0200
@@ -0,0 +1,59 @@
+int
+main ()
+{
+  int a, b, c = 0;
+  #pragma omp parallel num_threads(2)
+  {
+    #pragma omp barrier
+    #pragma omp single
+    {
+      #pragma omp task depend(out: a)
+      {
+       int i;
+       a = 0;
+       for (i = 0; i < 524288; ++i)
+         {
+           asm volatile ("" : "+g" (a));
+           a++;
+         }
+      }
+      #pragma omp task depend(out: b)
+      {
+       int i;
+       b = 0;
+       for (i = 0; i < 64; ++i)
+         {
+           asm volatile ("" : "+g" (b));
+           b++;
+         }
+      }
+      #pragma omp task depend(in: a) depend(mutexinoutset: c)
+      {
+       int i;
+       int d = c;
+       for (i = 0; i < 524288 + 64 - a; ++i)
+         {
+           asm volatile ("" : "+g" (d) : "g" (&a) : "memory");
+           d++;
+         }
+       asm volatile ("" : "+g" (d), "+g" (c));
+       c = d;
+      }
+      #pragma omp task depend(in: b) depend(mutexinoutset: c)
+      {
+       int i;
+       int d = c;
+       for (i = 0; i < 524288 + 64 - b; ++i)
+         {
+           asm volatile ("" : "+g" (d) : "g" (&b) : "memory");
+           d++;
+         }
+       asm volatile ("" : "+g" (d), "+g" (c));
+       c = d;
+      }
+    }
+  }
+  if (c != 524288 + 64)
+    __builtin_abort ();
+  return 0;
+}

        Jakub

Reply via email to