On Thu, Jan 5, 2012 at 1:13 AM, Jakub Jelinek <ja...@redhat.com> wrote: > 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?
Ok (I suppose we could trigger this even w/o the CLOBBER stuff by having a noreturn function that throws). Thanks, Richard. > 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