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:
parent
4223ff5f25
commit
03742a9b01
6 changed files with 174 additions and 3 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
33
libgomp/testsuite/libgomp.c/pr39591-1.c
Normal file
33
libgomp/testsuite/libgomp.c/pr39591-1.c
Normal 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;
|
||||
}
|
39
libgomp/testsuite/libgomp.c/pr39591-2.c
Normal file
39
libgomp/testsuite/libgomp.c/pr39591-2.c
Normal 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;
|
||||
}
|
40
libgomp/testsuite/libgomp.c/pr39591-3.c
Normal file
40
libgomp/testsuite/libgomp.c/pr39591-3.c
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue