aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/ChangeLog26
-rw-r--r--gcc/cp/ChangeLog25
-rw-r--r--gcc/cp/constexpr.c1
-rw-r--r--gcc/cp/cp-gimplify.c12
-rw-r--r--gcc/cp/parser.c11
-rw-r--r--gcc/cp/pt.c9
-rw-r--r--gcc/cp/semantics.c53
-rw-r--r--gcc/gimplify.c80
-rw-r--r--gcc/omp-low.c29
-rw-r--r--gcc/tree.h9
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))
diff --git a/gcc/tree.h b/gcc/tree.h
index d5fb3b2..ce75b0c 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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. */