diff options
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/omp-low.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/gomp/pr27328.c | 19 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 39 |
5 files changed, 70 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 984916d5a0c..9a0849a8794 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2006-05-02 Jakub Jelinek <jakub@redhat.com> + PR middle-end/27328 + * omp-low.c (remove_exit_barrier): Handle NULL exit_bb. + (expand_omp_parallel): Likewise. + * tree-cfg.c (move_sese_region_to_fn): Likewise. + PR middle-end/27325 * omp-low.c (lower_omp_sections): Call maybe_catch_exception on statement list containing also constructors and destructors. diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 92d71ae025c..62b715e37ad 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -2227,6 +2227,11 @@ remove_exit_barrier (struct omp_region *region) exit_bb = region->exit; + /* If the parallel region doesn't return, we don't have REGION->EXIT + block at all. */ + if (! exit_bb) + return; + /* The last insn in the block will be the parallel's OMP_RETURN. The workshare's OMP_RETURN will be in a preceding block. The kinds of statements that can appear in between are extremely limited -- no @@ -2372,15 +2377,20 @@ expand_omp_parallel (struct omp_region *region) regions has invalidated it. */ free_dominance_info (CDI_DOMINATORS); new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb); - single_succ_edge (new_bb)->flags = EDGE_FALLTHRU; + if (exit_bb) + single_succ_edge (new_bb)->flags = EDGE_FALLTHRU; cgraph_add_new_function (child_fn); /* Convert OMP_RETURN into a RETURN_EXPR. */ - si = bsi_last (exit_bb); - gcc_assert (!bsi_end_p (si) && TREE_CODE (bsi_stmt (si)) == OMP_RETURN); - t = build1 (RETURN_EXPR, void_type_node, NULL); - bsi_insert_after (&si, t, TSI_SAME_STMT); - bsi_remove (&si, true); + if (exit_bb) + { + si = bsi_last (exit_bb); + gcc_assert (!bsi_end_p (si) + && TREE_CODE (bsi_stmt (si)) == OMP_RETURN); + t = build1 (RETURN_EXPR, void_type_node, NULL); + bsi_insert_after (&si, t, TSI_SAME_STMT); + bsi_remove (&si, true); + } } /* Emit a library call to launch the children threads. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b0fda63339d..b890b64302b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2006-05-02 Jakub Jelinek <jakub@redhat.com> + PR middle-end/27328 + * gcc.dg/gomp/pr27328.c: New test. + PR middle-end/27325 * g++.dg/gomp/pr27325.C: New test. diff --git a/gcc/testsuite/gcc.dg/gomp/pr27328.c b/gcc/testsuite/gcc.dg/gomp/pr27328.c new file mode 100644 index 00000000000..afde738a725 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/pr27328.c @@ -0,0 +1,19 @@ +/* PR middle-end/27328 */ +/* { dg-do compile } */ + +extern void baz (void) __attribute__((noreturn)); + +void +foo (void) +{ +#pragma omp parallel + for (;;) + ; +} + +void +bar (void) +{ +#pragma omp parallel + baz (); +} diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 744a9032b5f..4c5aa4bd4e7 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -4814,7 +4814,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, /* If ENTRY does not strictly dominate EXIT, this cannot be an SESE region. */ gcc_assert (entry_bb != exit_bb - && dominated_by_p (CDI_DOMINATORS, exit_bb, entry_bb)); + && (!exit_bb + || dominated_by_p (CDI_DOMINATORS, exit_bb, entry_bb))); bbs = NULL; VEC_safe_push (basic_block, heap, bbs, entry_bb); @@ -4835,15 +4836,25 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, remove_edge (e); } - num_exit_edges = EDGE_COUNT (exit_bb->succs); - exit_succ = (basic_block *) xcalloc (num_exit_edges, sizeof (basic_block)); - exit_flag = (int *) xcalloc (num_exit_edges, sizeof (int)); - i = 0; - for (ei = ei_start (exit_bb->succs); (e = ei_safe_edge (ei)) != NULL;) + if (exit_bb) { - exit_flag[i] = e->flags; - exit_succ[i++] = e->dest; - remove_edge (e); + num_exit_edges = EDGE_COUNT (exit_bb->succs); + exit_succ = (basic_block *) xcalloc (num_exit_edges, + sizeof (basic_block)); + exit_flag = (int *) xcalloc (num_exit_edges, sizeof (int)); + i = 0; + for (ei = ei_start (exit_bb->succs); (e = ei_safe_edge (ei)) != NULL;) + { + exit_flag[i] = e->flags; + exit_succ[i++] = e->dest; + remove_edge (e); + } + } + else + { + num_exit_edges = 0; + exit_succ = NULL; + exit_flag = NULL; } /* Switch context to the child function to initialize DEST_FN's CFG. */ @@ -4923,7 +4934,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, these helpers. */ cfun = dest_cfun; make_edge (ENTRY_BLOCK_PTR, entry_bb, EDGE_FALLTHRU); - make_edge (exit_bb, EXIT_BLOCK_PTR, 0); + if (exit_bb) + make_edge (exit_bb, EXIT_BLOCK_PTR, 0); cfun = saved_cfun; /* Back in the original function, the SESE region has disappeared, @@ -4935,10 +4947,13 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, for (i = 0; i < num_exit_edges; i++) make_edge (bb, exit_succ[i], exit_flag[i]); - free (exit_flag); + if (exit_bb) + { + free (exit_flag); + free (exit_succ); + } free (entry_flag); free (entry_pred); - free (exit_succ); free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); VEC_free (basic_block, heap, bbs); |