aboutsummaryrefslogtreecommitdiff
path: root/gcc/omp-low.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-11-23 19:28:41 +0000
committerJakub Jelinek <jakub@redhat.com>2016-11-23 19:28:41 +0000
commitf70405c4b8886aa1aa77eb5ef8f099efcbf61262 (patch)
tree5d06b113ac247902a7dfb85ee5f1f7021a0eaf1d /gcc/omp-low.c
parent7082643e636e2edd6d90278521083d8899e9a07d (diff)
PR middle-end/69183
* omp-low.c (build_outer_var_ref): Change lastprivate argument to code, pass it recursively, adjust uses. For OMP_CLAUSE_PRIVATE on worksharing constructs, treat it like clauses on simd construct. Formatting fix. (lower_rec_input_clauses): For OMP_CLAUSE_PRIVATE_OUTER_REF pass OMP_CLAUSE_PRIVATE as last argument to build_outer_var_ref. (lower_lastprivate_clauses): Pass OMP_CLAUSE_LASTPRIVATE instead of true as last argument to build_outer_var_ref. * gfortran.dg/gomp/pr69183.f90: New test. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@242793 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/omp-low.c')
-rw-r--r--gcc/omp-low.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 3eff4e7f1e8..7bcaeee2409 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -1283,7 +1283,8 @@ build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
this is some variable. */
static tree
-build_outer_var_ref (tree var, omp_context *ctx, bool lastprivate = false)
+build_outer_var_ref (tree var, omp_context *ctx,
+ enum omp_clause_code code = OMP_CLAUSE_ERROR)
{
tree x;
@@ -1292,7 +1293,7 @@ build_outer_var_ref (tree var, omp_context *ctx, bool lastprivate = false)
else if (is_variable_sized (var))
{
x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
- x = build_outer_var_ref (x, ctx, lastprivate);
+ x = build_outer_var_ref (x, ctx, code);
x = build_simple_mem_ref (x);
}
else if (is_taskreg_ctx (ctx))
@@ -1300,11 +1301,17 @@ build_outer_var_ref (tree var, omp_context *ctx, bool lastprivate = false)
bool by_ref = use_pointer_for_field (var, NULL);
x = build_receiver_ref (var, by_ref, ctx);
}
- else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
- {
- /* #pragma omp simd isn't a worksharing construct, and can reference even
- private vars in its linear etc. clauses. */
+ else if ((gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
+ || (code == OMP_CLAUSE_PRIVATE
+ && (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ || gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS
+ || gimple_code (ctx->stmt) == GIMPLE_OMP_SINGLE)))
+ {
+ /* #pragma omp simd isn't a worksharing construct, and can reference
+ even private vars in its linear etc. clauses.
+ Similarly for OMP_CLAUSE_PRIVATE with outer ref, that can refer
+ to private vars in all worksharing constructs. */
x = NULL_TREE;
if (ctx->outer && is_taskreg_ctx (ctx))
x = lookup_decl (var, ctx->outer);
@@ -1313,7 +1320,7 @@ build_outer_var_ref (tree var, omp_context *ctx, bool lastprivate = false)
if (x == NULL_TREE)
x = var;
}
- else if (lastprivate && is_taskloop_ctx (ctx))
+ else if (code == OMP_CLAUSE_LASTPRIVATE && is_taskloop_ctx (ctx))
{
gcc_assert (ctx->outer);
splay_tree_node n
@@ -1350,7 +1357,7 @@ build_outer_var_ref (tree var, omp_context *ctx, bool lastprivate = false)
gcc_assert (outer
&& gimple_code (outer->stmt) != GIMPLE_OMP_GRID_BODY);
}
- x = lookup_decl (var, outer);
+ x = lookup_decl (var, outer);
}
else if (is_reference (var))
/* This can happen with orphaned constructs. If var is reference, it is
@@ -5031,7 +5038,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
if (is_task_ctx (ctx))
x = build_receiver_ref (var, false, ctx);
else
- x = build_outer_var_ref (var, ctx);
+ x = build_outer_var_ref (var, ctx, OMP_CLAUSE_PRIVATE);
}
else
x = NULL;
@@ -5697,7 +5704,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
x = ovar;
}
if (!x)
- x = build_outer_var_ref (var, ctx, true);
+ x = build_outer_var_ref (var, ctx, OMP_CLAUSE_LASTPRIVATE);
if (is_reference (var))
new_var = build_simple_mem_ref_loc (clause_loc, new_var);
x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);