]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Add support for firstprivate and allocate clauses on scope construct
authorJakub Jelinek <jakub@redhat.com>
Tue, 5 Jul 2022 08:01:09 +0000 (10:01 +0200)
committerTobias Burnus <tobias@codesourcery.com>
Tue, 5 Jul 2022 08:01:20 +0000 (10:01 +0200)
OpenMP 5.2 adds support for firstprivate and allocate clauses on the scope
construct and this patch adds that support to GCC.
5.2 unfortunately (IMNSHO mistakenly) marked scope construct as worksharing,
which implies that it isn't possible to nest inside of it other scope,
worksharing loop, sections, explicit barriers, single etc. which would
make scope far less useful.  I'm not implementing that part, keeping the
5.1 behavior here, and will file an issue to revert that for OpenMP 6.0.
But, for firstprivate it keeps the restriction that is now implied from
worksharing construct that listed var can't be private in outer context,
where for reduction 5.1 had similar restriction explicit even for scope
and 5.2 has it implicitly through worksharing construct.

2022-05-31  Jakub Jelinek  <jakub@redhat.com>

gcc/
* omp-low.cc (build_outer_var_ref): For code == OMP_CLAUSE_ALLOCATE
allow var to be private in the outer context.
(lower_private_allocate): Pass OMP_CLAUSE_ALLOCATE as last argument
to build_outer_var_ref.
gcc/c/
* c-parser.cc (OMP_SCOPE_CLAUSE_MASK): Add firstprivate and allocate
clauses.
gcc/cp/
* parser.cc (OMP_SCOPE_CLAUSE_MASK): Add firstprivate and allocate
clauses.
gcc/testsuite/
* c-c++-common/gomp/scope-5.c: New test.
* c-c++-common/gomp/scope-6.c: New test.
* g++.dg/gomp/attrs-1.C (bar): Add firstprivate and allocate clauses
to scope construct.
* g++.dg/gomp/attrs-2.C (bar): Likewise.
libgomp/
* testsuite/libgomp.c-c++-common/allocate-1.c (foo): Add testcase for
scope construct with allocate clause.
* testsuite/libgomp.c-c++-common/allocate-3.c (foo): Likewise.
* testsuite/libgomp.c-c++-common/scope-2.c: New test.

(cherry picked from commit f38b20d68fade5a922b9f68c4c3841e653d1b83c)

15 files changed:
gcc/ChangeLog.omp
gcc/c/ChangeLog.omp
gcc/c/c-parser.cc
gcc/cp/ChangeLog.omp
gcc/cp/parser.cc
gcc/omp-low.cc
gcc/testsuite/ChangeLog.omp
gcc/testsuite/c-c++-common/gomp/scope-5.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/gomp/scope-6.c [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/attrs-1.C
gcc/testsuite/g++.dg/gomp/attrs-2.C
libgomp/ChangeLog.omp
libgomp/testsuite/libgomp.c-c++-common/allocate-1.c
libgomp/testsuite/libgomp.c-c++-common/allocate-3.c
libgomp/testsuite/libgomp.c-c++-common/scope-2.c [new file with mode: 0644]

index 21bfd6c79a377a035d1c68bd7c984d923bbb0d1e..085f67a30fbcab66d650be47a1b34a8e7d725e32 100644 (file)
@@ -1,3 +1,13 @@
+2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-05-31  Jakub Jelinek  <jakub@redhat.com>
+
+       * omp-low.cc (build_outer_var_ref): For code == OMP_CLAUSE_ALLOCATE
+       allow var to be private in the outer context.
+       (lower_private_allocate): Pass OMP_CLAUSE_ALLOCATE as last argument
+       to build_outer_var_ref.
+
 2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
index 667e2b4bcac50d9d53fb7ef4e55fe846ecc55362..10499527eb7cefefbadb9fcf31bdbad7913fc2cd 100644 (file)
@@ -1,3 +1,11 @@
+2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-05-31  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-parser.cc (OMP_SCOPE_CLAUSE_MASK): Add firstprivate and allocate
+       clauses.
+
 2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
index b01ebdb3cda9c4b5e473096e33afb0f851c979b2..a6a576930c16fd097c91dcb4ced70358bbf92ffe 100644 (file)
@@ -20659,7 +20659,9 @@ c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
 
 #define OMP_SCOPE_CLAUSE_MASK                                  \
        ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)      \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)    \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)     \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
 
 static tree
