aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-05-12 14:11:00 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2010-05-12 14:11:00 +0200
commitf22f434020d20d8d12bf5171cbb7ba720808ac15 (patch)
tree7303bd5cc39e81125c26e6d6f98ccc7eb2175c34 /gcc/gimplify.c
parent7c2db0d3628062fc4fc9227c2e3ac4922b10f059 (diff)
downloadgcc-f22f434020d20d8d12bf5171cbb7ba720808ac15.zip
gcc-f22f434020d20d8d12bf5171cbb7ba720808ac15.tar.gz
gcc-f22f434020d20d8d12bf5171cbb7ba720808ac15.tar.bz2
re PR middle-end/44085 (OpenMP - untied task accesses threadprivate - non-conforming but no msg)
PR middle-end/44085 * gimplify.c (enum omp_region_type): Add ORT_UNTIED_TASK, change value of ORT_TASK. (new_omp_context): Handle ORT_UNTIED_TASK like ORT_TASK. (omp_notice_threadprivate_variable): New function. (omp_notice_variable): Call it for threadprivate variables. If enclosing ctx is a task, print enclosing task rather than enclosing parallel. Handle ORT_UNTIED_TASK like ORT_TASK. (gimplify_omp_task): Pass ORT_UNTIED_TASK instead of ORT_TASK if task has untied clause. * gcc.dg/gomp/pr44085.c: New test. * gfortran.dg/gomp/pr44085.f90: New test. From-SVN: r159316
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r--gcc/gimplify.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index f6266e1..c741891 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -74,9 +74,10 @@ enum gimplify_omp_var_data
enum omp_region_type
{
ORT_WORKSHARE = 0,
- ORT_TASK = 1,
ORT_PARALLEL = 2,
- ORT_COMBINED_PARALLEL = 3
+ ORT_COMBINED_PARALLEL = 3,
+ ORT_TASK = 4,
+ ORT_UNTIED_TASK = 5
};
struct gimplify_omp_ctx
@@ -318,7 +319,7 @@ new_omp_context (enum omp_region_type region_type)
c->privatized_types = pointer_set_create ();
c->location = input_location;
c->region_type = region_type;
- if (region_type != ORT_TASK)
+ if ((region_type & ORT_TASK) == 0)
c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
else
c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
@@ -5470,6 +5471,31 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
}
+/* Notice a threadprivate variable DECL used in OpenMP context CTX.
+ This just prints out diagnostics about threadprivate variable uses
+ in untied tasks. If DECL2 is non-NULL, prevent this warning
+ on that variable. */
+
+static bool
+omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
+ tree decl2)
+{
+ splay_tree_node n;
+
+ if (ctx->region_type != ORT_UNTIED_TASK)
+ return false;
+ n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
+ if (n == NULL)
+ {
+ error ("threadprivate variable %qE used in untied task", DECL_NAME (decl));
+ error_at (ctx->location, "enclosing task");
+ splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
+ }
+ if (decl2)
+ splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
+ return false;
+}
+
/* Record the fact that DECL was used within the OpenMP context CTX.
IN_CODE is true when real code uses DECL, and false when we should
merely emit default(none) errors. Return true if DECL is going to
@@ -5490,14 +5516,14 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
if (is_global_var (decl))
{
if (DECL_THREAD_LOCAL_P (decl))
- return false;
+ return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
if (DECL_HAS_VALUE_EXPR_P (decl))
{
tree value = get_base_address (DECL_VALUE_EXPR (decl));
if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
- return false;
+ return omp_notice_threadprivate_variable (ctx, decl, value);
}
}
@@ -5523,7 +5549,10 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
case OMP_CLAUSE_DEFAULT_NONE:
error ("%qE not specified in enclosing parallel",
DECL_NAME (decl));
- error_at (ctx->location, "enclosing parallel");
+ if ((ctx->region_type & ORT_TASK) != 0)
+ error_at (ctx->location, "enclosing task");
+ else
+ error_at (ctx->location, "enclosing parallel");
/* FALLTHRU */
case OMP_CLAUSE_DEFAULT_SHARED:
flags |= GOVD_SHARED;
@@ -5536,7 +5565,7 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
break;
case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
/* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
- gcc_assert (ctx->region_type == ORT_TASK);
+ gcc_assert ((ctx->region_type & ORT_TASK) != 0);
if (ctx->outer_context)
omp_notice_variable (ctx->outer_context, decl, in_code);
for (octx = ctx->outer_context; octx; octx = octx->outer_context)
@@ -6039,7 +6068,10 @@ gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
gimple_seq body = NULL;
struct gimplify_ctx gctx;
- gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p, ORT_TASK);
+ gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
+ find_omp_clause (OMP_TASK_CLAUSES (expr),
+ OMP_CLAUSE_UNTIED)
+ ? ORT_UNTIED_TASK : ORT_TASK);
push_gimplify_context (&gctx);