summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/gomp/nestedfn-1.c53
-rw-r--r--gcc/tree-nested.c41
-rw-r--r--libgomp/ChangeLog6
-rw-r--r--libgomp/testsuite/libgomp.c/nestedfn-4.c65
-rw-r--r--libgomp/testsuite/libgomp.c/nestedfn-5.c38
-rw-r--r--libgomp/testsuite/libgomp.fortran/nestedfn3.f9024
8 files changed, 238 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e394cb7b9ac..4a167ddb47a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2006-09-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/25261
+ PR middle-end/28790
+ * tree-nested.c (struct nesting_info): Added static_chain_added.
+ (convert_call_expr): Set static_chain_added when adding static
+ chain. Handle OMP_PARALLEL and OMP_SECTION.
+
2006-09-25 Matthias Klose <doko@debian.org>
* doc/invoke.texi: Add missing full stop.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b196528b820..836f23615cd 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2006-09-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/25261
+ PR middle-end/28790
+ * gcc.dg/gomp/nestedfn-1.c: New test.
+
2006-09-26 Andrew Pinski <pinskia@physics.uc.edu>
PR objc/29195
diff --git a/gcc/testsuite/gcc.dg/gomp/nestedfn-1.c b/gcc/testsuite/gcc.dg/gomp/nestedfn-1.c
new file mode 100644
index 00000000000..8532d8af1af
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/nestedfn-1.c
@@ -0,0 +1,53 @@
+/* This testcase violates the OpenMP requirements, as nested functions
+ access the original variables.
+ We test it just to make sure we don't ICE on it. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp" } */
+
+extern void abort (void);
+extern int omp_get_thread_num ();
+extern void omp_set_dynamic (int);
+
+int
+main (void)
+{
+ int j = 0, k = 6, l = 7, m = 8;
+ void foo (void)
+ {
+ int i = 5;
+ int bar (void)
+ {
+ return i + 1 + (j > 100 ? 10000 : 0);
+ }
+#pragma omp sections private (i)
+ {
+#pragma omp section
+ {
+ i = 6;
+ if (bar () != 6)
+#pragma omp atomic
+ ++j;
+ }
+#pragma omp section
+ {
+ if (bar () != 6)
+#pragma omp atomic
+ ++j;
+ }
+ }
+ if (k != 6 || l != 7 || m != 8)
+#pragma omp atomic
+ ++j;
+ }
+ omp_set_dynamic (0);
+#pragma omp parallel num_threads (2) firstprivate (k) shared (l) private (m)
+ {
+ if (omp_get_thread_num () != 0)
+ k += omp_get_thread_num ();
+ m = 9;
+ foo ();
+ }
+ if (j)
+ abort ();
+ return 0;
+}
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 591642c732c..7467dca84e6 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -1,5 +1,5 @@
/* Nested function decomposition for trees.
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GCC.
@@ -104,6 +104,7 @@ struct nesting_info GTY ((chain_next ("%h.next")))
bool any_parm_remapped;
bool any_tramp_created;
+ char static_chain_added;
};
@@ -1626,6 +1627,8 @@ convert_call_expr (tree *tp, int *walk_subtrees, void *data)
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
struct nesting_info *info = wi->info;
tree t = *tp, decl, target_context;
+ char save_static_chain_added;
+ int i;
*walk_subtrees = 0;
switch (TREE_CODE (t))
@@ -1636,8 +1639,12 @@ convert_call_expr (tree *tp, int *walk_subtrees, void *data)
break;
target_context = decl_function_context (decl);
if (target_context && !DECL_NO_STATIC_CHAIN (decl))
- TREE_OPERAND (t, 2)
- = get_static_chain (info, target_context, &wi->tsi);
+ {
+ TREE_OPERAND (t, 2)
+ = get_static_chain (info, target_context, &wi->tsi);
+ info->static_chain_added
+ |= (1 << (info->context != target_context));
+ }
break;
case RETURN_EXPR:
@@ -1647,8 +1654,36 @@ convert_call_expr (tree *tp, int *walk_subtrees, void *data)
*walk_subtrees = 1;
break;
+ case OMP_PARALLEL:
+ save_static_chain_added = info->static_chain_added;
+ info->static_chain_added = 0;
+ walk_body (convert_call_expr, info, &OMP_PARALLEL_BODY (t));
+ for (i = 0; i < 2; i++)
+ {
+ tree c, decl;
+ if ((info->static_chain_added & (1 << i)) == 0)
+ continue;
+ decl = i ? get_chain_decl (info) : info->frame_decl;
+ /* Don't add CHAIN.* or FRAME.* twice. */
+ for (c = OMP_PARALLEL_CLAUSES (t); c; c = OMP_CLAUSE_CHAIN (c))
+ if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
+ && OMP_CLAUSE_DECL (c) == decl)
+ break;
+ if (c == NULL)
+ {
+ c = build_omp_clause (OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = decl;
+ OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (t);
+ OMP_PARALLEL_CLAUSES (t) = c;
+ }
+ }
+ info->static_chain_added |= save_static_chain_added;
+ break;
+
case OMP_FOR:
case OMP_SECTIONS:
+ case OMP_SECTION:
case OMP_SINGLE:
case OMP_MASTER:
case OMP_ORDERED:
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 229b27ab51a..a4c470cc703 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,5 +1,11 @@
2006-09-26 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/25261
+ PR middle-end/28790
+ * testsuite/libgomp.c/nestedfn-4.c: New test.
+ * testsuite/libgomp.c/nestedfn-5.c: New test.
+ * testsuite/libgomp.fortran/nestedfn3.f90: New test.
+
PR fortran/29097
* testsuite/libgomp.fortran/condinc1.f: New test.
* testsuite/libgomp.fortran/condinc2.f: New test.
diff --git a/libgomp/testsuite/libgomp.c/nestedfn-4.c b/libgomp/testsuite/libgomp.c/nestedfn-4.c
new file mode 100644
index 00000000000..dbe1062bddc
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/nestedfn-4.c
@@ -0,0 +1,65 @@
+/* PR middle-end/25261 */
+/* { dg-do run } */
+
+#include <omp.h>
+
+extern void abort (void);
+
+int
+main (void)
+{
+ int i = 5, j, l = 0;
+ int foo (void)
+ {
+ return i == 6;
+ }
+ int bar (void)
+ {
+ return i - 3;
+ }
+
+ omp_set_dynamic (0);
+
+#pragma omp parallel if (foo ()) num_threads (2)
+ if (omp_get_num_threads () != 1)
+#pragma omp atomic
+ l++;
+
+#pragma omp parallel for schedule (static, bar ()) num_threads (2) \
+ reduction (|:l)
+ for (j = 0; j < 4; j++)
+ if (omp_get_thread_num () != (j >= 2))
+#pragma omp atomic
+ l++;
+
+ i++;
+
+#pragma omp parallel if (foo ()) num_threads (2)
+ if (omp_get_num_threads () != 2)
+#pragma omp atomic
+ l++;
+
+#pragma omp parallel for schedule (static, bar ()) num_threads (2) \
+ reduction (|:l)
+ for (j = 0; j < 6; j++)
+ if (omp_get_thread_num () != (j >= 3))
+#pragma omp atomic
+ l++;
+
+#pragma omp parallel num_threads (4) reduction (|:l)
+ if (!foo () || bar () != 3)
+#pragma omp atomic
+ l++;
+
+ i++;
+
+#pragma omp parallel num_threads (4) reduction (|:l)
+ if (foo () || bar () != 4)
+#pragma omp atomic
+ l++;
+
+ if (l)
+ abort ();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/nestedfn-5.c b/libgomp/testsuite/libgomp.c/nestedfn-5.c
new file mode 100644
index 00000000000..6072b1fe369
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/nestedfn-5.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+void
+foo (int *j)
+{
+ int i = 5;
+ int bar (void) { return i + 1; }
+#pragma omp sections
+ {
+ #pragma omp section
+ {
+ if (bar () != 6)
+ #pragma omp atomic
+ ++*j;
+ }
+ #pragma omp section
+ {
+ if (bar () != 6)
+ #pragma omp atomic
+ ++*j;
+ }
+ }
+}
+
+int
+main (void)
+{
+ int j = 0;
+#pragma omp parallel num_threads (2)
+ foo (&j);
+ if (j)
+ abort ();
+ return 0;
+}
+
diff --git a/libgomp/testsuite/libgomp.fortran/nestedfn3.f90 b/libgomp/testsuite/libgomp.fortran/nestedfn3.f90
new file mode 100644
index 00000000000..454749c5485
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/nestedfn3.f90
@@ -0,0 +1,24 @@
+! PR middle-end/28790
+! { dg-do run }
+
+program nestomp
+ integer :: j
+ j = 8
+ call bar
+ if (j.ne.10) call abort
+contains
+ subroutine foo (i)
+ integer :: i
+ !$omp atomic
+ j = j + i - 5
+ end subroutine
+ subroutine bar
+ use omp_lib
+ integer :: i
+ i = 6
+ call omp_set_dynamic (.false.)
+ !$omp parallel num_threads (2)
+ call foo(i)
+ !$omp end parallel
+ end subroutine
+end