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 sharing in nested scopes


        * omp-low.c (use_pointer_for_field): True for shared variables
        with DECL_HAS_VALUE_EXPR_P set.

Index: gcc/omp-low.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/omp-low.c,v
retrieving revision 1.1.2.10
diff -u -p -d -r1.1.2.10 omp-low.c
--- gcc/omp-low.c	28 Sep 2005 17:08:34 -0000	1.1.2.10
+++ gcc/omp-low.c	29 Sep 2005 23:22:06 -0000
@@ -132,8 +132,24 @@ use_pointer_for_field (tree decl, bool s
   if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
     return true;
 
-  if (shared_p && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
-    return true;
+  /* We can only use copy-in/copy-out semantics for shared varibles
+     when we know the value is not accessible from an outer scope.  */
+  if (shared_p)
+    {
+      /* ??? Trivially accessible from anywhere.  But why would we even
+	 be passing an address in this case?  Should we simply assert
+	 this to be false, or should we have a cleanup pass that removes
+	 these from the list of mappings?  */
+      if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
+	return true;
+
+      /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
+	 without analyzing the expression whether or not its location
+	 is accessible to anyone else.  In the case of nested parallel
+	 regions it certainly may be.  */
+      if (DECL_HAS_VALUE_EXPR_P (decl))
+	return true;
+    }
 
   return false;
 }
Index: libgomp/testsuite/libgomp.dg/omp-nested-1.c
===================================================================
RCS file: libgomp/testsuite/libgomp.dg/omp-nested-1.c
diff -N libgomp/testsuite/libgomp.dg/omp-nested-1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libgomp/testsuite/libgomp.dg/omp-nested-1.c	29 Sep 2005 23:22:06 -0000
@@ -0,0 +1,28 @@
+// { dg-do run }
+
+extern void abort(void);
+#define N 1000
+
+int foo()
+{
+  int i = 0, j;
+
+  #pragma omp parallel for num_threads(2) shared (i)
+  for (j = 0; j < N; ++j)
+    {
+      #pragma omp parallel num_threads(1) shared (i)
+      {
+	#pragma omp atomic
+	i++;
+      }
+    }
+
+  return i;
+}
+
+int main()
+{
+  if (foo() != N)
+    abort ();
+  return 0;
+}


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