gimplify.c (gimplify_scan_omp_clauses): Allow lastprivate conditional on sections construct.
* gimplify.c (gimplify_scan_omp_clauses): Allow lastprivate conditional on sections construct. * omp-low.c (lower_lastprivate_conditional_clauses): Handle sections construct. (lower_omp_sections): Handle lastprivate conditional. (lower_omp_1) <case GIMPLE_ASSIGN>: Handle sections construct with lastprivate_conditional_map. * omp-expand.c (expand_omp_sections): Handle lastprivate conditional. libgomp/ * testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c: New test. From-SVN: r271673
This commit is contained in:
parent
36c7a3fff9
commit
8e7757ba17
6 changed files with 265 additions and 23 deletions
|
@ -1,5 +1,14 @@
|
|||
2019-05-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gimplify.c (gimplify_scan_omp_clauses): Allow lastprivate conditional
|
||||
on sections construct.
|
||||
* omp-low.c (lower_lastprivate_conditional_clauses): Handle sections
|
||||
construct.
|
||||
(lower_omp_sections): Handle lastprivate conditional.
|
||||
(lower_omp_1) <case GIMPLE_ASSIGN>: Handle sections construct with
|
||||
lastprivate_conditional_map.
|
||||
* omp-expand.c (expand_omp_sections): Handle lastprivate conditional.
|
||||
|
||||
* omp-low.c (lower_omp_1) <case GIMPLE_ASSIGN>: Look through ordered,
|
||||
critical, taskgroup and section regions when looking for a region
|
||||
with non-NULL lastprivate_conditional_map.
|
||||
|
|
|
@ -8143,7 +8143,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
|
|||
}
|
||||
if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
|
||||
{
|
||||
if (code == OMP_FOR)
|
||||
if (code == OMP_FOR || code == OMP_SECTIONS)
|
||||
flags |= GOVD_LASTPRIVATE_CONDITIONAL;
|
||||
else
|
||||
{
|
||||
|
|
|
@ -6386,21 +6386,62 @@ expand_omp_sections (struct omp_region *region)
|
|||
vin = gimple_omp_sections_control (sections_stmt);
|
||||
tree clauses = gimple_omp_sections_clauses (sections_stmt);
|
||||
tree reductmp = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
|
||||
if (reductmp)
|
||||
tree condtmp = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
|
||||
tree cond_var = NULL_TREE;
|
||||
if (reductmp || condtmp)
|
||||
{
|
||||
tree reductions = OMP_CLAUSE_DECL (reductmp);
|
||||
gcc_assert (TREE_CODE (reductions) == SSA_NAME);
|
||||
gimple *g = SSA_NAME_DEF_STMT (reductions);
|
||||
reductions = gimple_assign_rhs1 (g);
|
||||
OMP_CLAUSE_DECL (reductmp) = reductions;
|
||||
gimple_stmt_iterator gsi = gsi_for_stmt (g);
|
||||
tree reductions = null_pointer_node, mem = null_pointer_node;
|
||||
tree memv = NULL_TREE, condtemp = NULL_TREE;
|
||||
gimple_stmt_iterator gsi = gsi_none ();
|
||||
gimple *g = NULL;
|
||||
if (reductmp)
|
||||
{
|
||||
reductions = OMP_CLAUSE_DECL (reductmp);
|
||||
gcc_assert (TREE_CODE (reductions) == SSA_NAME);
|
||||
g = SSA_NAME_DEF_STMT (reductions);
|
||||
reductions = gimple_assign_rhs1 (g);
|
||||
OMP_CLAUSE_DECL (reductmp) = reductions;
|
||||
gsi = gsi_for_stmt (g);
|
||||
}
|
||||
else
|
||||
gsi = si;
|
||||
if (condtmp)
|
||||
{
|
||||
condtemp = OMP_CLAUSE_DECL (condtmp);
|
||||
tree c = omp_find_clause (OMP_CLAUSE_CHAIN (condtmp),
|
||||
OMP_CLAUSE__CONDTEMP_);
|
||||
cond_var = OMP_CLAUSE_DECL (c);
|
||||
tree type = TREE_TYPE (condtemp);
|
||||
memv = create_tmp_var (type);
|
||||
TREE_ADDRESSABLE (memv) = 1;
|
||||
unsigned cnt = 0;
|
||||
for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
|
||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
|
||||
&& OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
|
||||
++cnt;
|
||||
unsigned HOST_WIDE_INT sz
|
||||
= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type))) * cnt;
|
||||
expand_omp_build_assign (&gsi, memv, build_int_cst (type, sz),
|
||||
false);
|
||||
mem = build_fold_addr_expr (memv);
|
||||
}
|
||||
t = build_int_cst (unsigned_type_node, len - 1);
|
||||
u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS2_START);
|
||||
stmt = gimple_build_call (u, 3, t, reductions, null_pointer_node);
|
||||
stmt = gimple_build_call (u, 3, t, reductions, mem);
|
||||
gimple_call_set_lhs (stmt, vin);
|
||||
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
|
||||
gsi_remove (&gsi, true);
|
||||
release_ssa_name (gimple_assign_lhs (g));
|
||||
if (condtmp)
|
||||
{
|
||||
expand_omp_build_assign (&gsi, condtemp, memv, false);
|
||||
tree t = build2 (PLUS_EXPR, TREE_TYPE (cond_var),
|
||||
vin, build_one_cst (TREE_TYPE (cond_var)));
|
||||
expand_omp_build_assign (&gsi, cond_var, t, false);
|
||||
}
|
||||
if (reductmp)
|
||||
{
|
||||
gsi_remove (&gsi, true);
|
||||
release_ssa_name (gimple_assign_lhs (g));
|
||||
}
|
||||
}
|
||||
else if (!is_combined_parallel (region))
|
||||
{
|
||||
|
@ -6416,7 +6457,7 @@ expand_omp_sections (struct omp_region *region)
|
|||
u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
|
||||
stmt = gimple_build_call (u, 0);
|
||||
}
|
||||
if (!reductmp)
|
||||
if (!reductmp && !condtmp)
|
||||
{
|
||||
gimple_call_set_lhs (stmt, vin);
|
||||
gsi_insert_after (&si, stmt, GSI_SAME_STMT);
|
||||
|
@ -6508,7 +6549,13 @@ expand_omp_sections (struct omp_region *region)
|
|||
bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
|
||||
stmt = gimple_build_call (bfn_decl, 0);
|
||||
gimple_call_set_lhs (stmt, vnext);
|
||||
gsi_insert_after (&si, stmt, GSI_SAME_STMT);
|
||||
gsi_insert_before (&si, stmt, GSI_SAME_STMT);
|
||||
if (cond_var)
|
||||
{
|
||||
tree t = build2 (PLUS_EXPR, TREE_TYPE (cond_var),
|
||||
vnext, build_one_cst (TREE_TYPE (cond_var)));
|
||||
expand_omp_build_assign (&si, cond_var, t, false);
|
||||
}
|
||||
gsi_remove (&si, true);
|
||||
|
||||
single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
|
||||
|
|
|
@ -5370,7 +5370,6 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
|||
static void
|
||||
lower_lastprivate_conditional_clauses (tree *clauses, omp_context *ctx)
|
||||
{
|
||||
struct omp_for_data fd;
|
||||
tree iter_type = NULL_TREE;
|
||||
tree cond_ptr = NULL_TREE;
|
||||
tree iter_var = NULL_TREE;
|
||||
|
@ -5380,8 +5379,15 @@ lower_lastprivate_conditional_clauses (tree *clauses, omp_context *ctx)
|
|||
{
|
||||
if (iter_type == NULL)
|
||||
{
|
||||
omp_extract_for_data (as_a <gomp_for *> (ctx->stmt), &fd, NULL);
|
||||
iter_type = unsigned_type_for (fd.iter_type);
|
||||
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR)
|
||||
{
|
||||
struct omp_for_data fd;
|
||||
omp_extract_for_data (as_a <gomp_for *> (ctx->stmt), &fd,
|
||||
NULL);
|
||||
iter_type = unsigned_type_for (fd.iter_type);
|
||||
}
|
||||
else if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
|
||||
iter_type = unsigned_type_node;
|
||||
cond_ptr = create_tmp_var_raw (build_pointer_type (iter_type));
|
||||
DECL_CONTEXT (cond_ptr) = current_function_decl;
|
||||
DECL_SEEN_IN_BIND_EXPR_P (cond_ptr) = 1;
|
||||
|
@ -6739,7 +6745,7 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
|||
gomp_sections *stmt;
|
||||
gimple *t;
|
||||
gbind *new_stmt, *bind;
|
||||
gimple_seq ilist, dlist, olist, tred_dlist = NULL, new_body;
|
||||
gimple_seq ilist, dlist, olist, tred_dlist = NULL, clist = NULL, new_body;
|
||||
|
||||
stmt = as_a <gomp_sections *> (gsi_stmt (*gsi_p));
|
||||
|
||||
|
@ -6771,6 +6777,12 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
|||
lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
|
||||
&ilist, &dlist, ctx, NULL);
|
||||
|
||||
control = create_tmp_var (unsigned_type_node, ".section");
|
||||
gimple_omp_sections_set_control (stmt, control);
|
||||
|
||||
tree *clauses_ptr = gimple_omp_sections_clauses_ptr (stmt);
|
||||
lower_lastprivate_conditional_clauses (clauses_ptr, ctx);
|
||||
|
||||
new_body = gimple_omp_body (stmt);
|
||||
gimple_omp_set_body (stmt, NULL);
|
||||
tgsi = gsi_start (new_body);
|
||||
|
@ -6792,7 +6804,7 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
|||
{
|
||||
gimple_seq l = NULL;
|
||||
lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
|
||||
NULL, &l, NULL, ctx);
|
||||
&ilist, &l, &clist, ctx);
|
||||
gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
|
||||
gimple_omp_section_set_last (sec_start);
|
||||
}
|
||||
|
@ -6806,7 +6818,17 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
|||
|
||||
olist = NULL;
|
||||
lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist,
|
||||
NULL, ctx);
|
||||
&clist, ctx);
|
||||
if (clist)
|
||||
{
|
||||
tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
|
||||
gcall *g = gimple_build_call (fndecl, 0);
|
||||
gimple_seq_add_stmt (&olist, g);
|
||||
gimple_seq_add_seq (&olist, clist);
|
||||
fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
|
||||
g = gimple_build_call (fndecl, 0);
|
||||
gimple_seq_add_stmt (&olist, g);
|
||||
}
|
||||
|
||||
block = make_node (BLOCK);
|
||||
new_stmt = gimple_build_bind (NULL, NULL, block);
|
||||
|
@ -6824,9 +6846,7 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
|||
gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
|
||||
gimple_seq_add_stmt (&new_body, bind);
|
||||
|
||||
control = create_tmp_var (unsigned_type_node, ".section");
|
||||
t = gimple_build_omp_continue (control, control);
|
||||
gimple_omp_sections_set_control (stmt, control);
|
||||
gimple_seq_add_stmt (&new_body, t);
|
||||
|
||||
gimple_seq_add_seq (&new_body, olist);
|
||||
|
@ -10640,8 +10660,11 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
|||
if (DECL_P (lhs))
|
||||
if (tree *v = up->lastprivate_conditional_map->get (lhs))
|
||||
{
|
||||
tree clauses
|
||||
= gimple_omp_for_clauses (as_a <gomp_for *> (up->stmt));
|
||||
tree clauses;
|
||||
if (gimple_code (up->stmt) == GIMPLE_OMP_FOR)
|
||||
clauses = gimple_omp_for_clauses (up->stmt);
|
||||
else
|
||||
clauses = gimple_omp_sections_clauses (up->stmt);
|
||||
tree c = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
|
||||
c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
|
||||
OMP_CLAUSE__CONDTEMP_);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
2019-05-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c: New test.
|
||||
|
||||
* testsuite/libgomp.c-c++-common/lastprivate-conditional-3.c: New test.
|
||||
|
||||
PR libgomp/90641
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
int x;
|
||||
long long y;
|
||||
int r, s, t;
|
||||
|
||||
void
|
||||
foo (const char *a)
|
||||
{
|
||||
#pragma omp 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 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 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 ()
|
||||
{
|
||||
#pragma omp parallel
|
||||
{
|
||||
foo ("\0\1\2\3\0\5");
|
||||
if (x != 5 || y != 3)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
foo ("\6\0\0\0\0\0\7");
|
||||
if (x != 6 || y != 7)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
foo ("\7\6\5\4\3\2\1");
|
||||
if (x != 2 || y != 1)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
foo ("\0\0\4\3\0\7");
|
||||
if (x != 7 || y != 3)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
bar ("\0\1\2\4\0\5");
|
||||
if (x != 5 || y != 4 || t != 2)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
bar ("\6\0\0\0\0\0\7");
|
||||
if (x != 6 || y != 7 || t != 4)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
bar ("\7\6\5\4\3\2\1");
|
||||
if (x != 2 || y != 1 || t != 6)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
bar ("\0\0\4\3\0\7");
|
||||
if (x != 7 || y != 3 || t != 8)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
baz ("\0\1\2\4\0\5");
|
||||
if (x != 5 || y != 4 || r != 1 || s != 3)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
baz ("\6\0\0\0\0\0\7");
|
||||
if (x != 6 || y != 7 || r != 2 || s != 6)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
baz ("\7\6\5\4\3\2\1");
|
||||
if (x != 2 || y != 1 || r != 3 || s != 9)
|
||||
abort ();
|
||||
#pragma omp barrier
|
||||
baz ("\0\0\4\3\0\7");
|
||||
if (x != 7 || y != 3 || r != 4 || s != 12)
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue