mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
4a31b7ee3c
commit
2aee3e57ae
|
|
@ -1,5 +1,10 @@
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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. */
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 ();
|
||||||
|
}
|
||||||
|
|
@ -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,
|
||||||
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,
|
||||||
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,
|
||||||
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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue