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] Fix OpenMP lookup in outer contexts


Hi!

This patch fixes something I discovered while working on gomp-3_0-branch
stuff, but it as shown on the testcase can be easily reproduced even
with OpenMP 2.5 constructs.

We were only trying to look decls in outer contexts if this was a nested
parallel, but even if a parallel (or for 3.0 task) is within an orphaned
worksharing construct which privatizes some variables the maybe_lookup_decl
calls are needed, otherwise we might use a global var rather than what the
outer worksharing construct privatized.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2007-12-03  Jakub Jelinek  <jakub@redhat.com>

	* omp-low.c (lookup_decl_in_outer_ctx): Allow calling this
	with !ctx->is_nested.
	(maybe_lookup_decl_in_outer_ctx): Look up in outer contexts
	even if !ctx->is_nested.
	(lower_copyprivate_clauses, lower_send_clauses,
	lower_send_shared_vars): Call lookup_decl_in_outer_ctx
	unconditionally.

	* testsuite/libgomp.c/private-1.c: New test.

--- gcc/omp-low.c.jj	2007-11-26 11:02:19.000000000 +0100
+++ gcc/omp-low.c	2007-12-03 20:59:37.000000000 +0100
@@ -1518,12 +1518,10 @@ lookup_decl_in_outer_ctx (tree decl, omp
   tree t;
   omp_context *up;
 
-  gcc_assert (ctx->is_nested);
-
   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
     t = maybe_lookup_decl (decl, up);
 
-  gcc_assert (t || is_global_var (decl));
+  gcc_assert (!ctx->is_nested || t || is_global_var (decl));
 
   return t ? t : decl;
 }
@@ -1538,9 +1536,8 @@ maybe_lookup_decl_in_outer_ctx (tree dec
   tree t = NULL;
   omp_context *up;
 
-  if (ctx->is_nested)
-    for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
-      t = maybe_lookup_decl (decl, up);
+  for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
+    t = maybe_lookup_decl (decl, up);
 
   return t ? t : decl;
 }
@@ -2012,7 +2009,7 @@ lower_copyprivate_clauses (tree clauses,
       by_ref = use_pointer_for_field (var, false);
 
       ref = build_sender_ref (var, ctx);
-      x = (ctx->is_nested) ? lookup_decl_in_outer_ctx (var, ctx) : var;
+      x = lookup_decl_in_outer_ctx (var, ctx);
       x = by_ref ? build_fold_addr_expr (x) : x;
       x = build_gimple_modify_stmt (ref, x);
       gimplify_and_add (x, slist);
@@ -2053,9 +2050,8 @@ lower_send_clauses (tree clauses, tree *
 	  continue;
 	}
 
-      var = val = OMP_CLAUSE_DECL (c);
-      if (ctx->is_nested)
-	var = lookup_decl_in_outer_ctx (val, ctx);
+      val = OMP_CLAUSE_DECL (c);
+      var = lookup_decl_in_outer_ctx (val, ctx);
 
       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
 	  && is_global_var (var))
@@ -2127,13 +2123,10 @@ lower_send_shared_vars (tree *ilist, tre
       if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
 	continue;
 
-      var = ovar;
-
       /* If CTX is a nested parallel directive.  Find the immediately
 	 enclosing parallel or workshare construct that contains a
 	 mapping for OVAR.  */
-      if (ctx->is_nested)
-	var = lookup_decl_in_outer_ctx (ovar, ctx);
+      var = lookup_decl_in_outer_ctx (ovar, ctx);
 
       if (use_pointer_for_field (ovar, true))
 	{
--- libgomp/testsuite/libgomp.c/private-1.c.jj	2007-12-03 20:39:01.000000000 +0100
+++ libgomp/testsuite/libgomp.c/private-1.c	2007-11-30 17:35:25.000000000 +0100
@@ -0,0 +1,54 @@
+extern void abort (void);
+
+int a = 18;
+
+void
+f1 (int i, int j, int k)
+{
+  int l = 6, m = 7, n = 8;
+#pragma omp parallel private(j, m) shared(k, n) firstprivate(i, l) \
+	    num_threads(1)
+  {
+    j = 6;
+    m = 5;
+    if (++a != 19 || ++i != 9 || j != 6 || ++l != 7 || m != 5 || ++n != 9)
+      #pragma omp atomic
+	k++;
+  }
+  if (a != 19 || i != 8 || j != 26 || k != 0 || l != 6 || m != 7 || n != 9)
+    abort ();
+}
+
+int v1 = 1, v2 = 2, v5 = 5;
+int err;
+
+void
+f2 (void)
+{
+  int v3 = 3;
+#pragma omp sections private (v1) firstprivate (v2)
+  {
+  #pragma omp section
+    {
+      int v4 = 4;
+      v1 = 7;
+      #pragma omp parallel num_threads(1) firstprivate(v1, v2, v3, v4)
+	{
+	  if (++v1 != 8 || ++v2 != 3 || ++v3 != 4 || ++v4 != 5 || ++v5 != 6)
+	    err = 1;
+	}
+      if (v1 != 7 || v2 != 2 || v3 != 3 || v4 != 4 || v5 != 6)
+	abort ();
+      if (err)
+	abort ();
+    }
+  }
+}
+
+int
+main (void)
+{
+  f1 (8, 26, 0);
+  f2 ();
+  return 0;
+}

	Jakub


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