index 453d3e1ffb9eebcb7f24438a2028daf568be4d62..bd4a83a376d168a42f4984786462d9ecc0756281 100644 (file)
@@ -1,3 +1,11 @@
+2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-05-31  Jakub Jelinek  <jakub@redhat.com>
+
+       * parser.cc (OMP_SCOPE_CLAUSE_MASK): Add firstprivate and allocate
+       clauses.
+
 2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
index 7389cbe9fdfc25b7774d8e917a7875e7ba9dedbf..5620cf626d19d4315ce052f375c9de9e832d6c07 100644 (file)
@@ -43857,7 +43857,9 @@ cp_parser_omp_single (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
 
 #define OMP_SCOPE_CLAUSE_MASK                                  \
        ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)      \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)    \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)     \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
 
 static tree
index 22a854bc1e5f44d69a1d3a741ca2debb3576d188..90a67810a893d7a57074cdcb96b1c399aed5bb04 100644 (file)
@@ -730,6 +730,7 @@ build_outer_var_ref (tree var, omp_context *ctx,
   else if ((gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
            && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
           || ctx->loop_p
+          || code == OMP_CLAUSE_ALLOCATE
           || (code == OMP_CLAUSE_PRIVATE
               && (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
                   || gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS
@@ -5367,7 +5368,7 @@ lower_private_allocate (tree var, tree new_var, tree &allocator,
       if (is_task_ctx (ctx))
        allocator = build_receiver_ref (allocator, false, ctx);
       else
-       allocator = build_outer_var_ref (allocator, ctx);
+       allocator = build_outer_var_ref (allocator, ctx, OMP_CLAUSE_ALLOCATE);
     }
   allocator = fold_convert (pointer_sized_int_node, allocator);
   if (TREE_CODE (allocator) != INTEGER_CST)
index 158b9bfa63b02bc7a52c09a141333f1c79f66717..db614a4e89920ef5eee8d0f2ac95db9a23f353d0 100644 (file)
@@ -1,3 +1,14 @@
+2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-05-31  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-c++-common/gomp/scope-5.c: New test.
+       * c-c++-common/gomp/scope-6.c: New test.
+       * g++.dg/gomp/attrs-1.C (bar): Add firstprivate and allocate clauses
+       to scope construct.
+       * g++.dg/gomp/attrs-2.C (bar): Likewise.
+
 2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
diff --git a/gcc/testsuite/c-c++-common/gomp/scope-5.c b/gcc/testsuite/c-c++-common/gomp/scope-5.c
new file mode 100644 (file)
index 0000000..6cd4a80
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+void
+foo ()
+{
+  int f = 0;
+  #pragma omp scope firstprivate(f)    /* { dg-error "firstprivate variable 'f' is private in outer context" } */
+  f++;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/scope-6.c b/gcc/testsuite/c-c++-common/gomp/scope-6.c
new file mode 100644 (file)
index 0000000..760dd71
--- /dev/null
@@ -0,0 +1,31 @@
+typedef enum omp_allocator_handle_t
+#if __cplusplus >= 201103L
+: __UINTPTR_TYPE__
+#endif
+{
+  omp_null_allocator = 0,
+  omp_default_mem_alloc = 1,
+  omp_large_cap_mem_alloc = 2,
+  omp_const_mem_alloc = 3,
+  omp_high_bw_mem_alloc = 4,
+  omp_low_lat_mem_alloc = 5,
+  omp_cgroup_mem_alloc = 6,
+  omp_pteam_mem_alloc = 7,
+  omp_thread_mem_alloc = 8,
+  __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+int a = 0, b = 42, c = 0;
+
+void
+foo (omp_allocator_handle_t h)
+{
+  #pragma omp scope private (a) private (b) reduction (+: c) allocate (allocator (h): a, b, c)
+  {
+    if (b != 42)
+      __builtin_abort ();
+    a = 36;
+    b = 15;
+    c++;
+  }
+}
index f64b078db4000bd1c9d9575e55ff4ab714b0df89..3f366aee58101cf8a371f3f6e587b0ccbe90280e 100644 (file)
@@ -593,9 +593,11 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int hda, int s,
       [[omp::directive (cancellation point parallel)]];
     }
   }
-  [[omp::directive (scope private (p) reduction(+:r) nowait)]]
+  [[omp::directive (scope private (p) firstprivate (f) reduction(+:r) nowait
+    allocate (omp_default_mem_alloc: r))]]
     ;
-  [[omp::directive (scope private (p) reduction(task, +:r))]]
+  [[omp::directive (scope private (p) firstprivate (f) reduction(task, +:r)
+    allocate (omp_default_mem_alloc: f))]]
     ;
   extern int t2;
   [[omp::directive (threadprivate (t2))]];
index cc91fa2830714c9d66e2433f2c41a5e6aef9a528..cb80415a4f8a6c00e50ea0a5691d568eb063dfac 100644 (file)
@@ -593,9 +593,11 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int hda, int s,
       [[omp::directive (cancellation point, parallel)]];
     }
   }
-  [[omp::directive (scope, private (p), reduction(+:r), nowait)]]
+  [[omp::directive (scope, private (p), firstprivate (f), reduction(+:r), nowait,
+    allocate(omp_default_mem_alloc: r))]]
     ;
-  [[using omp:directive (scope, private (p), reduction(task, +:r))]]
+  [[using omp:directive (scope, private (p), firstprivate (f), reduction(task, +:r),
+    allocate (omp_default_mem_alloc: f))]]
     ;
   extern int t2;
   [[omp::directive (threadprivate (t2))]];
index e52f7696701a5202b2a9d4f8c15c21762bf7b6a6..37780a713a4db5f43509b408a31e32e4cfbc786a 100644 (file)
@@ -1,3 +1,13 @@
+2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-05-31  Jakub Jelinek  <jakub@redhat.com>
+
+       * testsuite/libgomp.c-c++-common/allocate-1.c (foo): Add testcase for
+       scope construct with allocate clause.
+       * testsuite/libgomp.c-c++-common/allocate-3.c (foo): Likewise.
+       * testsuite/libgomp.c-c++-common/scope-2.c: New test.
+
 2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
index 4398ff957ef0e805d2af307f4255ceae01849018..d3af3b8170e4864e20542648a410cceb87df7189 100644 (file)
@@ -11,7 +11,7 @@ foo (int x, int *p, int *q, int px, omp_allocator_handle_t h, int fl)
   int i2, j2, n2 = 9, l4;
   int i3, j3, n3 = 10, l5;
   int i4, j4, n4 = 11, l6;
-  int i5;
+  int i5, n5;
   int v[x], w[x];
   int r2[4] = { 0, 0, 0, 0 };
   int xo = x;
@@ -214,6 +214,34 @@ foo (int x, int *p, int *q, int px, omp_allocator_handle_t h, int fl)
       || q[0] != 3 * (32 * 31) / 2 || q[2] != 4 * (32 * 31) / 2
       || r2[0] != 5 * (32 * 31) / 2 || r2[3] != 6 * (32 * 31) / 2)
     abort ();
+  r = 0;
+  x = xo;
+  #pragma omp parallel shared (x, y, r, n5) firstprivate (h)
+  {
+    #pragma omp masked
+    n5 = omp_get_num_threads ();
+    #pragma omp scope private (y) firstprivate (x) reduction(+:r) \
+                     allocate (h: x, y, r)
+    {
+      int *volatile p1 = &x;
+      int *volatile p2 = &y;
+      int *volatile p3 = &r;
+      if (x != 42)
+       abort ();
+      #pragma omp barrier
+      *p2 = 1;
+      p1[0]++;
+      p3[0]++;
+      #pragma omp barrier
+      if (x != 43 || y != 1 || r != 1)
+       abort ();
+      if ((fl & 1) && (((uintptr_t) p1 | (uintptr_t) p2
+                       | (uintptr_t) p3) & 63) != 0)
+       abort ();
+    }
+  }
+  if (x != 42 || r != n5)
+    abort ();
 }
 
 void
index ce1a045a4079540f0fef75607cecfc5decdff50b..0b507448e2926e67749d8454d280aa2174aceb6b 100644 (file)
@@ -11,7 +11,7 @@ foo (int x, int *p, int *q, int px, omp_allocator_handle_t h, int fl)
   int i2, j2, n2 = 9, l4;
   int i3, j3, n3 = 10, l5;
   int i4, j4, n4 = 11, l6;
-  int i5;
+  int i5, n5;
   int v[x], w[x];
   int r2[4] = { 0, 0, 0, 0 };
   int xo = x;
@@ -244,6 +244,39 @@ foo (int x, int *p, int *q, int px, omp_allocator_handle_t h, int fl)
       || q[0] != 3 * (32 * 31) / 2 || q[2] != 4 * (32 * 31) / 2
       || r2[0] != 5 * (32 * 31) / 2 || r2[3] != 6 * (32 * 31) / 2)
     abort ();
