From 8e7757ba17b1aeb83387c33004149a185a5fa137 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 27 May 2019 23:33:37 +0200 Subject: [PATCH] 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) : 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 --- gcc/ChangeLog | 9 ++ gcc/gimplify.c | 2 +- gcc/omp-expand.c | 73 ++++++++-- gcc/omp-low.c | 43 ++++-- libgomp/ChangeLog | 2 + .../lastprivate_conditional_4.c | 161 +++++++++++++++++++++ 6 files changed, 266 insertions(+), 24 deletions(-) create mode 100644 libgomp/testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ce0004358ce..03b549601f0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2019-05-27 Jakub Jelinek + * 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) : Handle sections construct with + lastprivate_conditional_map. + * omp-expand.c (expand_omp_sections): Handle lastprivate conditional. + * omp-low.c (lower_omp_1) : Look through ordered, critical, taskgroup and section regions when looking for a region with non-NULL lastprivate_conditional_map. diff --git a/gcc/gimplify.c b/gcc/gimplify.c index b8b7e803990..a0177b25f56 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -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 { diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c index dfac4b075e5..038781c918c 100644 --- a/gcc/omp-expand.c +++ b/gcc/omp-expand.c @@ -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 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 condtmp = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_); + tree cond_var = NULL_TREE; + if (reductmp || condtmp) + { + 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; diff --git a/gcc/omp-low.c b/gcc/omp-low.c index db9f5047c72..e673abaf4a2 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -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 (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 (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 (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 (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_); diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 33906ededc7..e6cda724fbd 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,5 +1,7 @@ 2019-05-27 Jakub Jelinek + * 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 diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c new file mode 100644 index 00000000000..bc102a10cd1 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c @@ -0,0 +1,161 @@ +#include + +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; +} -- 2.11.4.GIT