From 03b06a83441cac588cf04f494915ffd3868a9bed Mon Sep 17 00:00:00 2001 From: Steven Bosscher Date: Wed, 31 Oct 2012 21:37:10 +0000 Subject: [PATCH] re PR tree-optimization/55018 (CDDCE pass is too aggressive sometimes with infinite loops and with some functions) gcc/ PR tree-optimization/55018 * basic-block.h (dfs_find_deadend): New prototype. * cfganal.c (dfs_find_deadend): No longer static. Use bitmap instead of sbitmap for visited. (flow_dfs_compute_reverse_execute): Use dfs_find_deadend here, too. * dominance.c (calc_dfs_tree): If saw_unconnected, traverse from dfs_find_deadend of unconnected b instead of b directly. testsuite/ PR tree-optimization/55018 * gcc.dg/torture/pr55018.c: New test. Co-Authored-By: Jakub Jelinek From-SVN: r193047 --- gcc/ChangeLog | 12 ++++++++++++ gcc/basic-block.h | 1 + gcc/cfganal.c | 16 ++++++++-------- gcc/dominance.c | 12 ++++++++---- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/torture/pr55018.c | 22 ++++++++++++++++++++++ 6 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr55018.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 02e0d4ea66a..9bad56c6319 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2012-10-31 Steven Bosscher + Jakub Jelinek + + PR tree-optimization/55018 + * basic-block.h (dfs_find_deadend): New prototype. + * cfganal.c (dfs_find_deadend): No longer static. Use bitmap + instead of sbitmap for visited. + (flow_dfs_compute_reverse_execute): Use dfs_find_deadend here, too. + * dominance.c (calc_dfs_tree): If saw_unconnected, + traverse from dfs_find_deadend of unconnected b + instead of b directly. + 2012-10-31 Eric Botcazou * config/i386/i386.c (ix86_expand_prologue): Emit frame info for the diff --git a/gcc/basic-block.h b/gcc/basic-block.h index d9bd3b7e550..b28c443996e 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -787,6 +787,7 @@ extern void remove_fake_exit_edges (void); extern void add_noreturn_fake_exit_edges (void); extern void connect_infinite_loops_to_exit (void); extern int post_order_compute (int *, bool, bool); +extern basic_block dfs_find_deadend (basic_block); extern int inverted_post_order_compute (int *); extern int pre_and_rev_post_order_compute (int *, int *, bool); extern int dfs_enumerate_from (basic_block, int, diff --git a/gcc/cfganal.c b/gcc/cfganal.c index 58c763f8454..4bef629d13b 100644 --- a/gcc/cfganal.c +++ b/gcc/cfganal.c @@ -573,7 +573,9 @@ post_order_compute (int *post_order, bool include_entry_exit, } -/* Helper routine for inverted_post_order_compute. +/* Helper routine for inverted_post_order_compute + flow_dfs_compute_reverse_execute, and the reverse-CFG + deapth first search in dominance.c. BB has to belong to a region of CFG unreachable by inverted traversal from the exit. i.e. there's no control flow path from ENTRY to EXIT @@ -593,19 +595,17 @@ post_order_compute (int *post_order, bool include_entry_exit, that all blocks in the region are reachable by starting an inverted traversal from the returned block. */ -static basic_block +basic_block dfs_find_deadend (basic_block bb) { - sbitmap visited = sbitmap_alloc (last_basic_block); - bitmap_clear (visited); + bitmap visited = BITMAP_ALLOC (NULL); for (;;) { - SET_BIT (visited, bb->index); if (EDGE_COUNT (bb->succs) == 0 - || TEST_BIT (visited, EDGE_SUCC (bb, 0)->dest->index)) + || ! bitmap_set_bit (visited, bb->index)) { - sbitmap_free (visited); + BITMAP_FREE (visited); return bb; } @@ -958,7 +958,7 @@ flow_dfs_compute_reverse_execute (depth_first_search_ds data, /* Determine if there are unvisited basic blocks. */ FOR_BB_BETWEEN (bb, last_unvisited, NULL, prev_bb) if (!TEST_BIT (data->visited_blocks, bb->index)) - return bb; + return dfs_find_deadend (bb); return NULL; } diff --git a/gcc/dominance.c b/gcc/dominance.c index 10a58cd8a2a..683f3f5573f 100644 --- a/gcc/dominance.c +++ b/gcc/dominance.c @@ -377,14 +377,18 @@ calc_dfs_tree (struct dom_info *di, bool reverse) { FOR_EACH_BB_REVERSE (b) { + basic_block b2; if (di->dfs_order[b->index]) continue; - bitmap_set_bit (di->fake_exit_edge, b->index); - di->dfs_order[b->index] = di->dfsnum; - di->dfs_to_bb[di->dfsnum] = b; + b2 = dfs_find_deadend (b); + gcc_checking_assert (di->dfs_order[b2->index] == 0); + bitmap_set_bit (di->fake_exit_edge, b2->index); + di->dfs_order[b2->index] = di->dfsnum; + di->dfs_to_bb[di->dfsnum] = b2; di->dfs_parent[di->dfsnum] = di->dfs_order[last_basic_block]; di->dfsnum++; - calc_dfs_tree_nonrec (di, b, reverse); + calc_dfs_tree_nonrec (di, b2, reverse); + gcc_checking_assert (di->dfs_order[b->index]); } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b32d9f79a57..1dc498d7e05 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-10-31 Steven Bosscher + Jakub Jelinek + + PR tree-optimization/55018 + * gcc.dg/torture/pr55018.c: New test. + 2012-10-31 Paolo Carlini PR c++/54583 diff --git a/gcc/testsuite/gcc.dg/torture/pr55018.c b/gcc/testsuite/gcc.dg/torture/pr55018.c new file mode 100644 index 00000000000..f9f34bcf953 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr55018.c @@ -0,0 +1,22 @@ +/* PR tree-optimization/55018 */ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-optimized" } */ + +void +foo (int x) +{ + unsigned int a = 0; + int b = 3; + if (x) + b = 0; +lab: + if (x) + goto lab; + a++; + if (b != 2) + __builtin_printf ("%u", a); + goto lab; +} + +/* { dg-final { scan-tree-dump "printf" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */