re PR middle-end/25261 ([gomp] Nested function calls in #pragma omp parallel blocks)

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.

	* gcc.dg/gomp/nestedfn-1.c: New test.

	* testsuite/libgomp.c/nestedfn-4.c: New test.
	* testsuite/libgomp.c/nestedfn-5.c: New test.
	* testsuite/libgomp.fortran/nestedfn3.f90: New test.

From-SVN: r117235
This commit is contained in:
Jakub Jelinek 2006-09-26 20:10:58 +02:00 committed by Jakub Jelinek
parent 9b9e4cd6a9
commit a70ad3bb3e
8 changed files with 238 additions and 3 deletions

View File

@ -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.

View File

@ -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

View File

@ -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;
}

View File

@ -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:

View File

@ -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.

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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