aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-09-27 15:44:10 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2013-09-27 15:44:10 +0200
commit09dc585e9af0a2c2fe39674d4f2936428e9498dd (patch)
tree397b9bfaf3b6c235b4e2f991fd202f64d3ef1996
parentec5a350405c8c57cbe7dd264964f2577e834baab (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr58551.c33
-rw-r--r--gcc/tree-cfg.c33
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)
{