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/gimplify.c | |
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/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 80 |
1 files changed, 71 insertions, 9 deletions
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: |