Commit 03b06a83 by Steven Bosscher

re PR tree-optimization/55018 (CDDCE pass is too aggressive sometimes with…

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 <jakub@redhat.com>

From-SVN: r193047
parent e212c7f5
2012-10-31 Steven Bosscher <steven@gcc.gnu.org>
Jakub Jelinek <jakub@redhat.com>
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 <ebotcazou@adacore.com> 2012-10-31 Eric Botcazou <ebotcazou@adacore.com>
* config/i386/i386.c (ix86_expand_prologue): Emit frame info for the * config/i386/i386.c (ix86_expand_prologue): Emit frame info for the
...@@ -787,6 +787,7 @@ extern void remove_fake_exit_edges (void); ...@@ -787,6 +787,7 @@ extern void remove_fake_exit_edges (void);
extern void add_noreturn_fake_exit_edges (void); extern void add_noreturn_fake_exit_edges (void);
extern void connect_infinite_loops_to_exit (void); extern void connect_infinite_loops_to_exit (void);
extern int post_order_compute (int *, bool, bool); 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 inverted_post_order_compute (int *);
extern int pre_and_rev_post_order_compute (int *, int *, bool); extern int pre_and_rev_post_order_compute (int *, int *, bool);
extern int dfs_enumerate_from (basic_block, int, extern int dfs_enumerate_from (basic_block, int,
......
...@@ -573,7 +573,9 @@ post_order_compute (int *post_order, bool include_entry_exit, ...@@ -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 BB has to belong to a region of CFG
unreachable by inverted traversal from the exit. unreachable by inverted traversal from the exit.
i.e. there's no control flow path from ENTRY to 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, ...@@ -593,19 +595,17 @@ post_order_compute (int *post_order, bool include_entry_exit,
that all blocks in the region are reachable that all blocks in the region are reachable
by starting an inverted traversal from the returned block. */ by starting an inverted traversal from the returned block. */
static basic_block basic_block
dfs_find_deadend (basic_block bb) dfs_find_deadend (basic_block bb)
{ {
sbitmap visited = sbitmap_alloc (last_basic_block); bitmap visited = BITMAP_ALLOC (NULL);
bitmap_clear (visited);
for (;;) for (;;)
{ {
SET_BIT (visited, bb->index);
if (EDGE_COUNT (bb->succs) == 0 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; return bb;
} }
...@@ -958,7 +958,7 @@ flow_dfs_compute_reverse_execute (depth_first_search_ds data, ...@@ -958,7 +958,7 @@ flow_dfs_compute_reverse_execute (depth_first_search_ds data,
/* Determine if there are unvisited basic blocks. */ /* Determine if there are unvisited basic blocks. */
FOR_BB_BETWEEN (bb, last_unvisited, NULL, prev_bb) FOR_BB_BETWEEN (bb, last_unvisited, NULL, prev_bb)
if (!TEST_BIT (data->visited_blocks, bb->index)) if (!TEST_BIT (data->visited_blocks, bb->index))
return bb; return dfs_find_deadend (bb);
return NULL; return NULL;
} }
......
...@@ -377,14 +377,18 @@ calc_dfs_tree (struct dom_info *di, bool reverse) ...@@ -377,14 +377,18 @@ calc_dfs_tree (struct dom_info *di, bool reverse)
{ {
FOR_EACH_BB_REVERSE (b) FOR_EACH_BB_REVERSE (b)
{ {
basic_block b2;
if (di->dfs_order[b->index]) if (di->dfs_order[b->index])
continue; continue;
bitmap_set_bit (di->fake_exit_edge, b->index); b2 = dfs_find_deadend (b);
di->dfs_order[b->index] = di->dfsnum; gcc_checking_assert (di->dfs_order[b2->index] == 0);
di->dfs_to_bb[di->dfsnum] = b; 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->dfs_parent[di->dfsnum] = di->dfs_order[last_basic_block];
di->dfsnum++; di->dfsnum++;
calc_dfs_tree_nonrec (di, b, reverse); calc_dfs_tree_nonrec (di, b2, reverse);
gcc_checking_assert (di->dfs_order[b->index]);
} }
} }
} }
......
2012-10-31 Steven Bosscher <steven@gcc.gnu.org>
Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/55018
* gcc.dg/torture/pr55018.c: New test.
2012-10-31 Paolo Carlini <paolo.carlini@oracle.com> 2012-10-31 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/54583 PR c++/54583
......
/* 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" } } */
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