aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-08-06 09:26:32 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2019-08-06 09:26:32 +0200
commitd81ab49d0586fca0f3ee2f49c4581dd02508fcca (patch)
treed3d4e04d7c7e987c478e88417ded02a08e3e8aad /gcc/gimplify.c
parent7551a6e467c64b3155d5b8f005cd7ea7143b21f3 (diff)
downloadgcc-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.c80
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: