aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2022-05-31 11:41:52 +0200
committerJakub Jelinek <jakub@redhat.com>2022-05-31 11:41:52 +0200
commitf38b20d68fade5a922b9f68c4c3841e653d1b83c (patch)
tree1ca92757665a30a92421a2c3d095e5b6ecd8a25e
parent0f4df800b15437df1e00f198f86edc7163f1fc94 (diff)
downloadgcc-f38b20d68fade5a922b9f68c4c3841e653d1b83c.zip
gcc-f38b20d68fade5a922b9f68c4c3841e653d1b83c.tar.gz
gcc-f38b20d68fade5a922b9f68c4c3841e653d1b83c.tar.bz2
openmp: Add support for firstprivate and allocate clauses on scope construct
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.
-rw-r--r--gcc/c/c-parser.cc2
-rw-r--r--gcc/cp/parser.cc2
-rw-r--r--gcc/omp-low.cc3
-rw-r--r--gcc/testsuite/c-c++-common/gomp/scope-5.c9
-rw-r--r--gcc/testsuite/c-c++-common/gomp/scope-6.c31
-rw-r--r--gcc/testsuite/g++.dg/gomp/attrs-1.C6
-rw-r--r--gcc/testsuite/g++.dg/gomp/attrs-2.C6
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/allocate-1.c30
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/allocate-3.c35
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/scope-2.c54
10 files changed, 171 insertions, 7 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 7cc4d93c..c9a8d14 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -20413,7 +20413,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
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index b3a6c9a..2106642 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -43747,7 +43747,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
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index 16f5965..f976e3a 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -683,6 +683,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
@@ -4849,7 +4850,7 @@ lower_private_allocate (tree var, tree new_var, tree &allocator,
allocator = TREE_PURPOSE (allocator);
}
if (TREE_CODE (allocator) != INTEGER_CST)
- 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)
{
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
index 0000000..6cd4a80
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/scope-5.c
@@ -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
index 0000000..760dd71
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/scope-6.c
@@ -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++;
+ }
+}
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-1.C b/gcc/testsuite/g++.dg/gomp/attrs-1.C
index f64b078..3f366ae 100644
--- a/gcc/testsuite/g++.dg/gomp/attrs-1.C
+++ b/gcc/testsuite/g++.dg/gomp/attrs-1.C
@@ -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))]];
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-2.C b/gcc/testsuite/g++.dg/gomp/attrs-2.C
index cc91fa2..cb80415 100644
--- a/gcc/testsuite/g++.dg/gomp/attrs-2.C
+++ b/gcc/testsuite/g++.dg/gomp/attrs-2.C
@@ -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))]];
diff --git a/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c b/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c
index 4398ff9..d3af3b8 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/allocate-1.c
@@ -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
diff --git a/libgomp/testsuite/libgomp.c-c++-common/allocate-3.c b/libgomp/testsuite/libgomp.c-c++-common/allocate-3.c
index ce1a045..0b50744 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/allocate-3.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/allocate-3.c
@@ -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
index 0000000..2d67102
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/scope-2.c
@@ -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;
+}