gimplify.c (struct gimplify_omp_ctx): Add clauses member.

* gimplify.c (struct gimplify_omp_ctx): Add clauses member.
	(gimplify_scan_omp_clauses): Initialize ctx->clauses.
	(gimplify_adjust_omp_clauses_1): Transform lastprivate conditional
	explicit clause on combined parallel into implicit shared clause.
	(gimplify_adjust_omp_clauses): Move lastprivate conditional clause
	and firstprivate if the decl has one too from combined parallel to
	the worksharing construct.
gcc/testsuite/
	* c-c++-common/gomp/lastprivate-conditional-2.c (foo): Don't expect
	sorry on lastprivate conditional on parallel for.
	* c-c++-common/gomp/lastprivate-conditional-3.c (foo): Add tests for
	lastprivate conditional warnings on parallel for constructs.
	* c-c++-common/gomp/lastprivate-conditional-4.c: New test.
libgomp/
	* testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c: Rename
	to ...
	* testsuite/libgomp.c-c++-common/lastprivate-conditional-4.c: ... this.
	* testsuite/libgomp.c-c++-common/lastprivate-conditional-5.c: New test.
	* testsuite/libgomp.c-c++-common/lastprivate-conditional-6.c: New test.

From-SVN: r271733
This commit is contained in:
Jakub Jelinek 2019-05-29 09:51:43 +02:00 committed by Jakub Jelinek
parent 357a352fe3
commit 7e47198b80
10 changed files with 411 additions and 3 deletions

View File

@ -1,3 +1,13 @@
2019-05-29 Jakub Jelinek <jakub@redhat.com>
* gimplify.c (struct gimplify_omp_ctx): Add clauses member.
(gimplify_scan_omp_clauses): Initialize ctx->clauses.
(gimplify_adjust_omp_clauses_1): Transform lastprivate conditional
explicit clause on combined parallel into implicit shared clause.
(gimplify_adjust_omp_clauses): Move lastprivate conditional clause
and firstprivate if the decl has one too from combined parallel to
the worksharing construct.
2019-05-28 Bill Schmidt <wschmidt@linux.ibm.com>
Michael Meissner <meissner@linux.ibm.com>

View File

