Hi!

profiledbootstrap with --disable-poststage-build-with-cxx and -fexceptions
currently fails on x86_64-linux.  The problem is that no EDGE_FAKE edge is
added from noreturn fatal_error call to the exit block, eventhough
fatal_error calls exit.
The problem is that we have several places which add EDGE_FAKE edges.
One is add_noreturn_fake_exit_edges, which adds EDGE_FAKE to bbs with zero
successor (not this case, because after the call there is EDGE_EH (to a
={v} {CLOBBER} bb, which is why this is a regression)).
And another one is gimple_flow_call_edges_add, but that one skips
all ECF_NORETURN calls, based on the assumption (apparently wrong) that
all noreturn calls have zero successor edges.
And the third place that adds EDGE_FAKE edges is branch_prob
itself, but it does so only for abnormal edges.

I think this bug can be fixed in any of the 3 places, the following patch
changes the second one.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2012-01-04  Jakub Jelinek  <ja...@redhat.com>

        PR bootstrap/51648
        * tree-cfg.c (need_fake_edge_p): Return true also for noreturn
        calls that have any non-fake successor edges.

--- gcc/tree-cfg.c.jj   2011-12-27 11:39:49.000000000 +0100
+++ gcc/tree-cfg.c      2012-01-04 22:30:22.072838130 +0100
@@ -6882,9 +6882,20 @@ need_fake_edge_p (gimple t)
           && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FORK))
     return false;
 
-  if (is_gimple_call (t)
-      && !(call_flags & ECF_NORETURN))
-    return true;
+  if (is_gimple_call (t))
+    {
+      edge_iterator ei;
+      edge e;
+      basic_block bb;
+
+      if (!(call_flags & ECF_NORETURN))
+       return true;
+
+      bb = gimple_bb (t);
+      FOR_EACH_EDGE (e, ei, bb->succs)
+       if ((e->flags & EDGE_FAKE) == 0)
+         return true;
+    }
 
   if (gimple_code (t) == GIMPLE_ASM
        && (gimple_asm_volatile_p (t) || gimple_asm_input_p (t)))
@@ -6895,9 +6906,10 @@ need_fake_edge_p (gimple t)
 
 
 /* Add fake edges to the function exit for any non constant and non
-   noreturn calls, volatile inline assembly in the bitmap of blocks
-   specified by BLOCKS or to the whole CFG if BLOCKS is zero.  Return
-   the number of blocks that were split.
+   noreturn calls (or noreturn calls with EH/abnormal edges),
+   volatile inline assembly in the bitmap of blocks specified by BLOCKS
+   or to the whole CFG if BLOCKS is zero.  Return the number of blocks
+   that were split.
 
    The goal is to expose cases in which entering a basic block does
    not imply that all subsequent instructions must be executed.  */

        Jakub

Reply via email to