From f70405c4b8886aa1aa77eb5ef8f099efcbf61262 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 23 Nov 2016 19:28:41 +0000 Subject: 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 --- gcc/omp-low.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'gcc/omp-low.c') 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); -- cgit v1.2.3