This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gomp] fix sharing in nested scopes
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 29 Sep 2005 16:25:12 -0700
- Subject: [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;
+}