diff mbox

Fix bugs introduced by switch-case profile propagation

Message ID CAPK5YPa0CuLXOGR7TQq3hKVi4kxh1jxp0D9cf-PpdkkCucZ36A@mail.gmail.com
State New
Headers show

Commit Message

Easwaran Raman Oct. 17, 2012, 8:48 p.m. UTC
Hi,
 This patch fixes bugs introduced by my previous patch to propagate
profiles during switch expansion. Bootstrap and profiledbootstrap
successful on x86_64. Confirmed that it fixes the crashes reported in
PR middle-end/54957. OK for trunk?

- Easwaran

2012-10-17   Easwaran Raman  <eraman@google.com>

        PR target/54938
        PR middle-end/54957
        * optabs.c (emit_cmp_and_jump_insn_1): Add REG_BR_PROB note
        only if it doesn't already exist.
        * except.c (sjlj_emit_function_enter): Remove unused variable.
        * stmt.c (get_outgoing_edge_probs): Return 0 if BB is NULL.
        (emit_case_dispatch_table): Handle the case where STMT_BB is
        NULL.
        (expand_sjlj_dispatch_table): Pass BB containing before_case
        to emit_case_dispatch_table.

Comments

Easwaran Raman Oct. 22, 2012, 7:20 p.m. UTC | #1
Ping.


