On 27 March 2015 at 03:14, Jan Hubicka <hubi...@ucw.cz> wrote:
>> On 2015.03.27 at 00:46 +0100, Jan Hubicka wrote:
>> > > On 26 March 2015 at 22:12, Jan Hubicka <hubi...@ucw.cz> wrote:
>> > > After this fix, I can see build failures in glibc:
>> > > key_call.c:574:1: internal compiler error: in inline_call, at
>> > > ipa-inline-transform.c:386
>> >
>> > Can you please send me preprocessed testcase? It is probably another 
>> > misaccounting
>> > bug in ipa-inline-analysis.  I may just silence this assert for this stage 
>> > 4.
>>
>> Also happens when building the Linux kernel:
>>
>> trippels@gcc2-power8 linux-3.18.8 % cat nf_sockopt.i
>> int a;
>> int (*b)(), (*c)();
>> int fn1(int p1) {
>>   if (a)
>>     return 0;
>>   if (p1) {
>>     c();
>>     b();
>>   }
>> }
>> void fn2() { fn1(0); }
>
> Great, Markus, having a testcase is important for covering this code path.
> I am attaching a fix, will test it with your testcase and commit.
>
>         * ipa-inline-analysis.c (redirect_to_unreachable): Be prepared for
>         edge to change by speculation resolution or redirection.
>         (edge_set_predicate): Likewise.
>         (inline_summary_t::duplicate): Likewise.
>         (remap_edge_summaries): Likewise.

This commit (221718) does fix the problems I saw, thanks.

Christophe.

> Index: ipa-inline-analysis.c
> ===================================================================
> --- ipa-inline-analysis.c       (revision 221706)
> +++ ipa-inline-analysis.c       (working copy)
> @@ -762,20 +762,20 @@ account_size_time (struct inline_summary
>
>  /* We proved E to be unreachable, redirect it to __bultin_unreachable.  */
>
> -static void
> +static struct cgraph_edge *
>  redirect_to_unreachable (struct cgraph_edge *e)
>  {
>    struct cgraph_node *callee = !e->inline_failed ? e->callee : NULL;
> -  struct inline_edge_summary *es = inline_edge_summary (e);
>
>    if (e->speculative)
> -    e->resolve_speculation (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
> -  if (!e->callee)
> +    e = e->resolve_speculation (builtin_decl_implicit 
> (BUILT_IN_UNREACHABLE));
> +  else if (!e->callee)
>      e->make_direct (cgraph_node::get_create
>                       (builtin_decl_implicit (BUILT_IN_UNREACHABLE)));
>    else
>      e->redirect_callee (cgraph_node::get_create
>                         (builtin_decl_implicit (BUILT_IN_UNREACHABLE)));
> +  struct inline_edge_summary *es = inline_edge_summary (e);
>    e->inline_failed = CIF_UNREACHABLE;
>    e->frequency = 0;
>    e->count = 0;
> @@ -783,6 +783,7 @@ redirect_to_unreachable (struct cgraph_e
>    es->call_stmt_time = 0;
>    if (callee)
>      callee->remove_symbol_and_inline_clones ();
> +  return e;
>  }
>
>  /* Set predicate for edge E.  */
> @@ -790,12 +791,12 @@ redirect_to_unreachable (struct cgraph_e
>  static void
>  edge_set_predicate (struct cgraph_edge *e, struct predicate *predicate)
>  {
> -  struct inline_edge_summary *es = inline_edge_summary (e);
> -
>    /* If the edge is determined to be never executed, redirect it
>       to BUILTIN_UNREACHABLE to save inliner from inlining into it.  */
>    if (predicate && false_predicate_p (predicate))
> -    redirect_to_unreachable (e);
> +    e = redirect_to_unreachable (e);
> +
> +  struct inline_edge_summary *es = inline_edge_summary (e);
>    if (predicate && !true_predicate_p (predicate))
>      {
>        if (!es->predicate)
> @@ -1184,7 +1185,7 @@ inline_summary_t::duplicate (cgraph_node
>        size_time_entry *e;
>        int optimized_out_size = 0;
>        bool inlined_to_p = false;
> -      struct cgraph_edge *edge;
> +      struct cgraph_edge *edge, *next;
>
>        info->entry = 0;
>        known_vals.safe_grow_cleared (count);
> @@ -1229,10 +1230,11 @@ inline_summary_t::duplicate (cgraph_node
>
>        /* Remap edge predicates with the same simplification as above.
>           Also copy constantness arrays.   */
> -      for (edge = dst->callees; edge; edge = edge->next_callee)
> +      for (edge = dst->callees; edge; edge = next)
>         {
>           struct predicate new_predicate;
>           struct inline_edge_summary *es = inline_edge_summary (edge);
> +         next = edge->next_callee;
>
>           if (!edge->inline_failed)
>             inlined_to_p = true;
> @@ -1249,10 +1251,11 @@ inline_summary_t::duplicate (cgraph_node
>
>        /* Remap indirect edge predicates with the same simplificaiton as 
> above.
>           Also copy constantness arrays.   */
> -      for (edge = dst->indirect_calls; edge; edge = edge->next_callee)
> +      for (edge = dst->indirect_calls; edge; edge = next)
>         {
>           struct predicate new_predicate;
>           struct inline_edge_summary *es = inline_edge_summary (edge);
> +         next = edge->next_callee;
>
>           gcc_checking_assert (edge->inline_failed);
>           if (!es->predicate)
> @@ -3484,11 +3487,12 @@ remap_edge_summaries (struct cgraph_edge
>                       clause_t possible_truths,
>                       struct predicate *toplev_predicate)
>  {
> -  struct cgraph_edge *e;
> -  for (e = node->callees; e; e = e->next_callee)
> +  struct cgraph_edge *e, *next;
> +  for (e = node->callees; e; e = next)
>      {
>        struct inline_edge_summary *es = inline_edge_summary (e);
>        struct predicate p;
> +      next = e->next_callee;
>
>        if (e->inline_failed)
>         {
> @@ -3509,10 +3513,11 @@ remap_edge_summaries (struct cgraph_edge
>                               operand_map, offset_map, possible_truths,
>                               toplev_predicate);
>      }
> -  for (e = node->indirect_calls; e; e = e->next_callee)
> +  for (e = node->indirect_calls; e; e = next)
>      {
>        struct inline_edge_summary *es = inline_edge_summary (e);
>        struct predicate p;
> +      next = e->next_callee;
>
>        remap_edge_change_prob (inlined_edge, e);
>        if (es->predicate)

Reply via email to