2010-05-12 Jakub Jelinek <jakub@redhat.com>
+ 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.
+
PR debug/42278
* dwarf2out.c (base_type_die): Don't add name attribute here.
(modified_type_die): Instead of sizetype use
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
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;
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
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);
}
}
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;
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)
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);
--- /dev/null
+! PR middle-end/44085
+! { dg-do compile }
+! { dg-require-effective-target tls_native }
+! { dg-options "-fopenmp" }
+
+ integer, save :: thr1, thr2
+ integer :: thr3, thr4
+ common /thrs/ thr3, thr4
+!$omp threadprivate (thr1, thr2, /thrs/)
+
+!$omp task untied ! { dg-error "enclosing task" }
+ thr1 = thr1 + 1 ! { dg-error "used in untied task" }
+ thr2 = thr2 + 2 ! { dg-error "used in untied task" }
+ thr3 = thr3 + 3 ! { dg-error "used in untied task" }
+ thr4 = thr4 + 4 ! { dg-error "used in untied task" }
+!$omp end task
+
+!$omp task
+ thr1 = thr1 + 1
+ thr2 = thr2 + 2
+ thr3 = thr3 + 3
+ thr4 = thr4 + 4
+!$omp end task
+
+ end