re PR other/39591 (GOMP_loop_end illegally optmized into GOMP_loop_end_nowait)

PR other/39591
	* omp-low.c (remove_exit_barrier): Don't optimize if there are any
	addressable variables in the parallel that could go out of scope while
	running queued tasks.

	* testsuite/libgomp.c/pr39591-1.c: New test.
	* testsuite/libgomp.c/pr39591-2.c: New test.
	* testsuite/libgomp.c/pr39591-3.c: New test.

From-SVN: r145390
This commit is contained in:
Jakub Jelinek 2009-04-01 08:54:52 +02:00 committed by Jakub Jelinek
parent 4223ff5f25
commit 03742a9b01
6 changed files with 174 additions and 3 deletions

View File

@ -1,3 +1,10 @@
2009-04-01 Jakub Jelinek <jakub@redhat.com>
PR other/39591
* omp-low.c (remove_exit_barrier): Don't optimize if there are any
addressable variables in the parallel that could go out of scope while
running queued tasks.
2009-04-01 Anatoly Sokolov <aesok@post.ru>
* config/avr/avr.h (avr_case_values_threshold): Remove declaration.

View File

@ -3,7 +3,7 @@
marshalling to implement data sharing and copying clauses.
Contributed by Diego Novillo <dnovillo@redhat.com>
Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@ -3123,6 +3123,7 @@ remove_exit_barrier (struct omp_region *region)
edge_iterator ei;
edge e;
gimple stmt;
int any_addressable_vars = -1;
exit_bb = region->exit;
@ -3148,8 +3149,52 @@ remove_exit_barrier (struct omp_region *region)
if (gsi_end_p (gsi))
continue;
stmt = gsi_stmt (gsi);
if (gimple_code (stmt) == GIMPLE_OMP_RETURN)
gimple_omp_return_set_nowait (stmt);
if (gimple_code (stmt) == GIMPLE_OMP_RETURN
&& !gimple_omp_return_nowait_p (stmt))
{
/* OpenMP 3.0 tasks unfortunately prevent this optimization
in many cases. If there could be tasks queued, the barrier
might be needed to let the tasks run before some local
variable of the parallel that the task uses as shared
runs out of scope. The task can be spawned either
from within current function (this would be easy to check)
or from some function it calls and gets passed an address
of such a variable. */
if (any_addressable_vars < 0)
{
gimple parallel_stmt = last_stmt (region->entry);
tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
tree local_decls = DECL_STRUCT_FUNCTION (child_fun)->local_decls;
tree block;
any_addressable_vars = 0;
for (; local_decls; local_decls = TREE_CHAIN (local_decls))
if (TREE_ADDRESSABLE (TREE_VALUE (local_decls)))
{
any_addressable_vars = 1;
break;
}
for (block = gimple_block (stmt);
!any_addressable_vars
&& block
&& TREE_CODE (block) == BLOCK;
block = BLOCK_SUPERCONTEXT (block))
{
for (local_decls = BLOCK_VARS (block);
local_decls;
local_decls = TREE_CHAIN (local_decls))
if (TREE_ADDRESSABLE (local_decls))
{
any_addressable_vars = 1;
break;
}
if (block == gimple_block (parallel_stmt))
break;
}
}
if (!any_addressable_vars)
gimple_omp_return_set_nowait (stmt);
}
}
}

View File

@ -1,3 +1,10 @@
2009-04-01 Jakub Jelinek <jakub@redhat.com>
PR other/39591
* testsuite/libgomp.c/pr39591-1.c: New test.
* testsuite/libgomp.c/pr39591-2.c: New test.
* testsuite/libgomp.c/pr39591-3.c: New test.
2009-03-25 Uros Bizjak <ubizjak@gmail.com>
* testsuite/libgomp.c/atomic-5.c: Cleanup cpuid usage.

View File

@ -0,0 +1,33 @@
/* PR other/39591 */
/* { dg-do run } */
/* { dg-options "-O2" } */
extern void abort (void);
int err;
int
main (void)
{
#pragma omp parallel
{
int array[40];
int i;
for (i = 0; i < sizeof array / sizeof array[0]; i++)
array[i] = 0x55555555;
#pragma omp for schedule(dynamic)
for (i = 0; i < 50; i++)
#pragma omp task shared(array)
{
int j;
for (j = 0; j < sizeof array / sizeof array[0]; j++)
if (array[j] != 0x55555555)
#pragma omp atomic
err++;
}
}
if (err)
abort ();
return 0;
}

View File

@ -0,0 +1,39 @@
/* PR other/39591 */
/* { dg-do run } */
/* { dg-options "-O2" } */
extern void abort (void);
int err;
void __attribute__((noinline))
foo (int *array)
{
#pragma omp task
{
int j;
for (j = 0; j < sizeof array / sizeof array[0]; j++)
if (array[j] != 0x55555555)
#pragma omp atomic
err++;
}
}
int
main (void)
{
#pragma omp parallel
{
int array[40];
int i;
for (i = 0; i < sizeof array / sizeof array[0]; i++)
array[i] = 0x55555555;
#pragma omp for schedule (dynamic)
for (i = 0; i < 50; i++)
foo (array);
}
if (err)
abort ();
return 0;
}

View File

@ -0,0 +1,40 @@
/* PR other/39591 */
/* { dg-do run } */
/* { dg-options "-O2" } */
extern void abort (void);
int err, a[40];
void __attribute__((noinline))
foo (int *array)
{
#pragma omp task
{
int j;
for (j = 0; j < sizeof array / sizeof array[0]; j++)
if (array[j] != 0x55555555)
#pragma omp atomic
err++;
}
}
int
main (void)
{
int k;
for (k = 0; k < sizeof a / sizeof a[0]; k++)
a[k] = 0x55555555;
#pragma omp parallel
{
int i;
#pragma omp for schedule (dynamic)
for (i = 0; i < 50; i++)
foo (a);
}
if (err)
abort ();
return 0;
}