@ -205,6 +205,7 @@ struct gimplify_omp_ctx
struct gimplify_omp_ctx *outer_context;
splay_tree variables;
hash_set<tree> *privatized_types;
tree clauses;
/* Iteration variables in an OMP_FOR. */
vec<tree> loop_iter_var;
location_t location;
@ -8054,7 +8055,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
struct gimplify_omp_ctx *ctx, *outer_ctx;
tree c;
hash_map<tree, tree> *struct_map_to_clause = NULL;
tree *prev_list_p = NULL;
tree *prev_list_p = NULL, *orig_list_p = list_p;
int handled_depend_iterators = -1;
int nowait = -1;
@ -8143,7 +8144,9 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
}
if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
{
if (code == OMP_FOR || code == OMP_SECTIONS)
if (code == OMP_FOR
|| code == OMP_SECTIONS
|| region_type == ORT_COMBINED_PARALLEL)
flags |= GOVD_LASTPRIVATE_CONDITIONAL;
else
{
@ -9312,6 +9315,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
list_p = &OMP_CLAUSE_CHAIN (c);
}
ctx->clauses = *orig_list_p;
gimplify_omp_ctxp = ctx;
if (struct_map_to_clause)
delete struct_map_to_clause;
@ -9455,6 +9459,9 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
tree clause;
bool private_debug;
if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
&& (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
return 0;
if ((flags & GOVD_SEEN) == 0)
@ -9697,6 +9704,34 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
omp_find_stores_op, &wi);
}
}
if (ctx->region_type == ORT_WORKSHARE
&& ctx->outer_context
&& ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
{
for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
{
decl = OMP_CLAUSE_DECL (c);
splay_tree_node n
= splay_tree_lookup (ctx->outer_context->variables,
(splay_tree_key) decl);
gcc_checking_assert (!splay_tree_lookup (ctx->variables,
(splay_tree_key) decl));
omp_add_variable (ctx, decl, n->value);
tree c2 = copy_node (c);
OMP_CLAUSE_CHAIN (c2) = *list_p;
*list_p = c2;
if ((n->value & GOVD_FIRSTPRIVATE) == 0)
continue;
c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c2) = decl;
OMP_CLAUSE_CHAIN (c2) = *list_p;
*list_p = c2;
}
}
while ((c = *list_p) != NULL)
{
splay_tree_node n;
@ -9723,6 +9758,10 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
decl = OMP_CLAUSE_DECL (c);
n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
remove = !(n->value & GOVD_SEEN);
if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
&& code == OMP_PARALLEL
&& OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
remove = true;
if (! remove)
{
bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
@ -9771,6 +9810,8 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
&& DECL_P (decl)
&& omp_shared_to_firstprivate_optimizable_decl_p (decl))
omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
remove = true;
break;
case OMP_CLAUSE_ALIGNED:

View File

@ -1,5 +1,11 @@
2019-05-29 Jakub Jelinek <jakub@redhat.com>
* c-c++-common/gomp/lastprivate-conditional-2.c (foo): Don't expect
sorry on lastprivate conditional on parallel for.
* c-c++-common/gomp/lastprivate-conditional-3.c (foo): Add tests for
lastprivate conditional warnings on parallel for constructs.
* c-c++-common/gomp/lastprivate-conditional-4.c: New test.
PR c/90628
* c-c++-common/builtin-arith-overflow-3.c: New test.

View File

@ -17,7 +17,7 @@ foo (int *p)
for (i = 0; i < 32; i++)
if (p[i])
c = i;
#pragma omp parallel for lastprivate (conditional: d) /* { dg-message "not supported yet" } */
#pragma omp parallel for lastprivate (conditional: d)
for (i = 0; i < 32; i++)
if (p[i])
d = i;

View File

@ -23,4 +23,22 @@ foo (int *p)
for (k = 0; k < 2; ++k)
;
}
#pragma omp parallel for lastprivate (conditional: i) /* { dg-warning "conditional 'lastprivate' on loop iterator 'i' ignored" } */
for (i = 0; i < 32; i++)
;
#pragma omp parallel for collapse (3) lastprivate (conditional: i) /* { dg-warning "conditional 'lastprivate' on loop iterator 'i' ignored" } */
for (i = 0; i < 32; i++)
for (j = 0; j < 32; ++j)
for (k = 0; k < 2; ++k)
;
#pragma omp parallel for collapse (3) lastprivate (conditional: j) /* { dg-warning "conditional 'lastprivate' on loop iterator 'j' ignored" } */
for (i = 0; i < 32; i++)
for (j = 0; j < 32; ++j)
for (k = 0; k < 2; ++k)
;
#pragma omp parallel for collapse (3) lastprivate (conditional: k) /* { dg-warning "conditional 'lastprivate' on loop iterator 'k' ignored" } */
for (i = 0; i < 32; i++)
for (j = 0; j < 32; ++j)
for (k = 0; k < 2; ++k)
;
}

View File

@ -0,0 +1,23 @@
int x = 6, w = 8;
int bar (int);
void
foo ()
{
int y = 5, i;
#pragma omp teams num_teams(1) firstprivate (x) shared (y) shared (w)
{
int z = 7;
#pragma omp parallel for firstprivate (x, y, z, w) lastprivate (conditional: x, y, z, w)
for (i = 0; i < 64; i++)
if (bar (i))
{
x = i;
y = i + 1;
z = i + 2;
w = i + 3;
}
bar (y);
bar (z);
}
}

View File

@ -1,3 +1,11 @@
2019-05-29 Jakub Jelinek <jakub@redhat.com>
* testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c: Rename
to ...
* testsuite/libgomp.c-c++-common/lastprivate-conditional-4.c: ... this.
* testsuite/libgomp.c-c++-common/lastprivate-conditional-5.c: New test.
* testsuite/libgomp.c-c++-common/lastprivate-conditional-6.c: New test.
2019-05-27 Jakub Jelinek <jakub@redhat.com>
* testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c: New test.