+  r = 0;
+  x = xo;
+  #pragma omp parallel shared (x, y, r, n5) firstprivate (h)
+  {
+    #pragma omp masked
+    n5 = omp_get_num_threads ();
+    #pragma omp scope private (y) firstprivate (x) reduction(+:r) \
+                     allocate (allocator (h), align (32): x) \
+                     allocate (align (128), allocator (h): y) \
+                     allocate (align (32), allocator (h): r)
+    {
+      int *volatile p1 = &x;
+      int *volatile p2 = &y;
+      if (x != 42)
+       abort ();
+      #pragma omp barrier
+      *p2 = 1;
+      p1[0]++;
+      r++;
+      #pragma omp barrier
+      if (x != 43 || y != 1 || r != 1)
+       abort ();
+      if ((fl & 1) && (((uintptr_t) p1 | (uintptr_t) p2
+                       | (uintptr_t) &r) & 63) != 0)
+       abort ();
+      if ((((uintptr_t) p1 | (uintptr_t) &r) & 31) != 0)
+       abort ();
+      if ((((uintptr_t) p2) & 127) != 0)
+       abort ();
+    }
+  }
+  if (x != 42 || r != n5)
+    abort ();
 }
 
 void
diff --git a/libgomp/testsuite/libgomp.c-c++-common/scope-2.c b/libgomp/testsuite/libgomp.c-c++-common/scope-2.c
new file mode 100644 (file)
index 0000000..2d67102
--- /dev/null
@@ -0,0 +1,54 @@
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort ();
+
+int
+main ()
+{
+  int a[64] = {};
+  int r = 0, r2 = 0, i, n = 64;
+  #pragma omp parallel
+  {
+    #pragma omp scope nowait
+    #pragma omp scope nowait firstprivate (n)
+    #pragma omp for
+    for (i = 0; i < 64; i++)
+      a[i] += 1;
+    #pragma omp scope reduction(+: r) nowait firstprivate (n)
+    {
+      #pragma omp for nowait
+      for (i = 0; i < 64; i++)
+       {
+         r += i;
+         if (a[i] != 1)
+           abort ();
+       }
+      #pragma omp barrier
+      if (n != 64)
+       abort ();
+      else
+       n = 128;
+    }
+    #pragma omp barrier
+    if (r != 64 * 63 / 2)
+      abort ();
+    #pragma omp scope nowait private (i)
+    #pragma omp scope reduction(+: r2)
+    {
+      #pragma omp for nowait
+      for (i = 0; i < 64; i++)
+       {
+         r2 += 2 * i;
+         a[i] += i;
+       }
+    }
+    if (r2 != 64 * 63)
+      abort ();
+    #pragma omp for nowait
+    for (i = 0; i < 64; i++)
+      if (a[i] != i + 1)
+       abort ();
+  }
+  return 0;
+}