This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gomp] Diagnostics for invalid firstprivate/lastprivate/reduction


Hi!

As this PR got a second dup, guess it is time to fix it.
firstprivate/lastprivate/reduction on a worksharing construct
requires the variable to be shared in the outer context.
Often we only know at runtime what will it bind to, but
if an orphaned worksharing construct references a local variable
in the containing function, we ICE in build_outer_var_ref.

The following patch diagnoses where we can prove it the variable
can't be possibly shared in the outer context and avoids the ICEs.

Ok for trunk/4.2?

2007-01-23  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/27416
	* gimplify.c (omp_check_private): New function.
	(gimplify_scan_omp_clauses): Use it for
	firstprivate/lastprivate/reduction.

	* gcc.dg/gomp/pr27416.c: New test.

--- gcc/gimplify.c.jj	2007-01-23 21:21:13.000000000 +0100
+++ gcc/gimplify.c	2007-01-23 21:34:59.000000000 +0100
@@ -4667,6 +4667,31 @@ omp_is_private (struct gimplify_omp_ctx 
     return !is_global_var (decl);
 }
 
+/* Return true if DECL is private within a parallel region
+   that binds to the current construct's context or in parallel
+   region's REDUCTION clause.  */
+
+static bool
+omp_check_private (struct gimplify_omp_ctx *ctx, tree decl)
+{
+  splay_tree_node n;
+
+  do
+    {
+      ctx = ctx->outer_context;
+      if (ctx == NULL)
+	return !(is_global_var (decl)
+		 /* References might be private, but might be shared too.  */
+		 || lang_hooks.decls.omp_privatize_by_reference (decl));
+
+      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
+      if (n != NULL)
+	return (n->value & GOVD_SHARED) == 0;
+    }
+  while (!ctx->is_parallel);
+  return false;
+}
+
 /* Scan the OpenMP clauses in *LIST_P, installing mappings into a new
    and previous omp contexts.  */
 
@@ -4685,6 +4710,7 @@ gimplify_scan_omp_clauses (tree *list_p,
       enum gimplify_status gs;
       bool remove = false;
       bool notice_outer = true;
+      const char *check_non_private = NULL;
       unsigned int flags;
       tree decl;
 
@@ -4699,12 +4725,15 @@ gimplify_scan_omp_clauses (tree *list_p,
 	  goto do_add;
 	case OMP_CLAUSE_FIRSTPRIVATE:
 	  flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
+	  check_non_private = "firstprivate";
 	  goto do_add;
 	case OMP_CLAUSE_LASTPRIVATE:
 	  flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
+	  check_non_private = "lastprivate";
 	  goto do_add;
 	case OMP_CLAUSE_REDUCTION:
 	  flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
+	  check_non_private = "reduction";
 	  goto do_add;
 
 	do_add:
@@ -4754,6 +4783,14 @@ gimplify_scan_omp_clauses (tree *list_p,
 	do_notice:
 	  if (outer_ctx)
 	    omp_notice_variable (outer_ctx, decl, true);
+	  if (check_non_private
+	      && !in_parallel
+	      && omp_check_private (ctx, decl))
+	    {
+	      error ("%s variable %qs is private in outer context",
+		     check_non_private, IDENTIFIER_POINTER (DECL_NAME (decl)));
+	      remove = true;
+	    }
 	  break;
 
 	case OMP_CLAUSE_IF:
--- gcc/testsuite/gcc.dg/gomp/pr27416.c.jj	2007-01-23 21:26:51.000000000 +0100
+++ gcc/testsuite/gcc.dg/gomp/pr27416.c	2007-01-23 21:26:12.000000000 +0100
@@ -0,0 +1,31 @@
+/* PR middle-end/27416 */
+/* { dg-do compile } */
+
+void
+foo (void)
+{
+  int i = 0, j = 0;
+#pragma omp for firstprivate (j) /* { dg-error "is private in outer context" } */
+  for (i = 0; i < 10; i++)
+    j++;
+}
+
+int
+bar (void)
+{
+  int i, j;
+#pragma omp for lastprivate (j)	/* { dg-error "is private in outer context" } */
+  for (i = 0; i < 10; i++)
+    j = i;
+  return j;
+}
+
+int
+baz (void)
+{
+  int i, j = 0;
+#pragma omp for reduction (+:j)	/* { dg-error "is private in outer context" } */
+  for (i = 0; i < 10; i++)
+    j++;
+  return j;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]