View File

@ -0,0 +1,143 @@
/* { dg-do run } */
/* { dg-require-effective-target tls_runtime } */
/* { dg-additional-options "-std=gnu99" {target c } } */
#include <omp.h>
#include <stdlib.h>
int r, s, u, v, r2, s2, u2, v2, r3, s3, u3, v3;
long long w, w2, w3, p, p2, p3;
int *x, *x2, *x3;
short y, y2, y3;
int z;
int thr1, thr2;
#pragma omp threadprivate (thr1, thr2)
void
foo (int *a, long long int b, long long int c)
{
int i;
long long j;
#pragma omp parallel for lastprivate (conditional: u, x)
for (i = 15; i < 64; i++)
{
if ((a[i] % 5) == 3)
u = i;
if ((a[i] % 7) == 2)
x = &a[i];
}
#pragma omp parallel for lastprivate (conditional: v) reduction (+:r, s) schedule (nonmonotonic: static)
for (i = -3; i < 119; i += 2)
{
++s;
if ((a[i + 4] % 11) == 9)
v = i;
else
++r;
}
#pragma omp parallel for schedule (monotonic: static) lastprivate (conditional: w)
for (j = b; j < b + 115 * c; j += (b & 3) + 7)
if ((a[j] % 13) == 5)
w = j * 2;
#pragma omp parallel for schedule (auto) lastprivate (conditional: p) collapse(3)
for (i = -5; i < (int) (b + 5); i += 2)
for (j = b + 12 + c; j > b; --j)
for (int k = 0; k < 5; k += c)
if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
p = i * 10000 + j * 100 + k;
#pragma omp parallel for schedule (nonmonotonic: static, 2) lastprivate (conditional: u2, x2)
for (i = 15; i < 64; i++)
{
if ((a[i] % 5) == 3)
u2 = i;
if ((a[i] % 7) == 2)
x2 = &a[i];
}
#pragma omp parallel for schedule (static, 3) lastprivate (conditional: v2) reduction (+:r2, s2)
for (i = -3; i < 119; i += 2)
{
++s2;
if ((a[i + 4] % 11) == 9)
v2 = i;
else
++r2;
}
#pragma omp parallel for lastprivate (conditional: w2) schedule (static, 1)
for (j = b; j < b + 115 * c; j += (b & 3) + 7)
if ((a[j] % 13) == 5)
w2 = j * 2;
#pragma omp parallel for schedule (static, 3) collapse (3) lastprivate (conditional: p2)
for (i = -5; i < (int) (b + 5); i += 2)
for (j = b + 12 + c; j > b; --j)
for (int k = 0; k < 5; k += c)
if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
p2 = i * 10000 + j * 100 + k;
#pragma omp parallel for lastprivate (conditional: u3, x3) schedule (runtime)
for (i = 15; i < 64; i++)
{
if ((a[i] % 5) == 3)
u3 = i;
if ((a[i] % 7) == 2)
x3 = &a[i];
}
#pragma omp parallel for lastprivate (conditional: v3) reduction (+:r3, s3) schedule (nonmonotonic: dynamic)
for (i = -3; i < 119; i += 2)
{
++s3;
if ((a[i + 4] % 11) == 9)
v3 = i;
else
++r3;
}
#pragma omp parallel for schedule (monotonic: guided, 3) lastprivate (conditional: w3)
for (j = b; j < b + 115 * c; j += (b & 3) + 7)
if ((a[j] % 13) == 5)
w3 = j * 2;
#pragma omp parallel for schedule (dynamic, 4) lastprivate (conditional: p3) collapse(3)
for (i = -5; i < (int) (b + 5); i += 2)
for (j = b + 12 + c; j > b; --j)
for (int k = 0; k < 5; k += c)
if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
p3 = i * 10000 + j * 100 + k;
/* Nasty testcase, verify that even a no-op assignment is accounted
for in lastprivate(conditional:). */
#pragma omp parallel for schedule (monotonic: static, 2) firstprivate (z) \
lastprivate (conditional: z)
for (int k = -2000; k < 8000; ++k)
{
if (k < 3000 && (k & 3) == 1)
{
z = k;
thr1 = k;
}
else if (k == 7931)
{
z = z;
thr2 = 1;
}
}
if (thr2 && z != thr1)
abort ();
}
int
main ()
{
int a[128], i;
volatile int j = 0;
for (i = 0; i < 128; i++)
a[i] = i;
w = 1234;
foo (a, j, j + 1);
if (u != 63 || v != 115 || w != 140 || x != &a[58] || r != 55 || s != 61 || p != 30104)
abort ();
if (u2 != 63 || v2 != 115 || w2 != 140 || x2 != &a[58] || r2 != 55 || s2 != 61 || p2 != 30104)
abort ();
if (u3 != 63 || v3 != 115 || w3 != 140 || x3 != &a[58] || r3 != 55 || s3 != 61 || p3 != 30104)
abort ();
return 0;
}

View File

@ -0,0 +1,159 @@
#include <stdlib.h>
int x;
long long y;
int r, s, t;
void
foo (const char *a)
{
#pragma omp parallel sections lastprivate (conditional: x, y)
{
if (a[0])
x = a[0];
#pragma omp section
{
if (a[1])
x = a[1];
if (a[2])
y = a[2];
}
#pragma omp section
if (a[3])
y = a[3];
#pragma omp section
if (a[4])
x = a[4];
#pragma omp section
{
if (a[5])
x = a[5];
if (a[6])
y = a[6];
}
}
}
void
bar (const char *a)
{
#pragma omp parallel sections lastprivate (conditional: x, y) reduction (task, +: t)
{
if (a[0])
x = a[0];
#pragma omp section
{
if (a[1])
x = a[1];
if (a[2])
y = a[2];
#pragma omp task in_reduction (+: t)
t++;
}
#pragma omp section
if (a[3])
y = a[3];
#pragma omp section
if (a[4])
x = a[4];
#pragma omp section
{
#pragma omp task in_reduction (+: t)
++t;
if (a[5])
x = a[5];
if (a[6])
y = a[6];
}
}
}
void
baz (const char *a)
{
#pragma omp parallel sections lastprivate (conditional: x, y) reduction (+: r, s)
{
if (a[0])
x = a[0];
#pragma omp section
{
if (a[1])
x = a[1];
++r;
++s;
if (a[2])
y = a[2];
}
#pragma omp section
if (a[3])
y = a[3];
#pragma omp section
{
++s;
if (a[4])
x = a[4];
}
#pragma omp section
{
if (a[5])
x = a[5];
if (a[6])
y = a[6];
++s;
}
}
}
int
main ()
{
foo ("\0\1\2\3\0\5");
if (x != 5 || y != 3)
abort ();
foo ("\6\0\0\0\0\0\7");
if (x != 6 || y != 7)
abort ();
foo ("\7\6\5\4\3\2\1");
if (x != 2 || y != 1)
abort ();
foo ("\0\0\4\3\0\7");
if (x != 7 || y != 3)
abort ();
bar ("\0\1\2\4\0\5");
if (x != 5 || y != 4 || t != 2)
abort ();
bar ("\6\0\0\0\0\0\7");
if (x != 6 || y != 7 || t != 4)
abort ();
bar ("\7\6\5\4\3\2\1");
if (x != 2 || y != 1 || t != 6)
abort ();
bar ("\0\0\4\3\0\7");
if (x != 7 || y != 3 || t != 8)
abort ();
baz ("\0\1\2\4\0\5");
if (x != 5 || y != 4 || r != 1 || s != 3)
abort ();
baz ("\6\0\0\0\0\0\7");
if (x != 6 || y != 7 || r != 2 || s != 6)
abort ();
baz ("\7\6\5\4\3\2\1");
if (x != 2 || y != 1 || r != 3 || s != 9)
abort ();
baz ("\0\0\4\3\0\7");
if (x != 7 || y != 3 || r != 4 || s != 12)
abort ();
return 0;
}