On Mon, Oct 22, 2012 at 10:51:43PM +0200, Steven Bosscher wrote: > On Mon, Oct 22, 2012 at 10:39 PM, Jakub Jelinek <ja...@redhat.com> wrote: > > dominance.c doesn't use cfgloop.h (can it? Isn't it used before loops are > > computed, perhaps after loops destroyed, etc.), so there is no guarantee > > that loop->latch of endless loop will have the fake edge added and no other > > bb before it. As 7 and 8 are bigger than 4 or 6, the above loop > > starts with bb 8, finds that its predecessor has already been searched and > > stops there, similarly for 7, then goes on with 6 with another fake edge to > > exit. > > At least it looks like some of the cfganal DFS code could be used in > dominance.c. I will have a look. > > A hack like the following should result in no fake edges for bb7 and bb8.
Wouldn't it be way cheaper to just export dfs_find_deadend from cfganal.c and call it in calc_dfs_tree on each unconnected bb? I.e. (untested with the exception of the testcase): 2012-10-22 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/55018 * cfganal.c (dfs_find_deadend): No longer static. * basic-block.h (dfs_find_deadend): New prototype. * dominance.c (calc_dfs_tree): If saw_unconnected, traverse from dfs_find_deadend of unconnected b instead of b directly. * gcc.dg/torture/pr55018.c: New test. --- gcc/cfganal.c.jj 2012-08-14 08:45:00.000000000 +0200 +++ gcc/cfganal.c 2012-10-22 23:04:29.620117666 +0200 @@ -593,7 +593,7 @@ post_order_compute (int *post_order, boo 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); --- gcc/basic-block.h.jj 2012-10-17 17:18:21.000000000 +0200 +++ gcc/basic-block.h 2012-10-17 17:18:21.000000000 +0200 @@ -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, --- gcc/dominance.c.jj 2012-08-15 10:55:26.000000000 +0200 +++ gcc/dominance.c 2012-10-22 23:07:00.941220792 +0200 @@ -377,14 +377,18 @@ calc_dfs_tree (struct dom_info *di, bool { 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]); } } } --- gcc/testsuite/gcc.dg/torture/pr55018.c.jj 2012-10-22 16:53:56.623083723 +0200 +++ gcc/testsuite/gcc.dg/torture/pr55018.c 2012-10-22 16:54:21.278934668 +0200 @@ -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" } } */ Jakub