Commit 2aee3e57 by Jakub Jelinek Committed by Jakub Jelinek

re PR middle-end/27328 (ICE with -fopenmp and goto)

	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.

	* gcc.dg/gomp/pr27328.c: New test.

From-SVN: r113455
parent 4a31b7ee
2006-05-02 Jakub Jelinek <jakub@redhat.com> 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 PR middle-end/27325
* omp-low.c (lower_omp_sections): Call maybe_catch_exception * omp-low.c (lower_omp_sections): Call maybe_catch_exception
on statement list containing also constructors and destructors. on statement list containing also constructors and destructors.
......
...@@ -2227,6 +2227,11 @@ remove_exit_barrier (struct omp_region *region) ...@@ -2227,6 +2227,11 @@ remove_exit_barrier (struct omp_region *region)
exit_bb = region->exit; 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 /* 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 workshare's OMP_RETURN will be in a preceding block. The kinds of
statements that can appear in between are extremely limited -- no statements that can appear in between are extremely limited -- no
...@@ -2372,15 +2377,20 @@ expand_omp_parallel (struct omp_region *region) ...@@ -2372,15 +2377,20 @@ expand_omp_parallel (struct omp_region *region)
regions has invalidated it. */ regions has invalidated it. */
free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_DOMINATORS);
new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb); 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); cgraph_add_new_function (child_fn);
/* Convert OMP_RETURN into a RETURN_EXPR. */ /* Convert OMP_RETURN into a RETURN_EXPR. */
si = bsi_last (exit_bb); if (exit_bb)
gcc_assert (!bsi_end_p (si) && TREE_CODE (bsi_stmt (si)) == OMP_RETURN); {
t = build1 (RETURN_EXPR, void_type_node, NULL); si = bsi_last (exit_bb);
bsi_insert_after (&si, t, TSI_SAME_STMT); gcc_assert (!bsi_end_p (si)
bsi_remove (&si, true); && 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. */ /* Emit a library call to launch the children threads. */
......
2006-05-02 Jakub Jelinek <jakub@redhat.com> 2006-05-02 Jakub Jelinek <jakub@redhat.com>
PR middle-end/27328
* gcc.dg/gomp/pr27328.c: New test.
PR middle-end/27325 PR middle-end/27325
* g++.dg/gomp/pr27325.C: New test. * g++.dg/gomp/pr27325.C: New test.
/* 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 ();
}
...@@ -4814,7 +4814,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, ...@@ -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 /* If ENTRY does not strictly dominate EXIT, this cannot be an SESE
region. */ region. */
gcc_assert (entry_bb != exit_bb 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; bbs = NULL;
VEC_safe_push (basic_block, heap, bbs, entry_bb); 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, ...@@ -4835,15 +4836,25 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
remove_edge (e); remove_edge (e);
} }
num_exit_edges = EDGE_COUNT (exit_bb->succs); if (exit_bb)
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; num_exit_edges = EDGE_COUNT (exit_bb->succs);
exit_succ[i++] = e->dest; exit_succ = (basic_block *) xcalloc (num_exit_edges,
remove_edge (e); 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. */ /* 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, ...@@ -4923,7 +4934,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
these helpers. */ these helpers. */
cfun = dest_cfun; cfun = dest_cfun;
make_edge (ENTRY_BLOCK_PTR, entry_bb, EDGE_FALLTHRU); 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; cfun = saved_cfun;
/* Back in the original function, the SESE region has disappeared, /* 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, ...@@ -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++) for (i = 0; i < num_exit_edges; i++)
make_edge (bb, exit_succ[i], exit_flag[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_flag);
free (entry_pred); free (entry_pred);
free (exit_succ);
free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS);
VEC_free (basic_block, heap, bbs); VEC_free (basic_block, heap, bbs);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment