diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-07-02 21:22:47 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2007-07-02 21:22:47 +0200 |
commit | 69f1837b81f57ff588ffd82a3db0a7b739b446de (patch) | |
tree | e8a300b94b510ed658c3b719e55917d2e3346017 /gcc | |
parent | 15c723f39fb55da9ee0f288ecac2c178b68b2a3c (diff) | |
download | gcc-69f1837b81f57ff588ffd82a3db0a7b739b446de.zip gcc-69f1837b81f57ff588ffd82a3db0a7b739b446de.tar.gz gcc-69f1837b81f57ff588ffd82a3db0a7b739b446de.tar.bz2 |
re PR libgomp/32468 (number of threads in a parallel region depends on number of SECTIONs and MAX_THREADS)
PR libgomp/32468
* omp-low.c (check_combined_parallel): New function.
(lower_omp_parallel): Call it via walk_stmts, set
OMP_PARALLEL_COMBINED if appropriate.
(determine_parallel_type): If OMP_FOR resp. OMP_SECTIONS
isn't the only statement in WS_ENTRY_BB or OMP_RETURN
the only one in PAR_EXIT_BB and not OMP_PARALLEL_COMBINED,
don't consider it as combined parallel.
* gcc.dg/gomp/pr32468-1.c: New test.
From-SVN: r126226
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/omp-low.c | 42 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/gomp/pr32468-1.c | 100 |
4 files changed, 156 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f651d00..164af03 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2007-07-02 Jakub Jelinek <jakub@redhat.com> + + PR libgomp/32468 + * omp-low.c (check_combined_parallel): New function. + (lower_omp_parallel): Call it via walk_stmts, set + OMP_PARALLEL_COMBINED if appropriate. + (determine_parallel_type): If OMP_FOR resp. OMP_SECTIONS + isn't the only statement in WS_ENTRY_BB or OMP_RETURN + the only one in PAR_EXIT_BB and not OMP_PARALLEL_COMBINED, + don't consider it as combined parallel. + 2007-07-02 Richard Sandiford <richard@codesourcery.com> * configure.ac (gcc_gxx_include_dir): Use $(libsubdir_to_prefix). diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 700645f..fce9975 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -385,9 +385,12 @@ determine_parallel_type (struct omp_region *region) if (single_succ (par_entry_bb) == ws_entry_bb && single_succ (ws_exit_bb) == par_exit_bb - && workshare_safe_to_combine_p (par_entry_bb, ws_entry_bb)) + && workshare_safe_to_combine_p (par_entry_bb, ws_entry_bb) + && (OMP_PARALLEL_COMBINED (last_stmt (par_entry_bb)) + || (last_and_only_stmt (ws_entry_bb) + && last_and_only_stmt (par_exit_bb)))) { - tree ws_stmt = last_stmt (region->inner->entry); + tree ws_stmt = last_stmt (ws_entry_bb); if (region->inner->type == OMP_FOR) { @@ -4060,6 +4063,28 @@ lower_omp_for (tree *stmt_p, omp_context *ctx) *stmt_p = new_stmt; } +/* Callback for walk_stmts. Check if *TP only contains OMP_FOR + or OMP_PARALLEL. */ + +static tree +check_combined_parallel (tree *tp, int *walk_subtrees, void *data) +{ + struct walk_stmt_info *wi = data; + int *info = wi->info; + + *walk_subtrees = 0; + switch (TREE_CODE (*tp)) + { + case OMP_FOR: + case OMP_SECTIONS: + *info = *info == 0 ? 1 : -1; + break; + default: + *info = -1; + break; + } + return NULL; +} /* Lower the OpenMP parallel directive in *STMT_P. CTX holds context information for the directive. */ @@ -4077,6 +4102,19 @@ lower_omp_parallel (tree *stmt_p, omp_context *ctx) par_bind = OMP_PARALLEL_BODY (stmt); par_body = BIND_EXPR_BODY (par_bind); child_fn = ctx->cb.dst_fn; + if (!OMP_PARALLEL_COMBINED (stmt)) + { + struct walk_stmt_info wi; + int ws_num = 0; + + memset (&wi, 0, sizeof (wi)); + wi.callback = check_combined_parallel; + wi.info = &ws_num; + wi.val_only = true; + walk_stmts (&wi, &par_bind); + if (ws_num == 1) + OMP_PARALLEL_COMBINED (stmt) = 1; + } push_gimplify_context (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7b0e98e..f09c09e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-07-02 Jakub Jelinek <jakub@redhat.com> + + PR libgomp/32468 + * gcc.dg/gomp/pr32468-1.c: New test. + 2007-07-02 Richard Sandiford <richard@codesourcery.com> * gcc.target/mips/mips.exp (setup_mips_tests): Treat -mfp* as diff --git a/gcc/testsuite/gcc.dg/gomp/pr32468-1.c b/gcc/testsuite/gcc.dg/gomp/pr32468-1.c new file mode 100644 index 0000000..4372413 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/pr32468-1.c @@ -0,0 +1,100 @@ +/* PR libgomp/32468 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fopenmp -fdump-tree-ompexp" } */ + +extern int printf (const char *, ...); +extern int omp_get_thread_num (void), omp_get_num_threads (void); +extern int bar (void); +extern int baz (const char *, ...); + +void +f1 (void) +{ +#pragma omp parallel + { + baz ("%d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + #pragma omp sections + { + #pragma omp section + printf ("section1 %d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + #pragma omp section + printf ("section2 %d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + } + } +} + +void +f2 (void) +{ +#pragma omp parallel + { + #pragma omp sections + { + #pragma omp section + printf ("section1 %d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + #pragma omp section + printf ("section2 %d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + } + baz ("%d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + } +} + +void +f3 (void) +{ +#pragma omp parallel + { + int bb = bar (); + #pragma omp sections + { + #pragma omp section + printf ("section1 %d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + #pragma omp section + printf ("section2 %d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + } + } +} + +void +f4 (void) +{ + int i; +#pragma omp parallel + { + baz ("%d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + #pragma omp for schedule (dynamic, 15) + for (i = 0; i < 10000; i++) + printf ("section1 %d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + } +} + +void +f5 (void) +{ + int i; +#pragma omp parallel + { + #pragma omp for schedule (dynamic, 15) + for (i = 0; i < 10000; i++) + printf ("section1 %d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + baz ("%d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + } +} + +void +f6 (void) +{ + int i; +#pragma omp parallel + { + int bb = bar (); + #pragma omp for schedule (runtime) + for (i = 0; i < 10000; i++) + printf ("section1 %d/%d\n", omp_get_thread_num (), omp_get_num_threads ()); + } +} + +/* There should not be a GOMP_parallel_{loop,sections}* call. */ +/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop" 0 "ompexp"} } */ +/* { dg-final { scan-tree-dump-times "GOMP_parallel_sections" 0 "ompexp"} } */ +/* { dg-final { cleanup-tree-dump "ompexp" } } */ |