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

Reply via email to