On Tue, 4 Feb 2014, Jan Hubicka wrote:

> Hi,
> while playing around with devirtualization I tried to make it to always 
> produce
> builtin_unreachable ().  This makes early inliner to ICE, since the callgraph 
> edges
> are not properly updated after folding. This is because 
> cgraph_update_edges_for_call_stmt
> is called on a wrong statement.
> 
> Does something like this look resonable?

Hmm, the code looks messy.  Can you re-organize it like

  gimple prev = NULL;
  for (gsi = gsi_start_bb ....)
    {
      gimple old_stmt = gsi_stmt (gsi);
      if (fold_stmt (gsi))
        {
          if (is_gimple_call (old_stmt))
            {
              gimple_stmt_iterator i = gsi;
              do
                {
                  new_stmt = gsi_stmt (i);
                  if (is_gimple_call (new_stmt))
                    {
                      ... do call stuff ...
                      break;
                    }
                  gsi_prev (&i)
                }
              while (!gsi_end_p (i) && gsi_stmt (i) != prev);
            }
          new_stmt = gsi_stmt (gsi);
          if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt))
            gimple_purge_dead_eh_edges (...)
          prev = new_stmt;
        }
      else
        prev = old_stmt;
    }

thus merge the special builtin handling with the general call handling?

Thanks,
Richard.

> Honza
> 
>       * tree-inline.c (fold_marked_statements): Correctly handle cases where
>       folding produes extra statement.
> Index: tree-inline.c
> ===================================================================
> --- tree-inline.c     (revision 207438)
> +++ tree-inline.c     (working copy)
> @@ -4480,8 +4480,14 @@ fold_marked_statements (int first, struc
>         if (pointer_set_contains (statements, gsi_stmt (gsi)))
>           {
>             gimple old_stmt = gsi_stmt (gsi);
> +           gimple_stmt_iterator prev = gsi;
> +           gimple prev_stmt = NULL;
>             tree old_decl = is_gimple_call (old_stmt) ? gimple_call_fndecl 
> (old_stmt) : 0;
>  
> +           gsi_prev (&prev);
> +           if (!gsi_end_p (prev))
> +             prev_stmt = gsi_stmt (prev);
> +
>             if (old_decl && DECL_BUILT_IN (old_decl))
>               {
>                 /* Folding builtins can create multiple instructions,
> @@ -4541,8 +4547,31 @@ fold_marked_statements (int first, struc
>  
>                 if (is_gimple_call (old_stmt)
>                     || is_gimple_call (new_stmt))
> -                 cgraph_update_edges_for_call_stmt (old_stmt, old_decl,
> -                                                    new_stmt);
> +                 {
> +                   if (!is_gimple_call (new_stmt))
> +                     {
> +                       prev = gsi;
> +                       gsi_prev (&prev);
> +
> +                       /* Fold stmt may turn
> +
> +                          retval = call ();
> +
> +                          statement into
> +
> +                          __builtin_unreachable ();
> +                          retval = dummy.
> +
> +                          Be sure to look up the call.  */
> +                          
> +                       if (!gsi_end_p (prev)
> +                           && gsi_stmt (prev) != prev_stmt
> +                           && is_gimple_call (gsi_stmt (prev)))
> +                          new_stmt = gsi_stmt (prev);
> +                     }
> +                   cgraph_update_edges_for_call_stmt (old_stmt, old_decl,
> +                                                      new_stmt);
> +                 }
>  
>                 if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt))
>                   gimple_purge_dead_eh_edges (BASIC_BLOCK_FOR_FN (cfun,
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend"orffer

Reply via email to