[PATCH] Fix profiledbootstrap with -fexceptions (PR bootstrap/51648)
Richard Guenther
richard.guenther@gmail.com
Thu Jan 5 09:26:00 GMT 2012
On Thu, Jan 5, 2012 at 1:13 AM, Jakub Jelinek <jakub@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 <jakub@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
More information about the Gcc-patches
mailing list