diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-08-06 09:26:32 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-08-06 09:26:32 +0200 |
commit | d81ab49d0586fca0f3ee2f49c4581dd02508fcca (patch) | |
tree | d3d4e04d7c7e987c478e88417ded02a08e3e8aad /gcc | |
parent | 7551a6e467c64b3155d5b8f005cd7ea7143b21f3 (diff) | |
download | gcc-d81ab49d0586fca0f3ee2f49c4581dd02508fcca.zip gcc-d81ab49d0586fca0f3ee2f49c4581dd02508fcca.tar.gz gcc-d81ab49d0586fca0f3ee2f49c4581dd02508fcca.tar.bz2 |
tree.h (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV): Rename to ...
* tree.h (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV): Rename to ...
(OMP_CLAUSE_LASTPRIVATE_LOOP_IV): ... this. Adjust comment.
* gimplify.c (gimple_add_tmp_var): In SIMD contexts, turn addressable
new vars into GOVD_PRIVATE rather than GOVD_LOCAL.
(gimplify_omp_for): Don't do C++ random access iterator clause
adjustments on combined constructs from OMP_LOOP. For OMP_LOOP,
don't predetermine the artificial iterator in case of C++ random
access iterators as lastprivate, but private. For OMP_LOOP, force
bind expr around simd body and force for_pre_body before the
construct. Use OMP_CLAUSE_LASTPRIVATE_LOOP_IV instead of
OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV.
(gimplify_omp_loop): Add firstprivate clauses on OMP_PARALLEL for
diff var of C++ random access iterators. Handle
OMP_CLAUSE_FIRSTPRIVATE. For OMP_CLAUSE_LASTPRIVATE_LOOP_IV, if
not outermost also add OMP_CLAUSE_FIRSTPRIVATE, and in both cases
clear OMP_CLAUSE_LASTPRIVATE_LOOP_IV on the lastprivate clause
on the OMP_FOR and OMP_DISTRIBUTE constructs if any.
* omp-low.c (lower_rec_input_clauses): For
OMP_CLAUSE_LASTPRIVATE_LOOP_IV on simd copy construct the private
variables instead of default constructing them.
(lower_lastprivate_clauses): Use OMP_CLAUSE_LASTPRIVATE_LOOP_IV
instead of OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV and move the
is_taskloop_ctx check from the assert to the guarding condition.
gcc/cp/
* parser.c (cp_parser_omp_for_loop): For OMP_LOOP, ignore parallel
clauses and predetermine iterator as lastprivate.
* semantics.c (handle_omp_for_class_iterator): Use
OMP_CLAUSE_LASTPRIVATE_LOOP_IV instead of
OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV, set it for lastprivate also
on OMP_LOOP construct. If a clause is missing for class iterator
on OMP_LOOP, add firstprivate clause, and if there is private
clause, turn it into firstprivate too.
(finish_omp_for): Formatting fix. For OMP_LOOP, adjust
OMP_CLAUSE_LASTPRIVATE_LOOP_IV clause CP_CLAUSE_INFO, so that it
uses copy ctor instead of default ctor.
* cp-gimplify.c (cp_gimplify_expr): Handle OMP_LOOP like
OMP_DISTRIBUTE etc.
(cp_fold_r): Likewise.
(cp_genericize_r): Likewise.
(cxx_omp_finish_clause): Also finish lastprivate clause with
OMP_CLAUSE_LASTPRIVATE_LOOP_IV flag.
* pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_BIND.
(tsubst_omp_for_iterator): For OMP_LOOP, ignore parallel
clauses and predetermine iterator as lastprivate.
* constexpr.c (potential_constant_expression_1): Handle OMP_LOOP
like OMP_DISTRIBUTE etc.
libgomp/
* testsuite/libgomp.c++/loop-13.C: New test.
* testsuite/libgomp.c++/loop-14.C: New test.
* testsuite/libgomp.c++/loop-15.C: New test.
From-SVN: r274138
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 26 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 25 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 1 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 12 | ||||
-rw-r--r-- | gcc/cp/parser.c | 11 | ||||
-rw-r--r-- | gcc/cp/pt.c | 9 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 53 | ||||
-rw-r--r-- | gcc/gimplify.c | 80 | ||||
-rw-r--r-- | gcc/omp-low.c | 29 | ||||
-rw-r--r-- | gcc/tree.h | 9 |
10 files changed, 215 insertions, 40 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f19091c..ccb7253 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,29 @@ +2019-08-06 Jakub Jelinek <jakub@redhat.com> + + * tree.h (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV): Rename to ... + (OMP_CLAUSE_LASTPRIVATE_LOOP_IV): ... this. Adjust comment. + * gimplify.c (gimple_add_tmp_var): In SIMD contexts, turn addressable + new vars into GOVD_PRIVATE rather than GOVD_LOCAL. + (gimplify_omp_for): Don't do C++ random access iterator clause + adjustments on combined constructs from OMP_LOOP. For OMP_LOOP, + don't predetermine the artificial iterator in case of C++ random + access iterators as lastprivate, but private. For OMP_LOOP, force + bind expr around simd body and force for_pre_body before the + construct. Use OMP_CLAUSE_LASTPRIVATE_LOOP_IV instead of + OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV. + (gimplify_omp_loop): Add firstprivate clauses on OMP_PARALLEL for + diff var of C++ random access iterators. Handle + OMP_CLAUSE_FIRSTPRIVATE. For OMP_CLAUSE_LASTPRIVATE_LOOP_IV, if + not outermost also add OMP_CLAUSE_FIRSTPRIVATE, and in both cases + clear OMP_CLAUSE_LASTPRIVATE_LOOP_IV on the lastprivate clause + on the OMP_FOR and OMP_DISTRIBUTE constructs if any. + * omp-low.c (lower_rec_input_clauses): For + OMP_CLAUSE_LASTPRIVATE_LOOP_IV on simd copy construct the private + variables instead of default constructing them. + (lower_lastprivate_clauses): Use OMP_CLAUSE_LASTPRIVATE_LOOP_IV + instead of OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV and move the + is_taskloop_ctx check from the assert to the guarding condition. + 2019-08-06 Kito Cheng <kito.cheng@sifive.com> * gcc/config/riscv/multilib-generator: (canonical_order): New. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 049863e..98e3b3f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,28 @@ +2019-08-06 Jakub Jelinek <jakub@redhat.com> + + * parser.c (cp_parser_omp_for_loop): For OMP_LOOP, ignore parallel + clauses and predetermine iterator as lastprivate. + * semantics.c (handle_omp_for_class_iterator): Use + OMP_CLAUSE_LASTPRIVATE_LOOP_IV instead of + OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV, set it for lastprivate also + on OMP_LOOP construct. If a clause is missing for class iterator + on OMP_LOOP, add firstprivate clause, and if there is private + clause, turn it into firstprivate too. + (finish_omp_for): Formatting fix. For OMP_LOOP, adjust + OMP_CLAUSE_LASTPRIVATE_LOOP_IV clause CP_CLAUSE_INFO, so that it + uses copy ctor instead of default ctor. + * cp-gimplify.c (cp_gimplify_expr): Handle OMP_LOOP like + OMP_DISTRIBUTE etc. + (cp_fold_r): Likewise. + (cp_genericize_r): Likewise. + (cxx_omp_finish_clause): Also finish lastprivate clause with + OMP_CLAUSE_LASTPRIVATE_LOOP_IV flag. + * pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_BIND. + (tsubst_omp_for_iterator): For OMP_LOOP, ignore parallel + clauses and predetermine iterator as lastprivate. + * constexpr.c (potential_constant_expression_1): Handle OMP_LOOP + like OMP_DISTRIBUTE etc. + 2019-08-05 Marek Polacek <polacek@redhat.com> DR 2413 - typename in conversion-function-ids. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 75df984..36a6633 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -6437,6 +6437,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, case OMP_SIMD: case OMP_DISTRIBUTE: case OMP_TASKLOOP: + case OMP_LOOP: case OMP_TEAMS: case OMP_TARGET_DATA: case OMP_TARGET: diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index b4863e2..065dcb7 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -796,6 +796,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) case OMP_FOR: case OMP_SIMD: case OMP_DISTRIBUTE: + case OMP_LOOP: case OMP_TASKLOOP: ret = cp_gimplify_omp_for (expr_p, pre_p); break; @@ -1053,7 +1054,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data) code = TREE_CODE (stmt); if (code == OMP_FOR || code == OMP_SIMD || code == OMP_DISTRIBUTE - || code == OMP_TASKLOOP || code == OACC_LOOP) + || code == OMP_LOOP || code == OMP_TASKLOOP || code == OACC_LOOP) { tree x; int i, n; @@ -1544,6 +1545,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) case OMP_FOR: case OMP_SIMD: case OMP_DISTRIBUTE: + case OMP_LOOP: case OACC_LOOP: genericize_omp_for_stmt (stmt_p, walk_subtrees, data); break; @@ -2097,7 +2099,9 @@ cxx_omp_finish_clause (tree c, gimple_seq *) tree decl, inner_type; bool make_shared = false; - if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE) + if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE + && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE + || !OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))) return; decl = OMP_CLAUSE_DECL (c); @@ -2115,9 +2119,11 @@ cxx_omp_finish_clause (tree c, gimple_seq *) /* Check for special function availability by building a call to one. Save the results, because later we won't be in the right context for making these queries. */ + bool first = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE; if (!make_shared && CLASS_TYPE_P (inner_type) - && cxx_omp_create_clause_info (c, inner_type, false, true, false, true)) + && cxx_omp_create_clause_info (c, inner_type, !first, first, !first, + true)) make_shared = true; if (make_shared) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 83e6d24..79da7b5 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -37458,7 +37458,8 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses, real_decl = decl; if (cclauses != NULL && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL - && real_decl != NULL_TREE) + && real_decl != NULL_TREE + && code != OMP_LOOP) { tree *c; for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; ) @@ -37518,12 +37519,12 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses, } if (c == NULL) { - if (code != OMP_SIMD) + if ((code == OMP_SIMD && collapse != 1) || code == OMP_LOOP) + c = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE); + else if (code != OMP_SIMD) c = build_omp_clause (loc, OMP_CLAUSE_PRIVATE); - else if (collapse == 1) - c = build_omp_clause (loc, OMP_CLAUSE_LINEAR); else - c = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE); + c = build_omp_clause (loc, OMP_CLAUSE_LINEAR); OMP_CLAUSE_DECL (c) = add_private_clause; c = finish_omp_clauses (c, C_ORT_OMP); if (c) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e671fe1..903e589 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -16404,6 +16404,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort, case OMP_CLAUSE_SIMD: case OMP_CLAUSE_DEFAULTMAP: case OMP_CLAUSE_ORDER: + case OMP_CLAUSE_BIND: case OMP_CLAUSE_INDEPENDENT: case OMP_CLAUSE_AUTO: case OMP_CLAUSE_SEQ: @@ -16732,7 +16733,8 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree &orig_declv, { tree *pc; int j; - for (j = (omp_parallel_combined_clauses == NULL ? 1 : 0); j < 2; j++) + for (j = ((omp_parallel_combined_clauses == NULL + || TREE_CODE (t) == OMP_LOOP) ? 1 : 0); j < 2; j++) { for (pc = j ? clauses : omp_parallel_combined_clauses; *pc; ) { @@ -16772,7 +16774,10 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree &orig_declv, } if (*pc == NULL_TREE) { - tree c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE); + tree c = build_omp_clause (input_location, + TREE_CODE (t) == OMP_LOOP + ? OMP_CLAUSE_LASTPRIVATE + : OMP_CLAUSE_PRIVATE); OMP_CLAUSE_DECL (c) = decl; c = finish_omp_clauses (c, C_ORT_OMP); if (c) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index d151d3d..fa69624 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -8422,24 +8422,25 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code, incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error); incr = cp_fully_fold (incr); - bool taskloop_iv_seen = false; + tree loop_iv_seen = NULL_TREE; for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE && OMP_CLAUSE_DECL (c) == iter) { - if (code == OMP_TASKLOOP) + if (code == OMP_TASKLOOP || code == OMP_LOOP) { - taskloop_iv_seen = true; - OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c) = 1; + loop_iv_seen = c; + OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) = 1; } break; } - else if (code == OMP_TASKLOOP + else if ((code == OMP_TASKLOOP || code == OMP_LOOP) && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE && OMP_CLAUSE_DECL (c) == iter) { - taskloop_iv_seen = true; - OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c) = 1; + loop_iv_seen = c; + if (code == OMP_TASKLOOP) + OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c) = 1; } decl = create_temporary_var (TREE_TYPE (diff)); @@ -8459,7 +8460,7 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code, tree diffvar = NULL_TREE; if (code == OMP_TASKLOOP) { - if (!taskloop_iv_seen) + if (!loop_iv_seen) { tree ivc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE); OMP_CLAUSE_DECL (ivc) = iter; @@ -8475,6 +8476,28 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code, pushdecl (diffvar); add_decl_expr (diffvar); } + else if (code == OMP_LOOP) + { + if (!loop_iv_seen) + { + /* While iterators on the loop construct are predetermined + lastprivate, if the decl is not declared inside of the + loop, OMP_CLAUSE_LASTPRIVATE should have been added + already. */ + loop_iv_seen = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE); + OMP_CLAUSE_DECL (loop_iv_seen) = iter; + OMP_CLAUSE_CHAIN (loop_iv_seen) = clauses; + clauses = loop_iv_seen; + } + else if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_PRIVATE) + { + OMP_CLAUSE_PRIVATE_DEBUG (loop_iv_seen) = 0; + OMP_CLAUSE_PRIVATE_OUTER_REF (loop_iv_seen) = 0; + OMP_CLAUSE_CODE (loop_iv_seen) = OMP_CLAUSE_FIRSTPRIVATE; + } + if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_FIRSTPRIVATE) + cxx_omp_finish_clause (loop_iv_seen, NULL); + } orig_pre_body = *pre_body; *pre_body = push_stmt_list (); @@ -8825,9 +8848,7 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, omp_for = NULL_TREE; if (omp_for == NULL) - { - return NULL; - } + return NULL; add_stmt (omp_for); @@ -8926,6 +8947,16 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, gcc_unreachable (); } } + /* Override saved methods on OMP_LOOP's OMP_CLAUSE_LASTPRIVATE_LOOP_IV + clauses, we need copy ctor for those rather than default ctor, + plus as for other lastprivates assignment op and dtor. */ + if (code == OMP_LOOP && !processing_template_decl) + for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE + && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) + && cxx_omp_create_clause_info (c, TREE_TYPE (OMP_CLAUSE_DECL (c)), + false, true, true, true)) + CP_OMP_CLAUSE_INFO (c) = NULL_TREE; return omp_for; } diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 6a1a7f0..10b9b68 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -775,14 +775,27 @@ gimple_add_tmp_var (tree tmp) if (gimplify_omp_ctxp) { struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; + int flag = GOVD_LOCAL; while (ctx && (ctx->region_type == ORT_WORKSHARE || ctx->region_type == ORT_TASKGROUP || ctx->region_type == ORT_SIMD || ctx->region_type == ORT_ACC)) - ctx = ctx->outer_context; + { + if (ctx->region_type == ORT_SIMD + && TREE_ADDRESSABLE (tmp) + && !TREE_STATIC (tmp)) + { + if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST) + ctx->add_safelen1 = true; + else + flag = GOVD_PRIVATE; + break; + } + ctx = ctx->outer_context; + } if (ctx) - omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN); + omp_add_variable (ctx, tmp, flag | GOVD_SEEN); } } else if (cfun) @@ -10590,6 +10603,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) orig_for_stmt = for_stmt = *expr_p; + bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND) + != NULL_TREE); if (OMP_FOR_INIT (for_stmt) == NULL_TREE) { tree *data[4] = { NULL, NULL, NULL, NULL }; @@ -10641,7 +10656,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) } for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++) - if (OMP_FOR_ORIG_DECLS (inner_for_stmt) + if (!loop_p + && OMP_FOR_ORIG_DECLS (inner_for_stmt) && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i)) == TREE_LIST && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), @@ -10649,7 +10665,9 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) { tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i); /* Class iterators aren't allowed on OMP_SIMD, so the only - case we need to solve is distribute parallel for. */ + case we need to solve is distribute parallel for. They are + allowed on the loop construct, but that is already handled + in gimplify_omp_loop. */ gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR && TREE_CODE (for_stmt) == OMP_DISTRIBUTE && data[1]); @@ -10791,8 +10809,6 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) } } - bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND) - != NULL_TREE); if (TREE_CODE (for_stmt) != OMP_TASKLOOP) gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort, loop_p && TREE_CODE (for_stmt) != OMP_SIMD @@ -11163,6 +11179,13 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) || !bitmap_bit_p (has_decl_expr, DECL_UID (decl))); if (TREE_PRIVATE (t)) lastprivate = false; + if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt)) + { + tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i); + if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt)) + lastprivate = false; + } + struct gimplify_omp_ctx *outer = gimplify_omp_ctxp->outer_context; if (outer && lastprivate) @@ -11485,7 +11508,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) BITMAP_FREE (has_decl_expr); - if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP) + if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP + || (loop_p && orig_for_stmt == for_stmt)) { push_gimplify_context (); if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR) @@ -11500,7 +11524,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt), &for_body); - if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP) + if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP + || (loop_p && orig_for_stmt == for_stmt)) { if (gimple_code (g) == GIMPLE_BIND) pop_gimplify_context (g); @@ -11540,6 +11565,11 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) default: gcc_unreachable (); } + if (loop_p && kind == GF_OMP_FOR_KIND_SIMD) + { + gimplify_seq_add_seq (pre_p, for_pre_body); + for_pre_body = NULL; + } gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt), TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)), for_pre_body); @@ -11640,7 +11670,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) a shared clause on task. If the same decl is also firstprivate, add also firstprivate clause on the inner taskloop. */ case OMP_CLAUSE_LASTPRIVATE: - if (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c)) + if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)) { /* For taskloop C++ lastprivate IVs, we want: 1) private on outer taskloop @@ -11963,6 +11993,21 @@ gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p) OMP_PARALLEL_BODY (*expr_p) = bind; OMP_PARALLEL_COMBINED (*expr_p) = 1; SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt)); + tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p); + for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) + if (OMP_FOR_ORIG_DECLS (for_stmt) + && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i)) + == TREE_LIST)) + { + tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i); + if (TREE_PURPOSE (elt) && TREE_VALUE (elt)) + { + *pc = build_omp_clause (UNKNOWN_LOCATION, + OMP_CLAUSE_FIRSTPRIVATE); + OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt); + pc = &OMP_CLAUSE_CHAIN (*pc); + } + } } tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR); tree *pc = &OMP_FOR_CLAUSES (t); @@ -11979,12 +12024,29 @@ gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p) pc = &OMP_CLAUSE_CHAIN (*pc); break; case OMP_CLAUSE_PRIVATE: + case OMP_CLAUSE_FIRSTPRIVATE: /* Only needed on innermost. */ break; case OMP_CLAUSE_LASTPRIVATE: + if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last) + { + *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c), + OMP_CLAUSE_FIRSTPRIVATE); + OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c); + lang_hooks.decls.omp_finish_clause (*pc, NULL); + pc = &OMP_CLAUSE_CHAIN (*pc); + } *pc = copy_node (c); OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE; TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c)); + if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)) + { + if (pass != last) + OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1; + else + lang_hooks.decls.omp_finish_clause (*pc, NULL); + OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0; + } pc = &OMP_CLAUSE_CHAIN (*pc); break; case OMP_CLAUSE_REDUCTION: diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 5d1b88c..4a6ea0a 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -5139,8 +5139,17 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, x = NULL; do_private: tree nx; - nx = lang_hooks.decls.omp_clause_default_ctor - (c, unshare_expr (new_var), x); + bool copy_ctor; + copy_ctor = false; + nx = unshare_expr (new_var); + if (is_simd + && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE + && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)) + copy_ctor = true; + if (copy_ctor) + nx = lang_hooks.decls.omp_clause_copy_ctor (c, nx, x); + else + nx = lang_hooks.decls.omp_clause_default_ctor (c, nx, x); if (is_simd) { tree y = lang_hooks.decls.omp_clause_dtor (c, new_var); @@ -5165,8 +5174,16 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, } if (nx) - x = lang_hooks.decls.omp_clause_default_ctor - (c, unshare_expr (ivar), x); + { + tree iv = unshare_expr (ivar); + if (copy_ctor) + x = lang_hooks.decls.omp_clause_copy_ctor (c, iv, + x); + else + x = lang_hooks.decls.omp_clause_default_ctor (c, + iv, + x); + } else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_) { x = build2 (MODIFY_EXPR, TREE_TYPE (ivar), @@ -6469,9 +6486,9 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p, x = NULL_TREE; if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE - && OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c)) + && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) + && is_taskloop_ctx (ctx)) { - gcc_checking_assert (is_taskloop_ctx (ctx)); tree ovar = maybe_lookup_decl_in_outer_ctx (var, ctx->outer->outer); if (is_global_var (ovar)) @@ -1517,10 +1517,11 @@ class auto_suppress_location_wrappers #define OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ(NODE) \ (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init -/* True if a LASTPRIVATE clause is for a C++ class IV on taskloop construct - (thus should be lastprivate on the outer taskloop and firstprivate on - task). */ -#define OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV(NODE) \ +/* True if a LASTPRIVATE clause is for a C++ class IV on taskloop or + loop construct (thus should be lastprivate on the outer taskloop and + firstprivate on task for the taskloop construct and carefully handled + for loop construct). */ +#define OMP_CLAUSE_LASTPRIVATE_LOOP_IV(NODE) \ TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LASTPRIVATE)) /* True if a LASTPRIVATE clause has CONDITIONAL: modifier. */ |