[gomp] Implement the special data sharing rules for implicit determination for task constructs

Jakub Jelinek jakub@redhat.com
Fri Nov 30 20:52:00 GMT 2007


Hi!

C/C++
"In an orphaned task construct, if no default clause is present, formal arguments
of the enclosing routine are firstprivate in the generated task."

Fortran
"In an orphaned task construct, if no default clause is present, dummy arguments
of the enclosing program unit are firstprivate in the generated task."

"In a task construct, if no default clause is present, a variable that is private in
any of the enclosing scopes within the innermost enclosing parallel construct, if
one exists, or is private within the enclosing routine if no enclosing parallel
construct exists, is firstprivate in the generated task."

"In a task construct, if no default clause is present, variables whose data-sharing
attributes are not determined by the three rules above are shared in the generated
task."

This patch implements that, though perhaps Fortran dummy arguments which are
passed by reference will need some further adjustments - we'll get there
when we adjust the Fortran parser to handle !$omp task.

BTW, as can be seen in the testcase I had to comment out one test, which
doesn't seem to be caused by a bug in this patch, in fact can be also
reproduced with some worksharing orphaned construct with privatized
global var containing parallel region which has firstprivate clause for
the same var.  So, I will work on a separate fix for that, which is
desirable even for 4.2/trunk and once that is in, we can adjust the testcase
and remove FIXME from it.

Committed to gomp-3_0-branch.

2007-11-30  Jakub Jelinek  <jakub@redhat.com>

	* gimplify.c (new_omp_context): Set default_kind to
	OMP_CLAUSE_DEFAULT_UNSPECIFIED for OMP_TASK regions.
	(omp_notice_variable): Handle vars that are supposed
	to be implicitly determined firstprivate for task regions.

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

--- gcc/gimplify.c.jj	2007-11-30 09:02:16.000000000 +0100
+++ gcc/gimplify.c	2007-11-30 16:55:36.000000000 +0100
@@ -286,7 +286,10 @@ new_omp_context (enum omp_region_type re
   c->privatized_types = pointer_set_create ();
   c->location = input_location;
   c->region_type = region_type;
-  c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
+  if (region_type != ORT_TASK)
+    c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
+  else
+    c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
 
   return c;
 }
@@ -4731,6 +4734,7 @@ omp_notice_variable (struct gimplify_omp
   if (n == NULL)
     {
       enum omp_clause_default_kind default_kind, kind;
+      struct gimplify_omp_ctx *octx;
 
       if (ctx->region_type == ORT_WORKSHARE)
 	goto do_outer;
@@ -4756,6 +4760,36 @@ omp_notice_variable (struct gimplify_omp
 	case OMP_CLAUSE_DEFAULT_PRIVATE:
 	  flags |= GOVD_PRIVATE;
 	  break;
+	case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
+	  /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED.  */
+	  gcc_assert (ctx->region_type == ORT_TASK);
+	  if (ctx->outer_context)
+	    omp_notice_variable (ctx->outer_context, decl, in_code);
+	  for (octx = ctx->outer_context; octx; octx = octx->outer_context)
+	    {
+	      splay_tree_node n2;
+
+	      n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
+	      if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
+		{
+		  flags |= GOVD_FIRSTPRIVATE;
+		  break;
+		}
+	      if ((octx->region_type & ORT_PARALLEL) != 0)
+		break;
+	    }
+	  if (flags & GOVD_FIRSTPRIVATE)
+	    break;
+	  if (octx == NULL
+	      && (TREE_CODE (decl) == PARM_DECL
+		  || (!is_global_var (decl)
+		      && DECL_CONTEXT (decl) == current_function_decl)))
+	    {
+	      flags |= GOVD_FIRSTPRIVATE;
+	      break;
+	    }
+	  flags |= GOVD_SHARED;
+	  break;
 	default:
 	  gcc_unreachable ();
 	}
--- libgomp/testsuite/libgomp.c/task-1.c.jj	2007-11-30 17:57:37.000000000 +0100
+++ libgomp/testsuite/libgomp.c/task-1.c	2007-11-30 17:56:38.000000000 +0100
@@ -0,0 +1,57 @@
+extern void abort (void);
+
+int a = 18;
+
+void
+f1 (int i, int j, int k)
+{
+  int l = 6, m = 7, n = 8;
+#pragma omp task private(j, m) shared(k, n)
+  {
+    j = 6;
+    m = 5;
+    if (++a != 19 || ++i != 9 || j != 6 || ++l != 7 || m != 5 || ++n != 9)
+      #pragma omp atomic
+	k++;
+  }
+#pragma omp taskwait
+  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 task
+	{
+	  if (0 && ++v1 != 8)	/* FIXME - this is broken ATM.  */
+	    err = 1;
+	  if (++v2 != 3 || ++v3 != 4 || ++v4 != 5 || ++v5 != 6)
+	    err = 1;
+	}
+      #pragma omp taskwait
+      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



More information about the Gcc-patches mailing list