On Wed, Oct 17, 2012 at 1:48 PM, Easwaran Raman <eraman@google.com> wrote:
> Hi,
>  This patch fixes bugs introduced by my previous patch to propagate
> profiles during switch expansion. Bootstrap and profiledbootstrap
> successful on x86_64. Confirmed that it fixes the crashes reported in
> PR middle-end/54957. OK for trunk?
>
> - Easwaran
>
> 2012-10-17   Easwaran Raman  <eraman@google.com>
>
>         PR target/54938
>         PR middle-end/54957
>         * optabs.c (emit_cmp_and_jump_insn_1): Add REG_BR_PROB note
>         only if it doesn't already exist.
>         * except.c (sjlj_emit_function_enter): Remove unused variable.
>         * stmt.c (get_outgoing_edge_probs): Return 0 if BB is NULL.
>         (emit_case_dispatch_table): Handle the case where STMT_BB is
>         NULL.
>         (expand_sjlj_dispatch_table): Pass BB containing before_case
>         to emit_case_dispatch_table.
>
> Index: gcc/optabs.c
> ===================================================================
> --- gcc/optabs.c (revision 192488)
> +++ gcc/optabs.c (working copy)
> @@ -4268,11 +4268,9 @@ emit_cmp_and_jump_insn_1 (rtx test, enum machine_m
>        && profile_status != PROFILE_ABSENT
>        && insn
>        && JUMP_P (insn)
> -      && any_condjump_p (insn))
> -    {
> -      gcc_assert (!find_reg_note (insn, REG_BR_PROB, 0));
> -      add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
> -    }
> +      && any_condjump_p (insn)
> +      && !find_reg_note (insn, REG_BR_PROB, 0))
> +    add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
>  }
>
>  /* Generate code to compare X with Y so that the condition codes are
> Index: gcc/except.c
> ===================================================================
> --- gcc/except.c (revision 192488)
> +++ gcc/except.c (working copy)
> @@ -1153,7 +1153,7 @@ sjlj_emit_function_enter (rtx dispatch_label)
>    if (dispatch_label)
>      {
>  #ifdef DONT_USE_BUILTIN_SETJMP
> -      rtx x, last;
> +      rtx x;
>        x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
>     TYPE_MODE (integer_type_node), 1,
>     plus_constant (Pmode, XEXP (fc, 0),
> Index: gcc/stmt.c
> ===================================================================
> --- gcc/stmt.c (revision 192488)
> +++ gcc/stmt.c (working copy)
> @@ -1867,6 +1867,8 @@ get_outgoing_edge_probs (basic_block bb)
>    edge e;
>    edge_iterator ei;
>    int prob_sum = 0;
> +  if (!bb)
> +    return 0;
>    FOR_EACH_EDGE(e, ei, bb->succs)
>      prob_sum += e->probability;
>    return prob_sum;
> @@ -1916,8 +1918,8 @@ emit_case_dispatch_table (tree index_expr, tree in
>    rtx fallback_label = label_rtx (case_list->code_label);
>    rtx table_label = gen_label_rtx ();
>    bool has_gaps = false;
> -  edge default_edge = EDGE_SUCC(stmt_bb, 0);
> -  int default_prob = default_edge->probability;
> +  edge default_edge = stmt_bb ? EDGE_SUCC(stmt_bb, 0) : NULL;
> +  int default_prob = default_edge ? default_edge->probability : 0;
>    int base = get_outgoing_edge_probs (stmt_bb);
>    bool try_with_tablejump = false;
>
> @@ -1997,7 +1999,8 @@ emit_case_dispatch_table (tree index_expr, tree in
>        default_prob = 0;
>      }
>
> -  default_edge->probability = default_prob;
> +  if (default_edge)
> +    default_edge->probability = default_prob;
>
>    /* We have altered the probability of the default edge. So the probabilities
>       of all other edges need to be adjusted so that it sums up to
> @@ -2289,7 +2292,8 @@ expand_sjlj_dispatch_table (rtx dispatch_index,
>
>        emit_case_dispatch_table (index_expr, index_type,
>   case_list, default_label,
> - minval, maxval, range, NULL);
> + minval, maxval, range,
> +                                BLOCK_FOR_INSN (before_case));
>        emit_label (default_label);
>        free_alloc_pool (case_node_pool);
>      }
Jan Hubicka Oct. 23, 2012, 10:03 a.m. UTC | #2
> Ping.
> 
> 
> On Wed, Oct 17, 2012 at 1:48 PM, Easwaran Raman <eraman@google.com> wrote:
> > Hi,
> >  This patch fixes bugs introduced by my previous patch to propagate
> > profiles during switch expansion. Bootstrap and profiledbootstrap
> > successful on x86_64. Confirmed that it fixes the crashes reported in
> > PR middle-end/54957. OK for trunk?
> >
> > - Easwaran
> >
> > 2012-10-17   Easwaran Raman  <eraman@google.com>
> >
> >         PR target/54938
> >         PR middle-end/54957
> >         * optabs.c (emit_cmp_and_jump_insn_1): Add REG_BR_PROB note
> >         only if it doesn't already exist.
> >         * except.c (sjlj_emit_function_enter): Remove unused variable.
> >         * stmt.c (get_outgoing_edge_probs): Return 0 if BB is NULL.

Seems fine, but under what conditions you get NULL here?

Honza
> >         (emit_case_dispatch_table): Handle the case where STMT_BB is
> >         NULL.
> >         (expand_sjlj_dispatch_table): Pass BB containing before_case
> >         to emit_case_dispatch_table.
> >
> > Index: gcc/optabs.c
> > ===================================================================
> > --- gcc/optabs.c (revision 192488)
> > +++ gcc/optabs.c (working copy)
> > @@ -4268,11 +4268,9 @@ emit_cmp_and_jump_insn_1 (rtx test, enum machine_m
> >        && profile_status != PROFILE_ABSENT
> >        && insn
> >        && JUMP_P (insn)
> > -      && any_condjump_p (insn))
> > -    {
> > -      gcc_assert (!find_reg_note (insn, REG_BR_PROB, 0));
> > -      add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
> > -    }
> > +      && any_condjump_p (insn)
> > +      && !find_reg_note (insn, REG_BR_PROB, 0))
> > +    add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
> >  }
> >
> >  /* Generate code to compare X with Y so that the condition codes are
> > Index: gcc/except.c
> > ===================================================================
> > --- gcc/except.c (revision 192488)
> > +++ gcc/except.c (working copy)
> > @@ -1153,7 +1153,7 @@ sjlj_emit_function_enter (rtx dispatch_label)
> >    if (dispatch_label)
> >      {
> >  #ifdef DONT_USE_BUILTIN_SETJMP
> > -      rtx x, last;
> > +      rtx x;
> >        x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
> >     TYPE_MODE (integer_type_node), 1,
> >     plus_constant (Pmode, XEXP (fc, 0),
> > Index: gcc/stmt.c
> > ===================================================================
> > --- gcc/stmt.c (revision 192488)
> > +++ gcc/stmt.c (working copy)
> > @@ -1867,6 +1867,8 @@ get_outgoing_edge_probs (basic_block bb)
> >    edge e;
> >    edge_iterator ei;
> >    int prob_sum = 0;
> > +  if (!bb)
> > +    return 0;
> >    FOR_EACH_EDGE(e, ei, bb->succs)
> >      prob_sum += e->probability;
> >    return prob_sum;
> > @@ -1916,8 +1918,8 @@ emit_case_dispatch_table (tree index_expr, tree in
> >    rtx fallback_label = label_rtx (case_list->code_label);
> >    rtx table_label = gen_label_rtx ();
> >    bool has_gaps = false;
> > -  edge default_edge = EDGE_SUCC(stmt_bb, 0);
> > -  int default_prob = default_edge->probability;
> > +  edge default_edge = stmt_bb ? EDGE_SUCC(stmt_bb, 0) : NULL;
> > +  int default_prob = default_edge ? default_edge->probability : 0;
> >    int base = get_outgoing_edge_probs (stmt_bb);
> >    bool try_with_tablejump = false;
> >
> > @@ -1997,7 +1999,8 @@ emit_case_dispatch_table (tree index_expr, tree in
> >        default_prob = 0;
> >      }
> >
> > -  default_edge->probability = default_prob;
> > +  if (default_edge)
> > +    default_edge->probability = default_prob;
> >
> >    /* We have altered the probability of the default edge. So the probabilities
> >       of all other edges need to be adjusted so that it sums up to
> > @@ -2289,7 +2292,8 @@ expand_sjlj_dispatch_table (rtx dispatch_index,
> >
> >        emit_case_dispatch_table (index_expr, index_type,
> >   case_list, default_label,
> > - minval, maxval, range, NULL);
> > + minval, maxval, range,
> > +                                BLOCK_FOR_INSN (before_case));
> >        emit_label (default_label);
> >        free_alloc_pool (case_node_pool);
> >      }
Easwaran Raman Oct. 23, 2012, 6:01 p.m. UTC | #3
On Tue, Oct 23, 2012 at 3:03 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
>> Ping.
>>
>>
>> On Wed, Oct 17, 2012 at 1:48 PM, Easwaran Raman <eraman@google.com> wrote:
>> > Hi,
>> >  This patch fixes bugs introduced by my previous patch to propagate
>> > profiles during switch expansion. Bootstrap and profiledbootstrap
>> > successful on x86_64. Confirmed that it fixes the crashes reported in
>> > PR middle-end/54957. OK for trunk?
>> >
>> > - Easwaran
>> >
>> > 2012-10-17   Easwaran Raman  <eraman@google.com>
>> >
>> >         PR target/54938
>> >         PR middle-end/54957
>> >         * optabs.c (emit_cmp_and_jump_insn_1): Add REG_BR_PROB note
>> >         only if it doesn't already exist.
>> >         * except.c (sjlj_emit_function_enter): Remove unused variable.
>> >         * stmt.c (get_outgoing_edge_probs): Return 0 if BB is NULL.
>
> Seems fine, but under what conditions you get NULL here?

When expand_sjlj_dispatch_table calls emit_case_dispatch_table,
stmt_bb is NULL.

- Easwaran

> Honza
>> >         (emit_case_dispatch_table): Handle the case where STMT_BB is
>> >         NULL.
>> >         (expand_sjlj_dispatch_table): Pass BB containing before_case
>> >         to emit_case_dispatch_table.
>> >
>> > Index: gcc/optabs.c
>> > ===================================================================
>> > --- gcc/optabs.c (revision 192488)
>> > +++ gcc/optabs.c (working copy)
>> > @@ -4268,11 +4268,9 @@ emit_cmp_and_jump_insn_1 (rtx test, enum machine_m
>> >        && profile_status != PROFILE_ABSENT
>> >        && insn
>> >        && JUMP_P (insn)
>> > -      && any_condjump_p (insn))
>> > -    {
>> > -      gcc_assert (!find_reg_note (insn, REG_BR_PROB, 0));
>> > -      add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
>> > -    }
>> > +      && any_condjump_p (insn)
>> > +      && !find_reg_note (insn, REG_BR_PROB, 0))
>> > +    add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
>> >  }
>> >
>> >  /* Generate code to compare X with Y so that the condition codes are
>> > Index: gcc/except.c
>> > ===================================================================
>> > --- gcc/except.c (revision 192488)
>> > +++ gcc/except.c (working copy)
>> > @@ -1153,7 +1153,7 @@ sjlj_emit_function_enter (rtx dispatch_label)
>> >    if (dispatch_label)
>> >      {
>> >  #ifdef DONT_USE_BUILTIN_SETJMP
>> > -      rtx x, last;
>> > +      rtx x;
>> >        x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
>> >     TYPE_MODE (integer_type_node), 1,
>> >     plus_constant (Pmode, XEXP (fc, 0),
>> > Index: gcc/stmt.c
>> > ===================================================================
>> > --- gcc/stmt.c (revision 192488)
>> > +++ gcc/stmt.c (working copy)
>> > @@ -1867,6 +1867,8 @@ get_outgoing_edge_probs (basic_block bb)
>> >    edge e;
>> >    edge_iterator ei;
>> >    int prob_sum = 0;
>> > +  if (!bb)
>> > +    return 0;
>> >    FOR_EACH_EDGE(e, ei, bb->succs)
>> >      prob_sum += e->probability;
>> >    return prob_sum;
>> > @@ -1916,8 +1918,8 @@ emit_case_dispatch_table (tree index_expr, tree in
>> >    rtx fallback_label = label_rtx (case_list->code_label);
>> >    rtx table_label = gen_label_rtx ();
>> >    bool has_gaps = false;
>> > -  edge default_edge = EDGE_SUCC(stmt_bb, 0);
>> > -  int default_prob = default_edge->probability;
>> > +  edge default_edge = stmt_bb ? EDGE_SUCC(stmt_bb, 0) : NULL;
>> > +  int default_prob = default_edge ? default_edge->probability : 0;
>> >    int base = get_outgoing_edge_probs (stmt_bb);
>> >    bool try_with_tablejump = false;
>> >
>> > @@ -1997,7 +1999,8 @@ emit_case_dispatch_table (tree index_expr, tree in
>> >        default_prob = 0;
>> >      }
>> >
>> > -  default_edge->probability = default_prob;
>> > +  if (default_edge)
>> > +    default_edge->probability = default_prob;
>> >
>> >    /* We have altered the probability of the default edge. So the probabilities
>> >       of all other edges need to be adjusted so that it sums up to
>> > @@ -2289,7 +2292,8 @@ expand_sjlj_dispatch_table (rtx dispatch_index,
>> >
>> >        emit_case_dispatch_table (index_expr, index_type,
>> >   case_list, default_label,
>> > - minval, maxval, range, NULL);
>> > + minval, maxval, range,
>> > +                                BLOCK_FOR_INSN (before_case));
>> >        emit_label (default_label);
>> >        free_alloc_pool (case_node_pool);
>> >      }
Easwaran Raman Oct. 25, 2012, 8:56 p.m. UTC | #4
Hi,

On Tue, Oct 23, 2012 at 3:03 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
>> Ping.
>>
>>
>> On Wed, Oct 17, 2012 at 1:48 PM, Easwaran Raman <eraman@google.com> wrote:
>> > Hi,
>> >  This patch fixes bugs introduced by my previous patch to propagate
>> > profiles during switch expansion. Bootstrap and profiledbootstrap
>> > successful on x86_64. Confirmed that it fixes the crashes reported in
>> > PR middle-end/54957. OK for trunk?
>> >
>> > - Easwaran
>> >
>> > 2012-10-17   Easwaran Raman  <eraman@google.com>
>> >
>> >         PR target/54938
>> >         PR middle-end/54957
>> >         * optabs.c (emit_cmp_and_jump_insn_1): Add REG_BR_PROB note
>> >         only if it doesn't already exist.
>> >         * except.c (sjlj_emit_function_enter): Remove unused variable.
>> >         * stmt.c (get_outgoing_edge_probs): Return 0 if BB is NULL.
>
> Seems fine, but under what conditions you get NULL here?
Wasn't sure if this is an OK for the patch or if I need to address
anything else.

Thanks,
Easwaran

>
> Honza
>> >         (emit_case_dispatch_table): Handle the case where STMT_BB is
>> >         NULL.
>> >         (expand_sjlj_dispatch_table): Pass BB containing before_case
>> >         to emit_case_dispatch_table.
>> >
>> > Index: gcc/optabs.c
>> > ===================================================================
>> > --- gcc/optabs.c (revision 192488)
>> > +++ gcc/optabs.c (working copy)
>> > @@ -4268,11 +4268,9 @@ emit_cmp_and_jump_insn_1 (rtx test, enum machine_m
>> >        && profile_status != PROFILE_ABSENT
>> >        && insn
>> >        && JUMP_P (insn)
>> > -      && any_condjump_p (insn))
>> > -    {
>> > -      gcc_assert (!find_reg_note (insn, REG_BR_PROB, 0));
>> > -      add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
>> > -    }
>> > +      && any_condjump_p (insn)
>> > +      && !find_reg_note (insn, REG_BR_PROB, 0))
>> > +    add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
>> >  }
>> >
>> >  /* Generate code to compare X with Y so that the condition codes are
>> > Index: gcc/except.c
>> > ===================================================================
>> > --- gcc/except.c (revision 192488)
>> > +++ gcc/except.c (working copy)
>> > @@ -1153,7 +1153,7 @@ sjlj_emit_function_enter (rtx dispatch_label)
>> >    if (dispatch_label)
>> >      {
>> >  #ifdef DONT_USE_BUILTIN_SETJMP
>> > -      rtx x, last;
>> > +      rtx x;
>> >        x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
>> >     TYPE_MODE (integer_type_node), 1,
>> >     plus_constant (Pmode, XEXP (fc, 0),
>> > Index: gcc/stmt.c
>> > ===================================================================
>> > --- gcc/stmt.c (revision 192488)
>> > +++ gcc/stmt.c (working copy)
>> > @@ -1867,6 +1867,8 @@ get_outgoing_edge_probs (basic_block bb)
>> >    edge e;
>> >    edge_iterator ei;
>> >    int prob_sum = 0;
>> > +  if (!bb)
>> > +    return 0;
>> >    FOR_EACH_EDGE(e, ei, bb->succs)
>> >      prob_sum += e->probability;
>> >    return prob_sum;
>> > @@ -1916,8 +1918,8 @@ emit_case_dispatch_table (tree index_expr, tree in
>> >    rtx fallback_label = label_rtx (case_list->code_label);
>> >    rtx table_label = gen_label_rtx ();
>> >    bool has_gaps = false;
>> > -  edge default_edge = EDGE_SUCC(stmt_bb, 0);
>> > -  int default_prob = default_edge->probability;
>> > +  edge default_edge = stmt_bb ? EDGE_SUCC(stmt_bb, 0) : NULL;
>> > +  int default_prob = default_edge ? default_edge->probability : 0;
>> >    int base = get_outgoing_edge_probs (stmt_bb);
>> >    bool try_with_tablejump = false;
>> >
>> > @@ -1997,7 +1999,8 @@ emit_case_dispatch_table (tree index_expr, tree in
>> >        default_prob = 0;
>> >      }
>> >
>> > -  default_edge->probability = default_prob;
>> > +  if (default_edge)
>> > +    default_edge->probability = default_prob;
>> >
>> >    /* We have altered the probability of the default edge. So the probabilities
>> >       of all other edges need to be adjusted so that it sums up to
>> > @@ -2289,7 +2292,8 @@ expand_sjlj_dispatch_table (rtx dispatch_index,
>> >
>> >        emit_case_dispatch_table (index_expr, index_type,
>> >   case_list, default_label,
>> > - minval, maxval, range, NULL);
>> > + minval, maxval, range,
>> > +                                BLOCK_FOR_INSN (before_case));
>> >        emit_label (default_label);
>> >        free_alloc_pool (case_node_pool);
>> >      }
Jan Hubicka Oct. 26, 2012, 3:05 p.m. UTC | #5
> Hi,
> 
> On Tue, Oct 23, 2012 at 3:03 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
> >> Ping.
> >>
> >>
> >> On Wed, Oct 17, 2012 at 1:48 PM, Easwaran Raman <eraman@google.com> wrote:
> >> > Hi,
> >> >  This patch fixes bugs introduced by my previous patch to propagate
> >> > profiles during switch expansion. Bootstrap and profiledbootstrap
> >> > successful on x86_64. Confirmed that it fixes the crashes reported in
> >> > PR middle-end/54957. OK for trunk?
> >> >
> >> > - Easwaran
> >> >
> >> > 2012-10-17   Easwaran Raman  <eraman@google.com>
> >> >
> >> >         PR target/54938
> >> >         PR middle-end/54957
> >> >         * optabs.c (emit_cmp_and_jump_insn_1): Add REG_BR_PROB note
> >> >         only if it doesn't already exist.
> >> >         * except.c (sjlj_emit_function_enter): Remove unused variable.
> >> >         * stmt.c (get_outgoing_edge_probs): Return 0 if BB is NULL.
> >
> > Seems fine, but under what conditions you get NULL here?
> Wasn't sure if this is an OK for the patch or if I need to address
> anything else.

Actually I think you should make the except.c to setcurrent_bb when expanding
the switch instead.
OK with this change.

Honza
Easwaran Raman Oct. 31, 2012, 6:08 p.m. UTC | #6
On Fri, Oct 26, 2012 at 8:05 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
>> Hi,
>>
>> On Tue, Oct 23, 2012 at 3:03 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
>> >> Ping.
>> >>
>> >>
>> >> On Wed, Oct 17, 2012 at 1:48 PM, Easwaran Raman <eraman@google.com> wrote:
>> >> > Hi,
>> >> >  This patch fixes bugs introduced by my previous patch to propagate
>> >> > profiles during switch expansion. Bootstrap and profiledbootstrap
>> >> > successful on x86_64. Confirmed that it fixes the crashes reported in
>> >> > PR middle-end/54957. OK for trunk?
>> >> >
>> >> > - Easwaran
>> >> >
>> >> > 2012-10-17   Easwaran Raman  <eraman@google.com>
>> >> >
>> >> >         PR target/54938
>> >> >         PR middle-end/54957
>> >> >         * optabs.c (emit_cmp_and_jump_insn_1): Add REG_BR_PROB note
>> >> >         only if it doesn't already exist.
>> >> >         * except.c (sjlj_emit_function_enter): Remove unused variable.
>> >> >         * stmt.c (get_outgoing_edge_probs): Return 0 if BB is NULL.
>> >
>> > Seems fine, but under what conditions you get NULL here?
>> Wasn't sure if this is an OK for the patch or if I need to address
>> anything else.
>
> Actually I think you should make the except.c to setcurrent_bb when expanding
> the switch instead.

In the current code, in sjlj_emit_dispatch_table (except.c), a
sequence of instructions including the dispatch table jump are first
generated and emitted to a BB before the first of the jump table
targets. I think you are asking me to first emit the instructions
before the indirect jump into a new bb so that BLOCK_FOR_INSN
(before_case) in stmt.c is non NULL. This would need some refactoring
inside except.c, but more importantly this BB won't have the correct
control flow right? So, while I can avoid the check for BB being NULL
in get_outgoing_edge_probs, I still need to guard for default_edge
being NULL and default_prob will still be 0. Would it be ok if I
remove the check for NULL inside get_outgoing_edge_probs and instead
check it when I initialize BASE?

Thanks,
Easwaran

> OK with this change.
>
> Honza
Jan Hubicka Oct. 31, 2012, 11:06 p.m. UTC | #7
> On Fri, Oct 26, 2012 at 8:05 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
> >> Hi,
> >>
> >> On Tue, Oct 23, 2012 at 3:03 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
> >> >> Ping.
> >> >>
> >> >>
> >> >> On Wed, Oct 17, 2012 at 1:48 PM, Easwaran Raman <eraman@google.com> wrote:
> >> >> > Hi,
> >> >> >  This patch fixes bugs introduced by my previous patch to propagate
> >> >> > profiles during switch expansion. Bootstrap and profiledbootstrap
> >> >> > successful on x86_64. Confirmed that it fixes the crashes reported in
> >> >> > PR middle-end/54957. OK for trunk?
> >> >> >
> >> >> > - Easwaran
> >> >> >
> >> >> > 2012-10-17   Easwaran Raman  <eraman@google.com>
> >> >> >
> >> >> >         PR target/54938
> >> >> >         PR middle-end/54957
> >> >> >         * optabs.c (emit_cmp_and_jump_insn_1): Add REG_BR_PROB note
> >> >> >         only if it doesn't already exist.
> >> >> >         * except.c (sjlj_emit_function_enter): Remove unused variable.
> >> >> >         * stmt.c (get_outgoing_edge_probs): Return 0 if BB is NULL.
> >> >
> >> > Seems fine, but under what conditions you get NULL here?
> >> Wasn't sure if this is an OK for the patch or if I need to address
> >> anything else.
> >
> > Actually I think you should make the except.c to setcurrent_bb when expanding
> > the switch instead.
> 
> In the current code, in sjlj_emit_dispatch_table (except.c), a
> sequence of instructions including the dispatch table jump are first
> generated and emitted to a BB before the first of the jump table
> targets. I think you are asking me to first emit the instructions
> before the indirect jump into a new bb so that BLOCK_FOR_INSN
> (before_case) in stmt.c is non NULL. This would need some refactoring
> inside except.c, but more importantly this BB won't have the correct
> control flow right? So, while I can avoid the check for BB being NULL
> in get_outgoing_edge_probs, I still need to guard for default_edge
> being NULL and default_prob will still be 0. Would it be ok if I
> remove the check for NULL inside get_outgoing_edge_probs and instead
> check it when I initialize BASE?

Hmm,
in general we should set insn_bb for all emit code since some code size/speed
tradeoffs are fixed at expansion time and EH code is a good example where it
would make difference (because it is almost always cold).  But I see it
will be more work, since except.c is somewhat dodgy about how it creates the
control flow.

I guess it is OK to go with the original version of the patch and hopefully
we can clean this up incrementally.

thanks,
Honza
> 
> Thanks,
> Easwaran
> 
> > OK with this change.
> >
> > Honza
diff mbox

Patch

Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c (revision 192488)
+++ gcc/optabs.c (working copy)
@@ -4268,11 +4268,9 @@  emit_cmp_and_jump_insn_1 (rtx test, enum machine_m
       && profile_status != PROFILE_ABSENT
       && insn
       && JUMP_P (insn)
-      && any_condjump_p (insn))
-    {
-      gcc_assert (!find_reg_note (insn, REG_BR_PROB, 0));
-      add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
-    }
+      && any_condjump_p (insn)
+      && !find_reg_note (insn, REG_BR_PROB, 0))
+    add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
 }

 /* Generate code to compare X with Y so that the condition codes are
Index: gcc/except.c
===================================================================
--- gcc/except.c (revision 192488)
+++ gcc/except.c (working copy)
@@ -1153,7 +1153,7 @@  sjlj_emit_function_enter (rtx dispatch_label)
   if (dispatch_label)
     {
 #ifdef DONT_USE_BUILTIN_SETJMP
-      rtx x, last;
+      rtx x;
       x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
    TYPE_MODE (integer_type_node), 1,
    plus_constant (Pmode, XEXP (fc, 0),
Index: gcc/stmt.c
===================================================================
--- gcc/stmt.c (revision 192488)
+++ gcc/stmt.c (working copy)
@@ -1867,6 +1867,8 @@  get_outgoing_edge_probs (basic_block bb)
   edge e;
   edge_iterator ei;
   int prob_sum = 0;
+  if (!bb)
+    return 0;
   FOR_EACH_EDGE(e, ei, bb->succs)
     prob_sum += e->probability;
   return prob_sum;
@@ -1916,8 +1918,8 @@  emit_case_dispatch_table (tree index_expr, tree in
   rtx fallback_label = label_rtx (case_list->code_label);
   rtx table_label = gen_label_rtx ();
   bool has_gaps = false;
-  edge default_edge = EDGE_SUCC(stmt_bb, 0);
-  int default_prob = default_edge->probability;
+  edge default_edge = stmt_bb ? EDGE_SUCC(stmt_bb, 0) : NULL;
+  int default_prob = default_edge ? default_edge->probability : 0;
   int base = get_outgoing_edge_probs (stmt_bb);
   bool try_with_tablejump = false;

@@ -1997,7 +1999,8 @@  emit_case_dispatch_table (tree index_expr, tree in
       default_prob = 0;
     }

-  default_edge->probability = default_prob;
+  if (default_edge)
+    default_edge->probability = default_prob;

   /* We have altered the probability of the default edge. So the probabilities
      of all other edges need to be adjusted so that it sums up to
@@ -2289,7 +2292,8 @@  expand_sjlj_dispatch_table (rtx dispatch_index,

       emit_case_dispatch_table (index_expr, index_type,
  case_list, default_label,
- minval, maxval, range, NULL);
+ minval, maxval, range,
+                                BLOCK_FOR_INSN (before_case));
       emit_label (default_label);
       free_alloc_pool (case_node_pool);
     }