diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-09-27 15:44:10 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-09-27 15:44:10 +0200 |
commit | 09dc585e9af0a2c2fe39674d4f2936428e9498dd (patch) | |
tree | 397b9bfaf3b6c235b4e2f991fd202f64d3ef1996 | |
parent | ec5a350405c8c57cbe7dd264964f2577e834baab (diff) | |
download | gcc-09dc585e9af0a2c2fe39674d4f2936428e9498dd.zip gcc-09dc585e9af0a2c2fe39674d4f2936428e9498dd.tar.gz gcc-09dc585e9af0a2c2fe39674d4f2936428e9498dd.tar.bz2 |
re PR middle-end/58551 (ICE with abort in OpenMP SESE region inside of some loop)
PR middle-end/58551
* tree-cfg.c (move_sese_region_to_fn): Also move loops that
are children of outermost saved_cfun's loop, and set it up to
be moved to dest_cfun's outermost loop. Fix up num_nodes adjustments
if loop != loop0 and SESE region contains bbs that belong to loop0.
* c-c++-common/gomp/pr58551.c: New test.
From-SVN: r202972
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/pr58551.c | 33 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 33 |
4 files changed, 71 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4f40aad..620229e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2013-09-27 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/58551 + * tree-cfg.c (move_sese_region_to_fn): Also move loops that + are children of outermost saved_cfun's loop, and set it up to + be moved to dest_cfun's outermost loop. Fix up num_nodes adjustments + if loop != loop0 and SESE region contains bbs that belong to loop0. + 2013-09-27 Richard Sandiford <rdsandiford@googlemail.com> * rtlanal.c (must_be_base_p, must_be_index_p): Delete. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 094fafc..2696aa2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-09-27 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/58551 + * c-c++-common/gomp/pr58551.c: New test. + 2013-09-27 Richard Biener <rguenther@suse.de> PR tree-optimization/58459 diff --git a/gcc/testsuite/c-c++-common/gomp/pr58551.c b/gcc/testsuite/c-c++-common/gomp/pr58551.c new file mode 100644 index 0000000..e2db70f --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr58551.c @@ -0,0 +1,33 @@ +/* PR middle-end/58551 */ +/* { dg-do compile } */ +/* { dg-options "-O0 -fopenmp" } */ + +void +foo (int *a) +{ + int i; + for (i = 0; i < 8; i++) + #pragma omp task + if (a[i]) + __builtin_abort (); +} + +void bar (int, int); + +void +baz (int *a) +{ + int i; + for (i = 0; i < 8; i++) + #pragma omp task + if (a[i]) + { + int j, k; + for (j = 0; j < 10; j++) + for (k = 0; k < 8; k++) + bar (j, k); + for (k = 0; k < 12; k++) + bar (-1, k); + __builtin_abort (); + } +} diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 70930a35..d1a6c31 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -6662,12 +6662,13 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, struct function *saved_cfun = cfun; int *entry_flag, *exit_flag; unsigned *entry_prob, *exit_prob; - unsigned i, num_entry_edges, num_exit_edges; + unsigned i, num_entry_edges, num_exit_edges, num_nodes; edge e; edge_iterator ei; htab_t new_label_map; struct pointer_map_t *vars_map, *eh_map; struct loop *loop = entry_bb->loop_father; + struct loop *loop0 = get_loop (saved_cfun, 0); struct move_stmt_d d; /* If ENTRY does not strictly dominate EXIT, this cannot be an SESE @@ -6760,16 +6761,29 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, set_loops_for_fn (dest_cfun, loops); /* Move the outlined loop tree part. */ + num_nodes = bbs.length (); FOR_EACH_VEC_ELT (bbs, i, bb) { - if (bb->loop_father->header == bb - && loop_outer (bb->loop_father) == loop) + if (bb->loop_father->header == bb) { struct loop *this_loop = bb->loop_father; - flow_loop_tree_node_remove (bb->loop_father); - flow_loop_tree_node_add (get_loop (dest_cfun, 0), this_loop); - fixup_loop_arrays_after_move (saved_cfun, cfun, this_loop); + struct loop *outer = loop_outer (this_loop); + if (outer == loop + /* If the SESE region contains some bbs ending with + a noreturn call, those are considered to belong + to the outermost loop in saved_cfun, rather than + the entry_bb's loop_father. */ + || outer == loop0) + { + if (outer != loop) + num_nodes -= this_loop->num_nodes; + flow_loop_tree_node_remove (bb->loop_father); + flow_loop_tree_node_add (get_loop (dest_cfun, 0), this_loop); + fixup_loop_arrays_after_move (saved_cfun, cfun, this_loop); + } } + else if (bb->loop_father == loop0 && loop0 != loop) + num_nodes--; /* Remove loop exits from the outlined region. */ if (loops_for_fn (saved_cfun)->exits) @@ -6789,6 +6803,7 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, /* Setup a mapping to be used by move_block_to_fn. */ loop->aux = current_loops->tree_root; + loop0->aux = current_loops->tree_root; pop_cfun (); @@ -6817,11 +6832,13 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, } loop->aux = NULL; + loop0->aux = NULL; /* Loop sizes are no longer correct, fix them up. */ - loop->num_nodes -= bbs.length (); + loop->num_nodes -= num_nodes; for (struct loop *outer = loop_outer (loop); outer; outer = loop_outer (outer)) - outer->num_nodes -= bbs.length (); + outer->num_nodes -= num_nodes; + loop0->num_nodes -= bbs.length () - num_nodes; if (saved_cfun->has_simduid_loops || saved_cfun->has_force_vect_loops) { |