------- Comment #2 from hubicka at gcc dot gnu dot org  2010-09-17 01:05 -------
OK, problem is that we both devirtualize and clone the destination function.
Then when producing clone, we run into:
cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node,
                                        gimple old_stmt, tree old_call, gimple
new_stmt)
{
  tree new_call = (is_gimple_call (new_stmt)) ? gimple_call_fndecl (new_stmt) :
0;

  /* We are seeing indirect calls, then there is nothing to update.  */
  if (!new_call && !old_call)
    return;
  /* See if we turned indirect call into direct call or folded call to one
builtin
     into different bultin.  */
  if (old_call != new_call)
    { 
      struct cgraph_edge *e = cgraph_edge (node, old_stmt);
      struct cgraph_edge *ne = NULL;
      gcov_type count;
      int frequency;
      int loop_nest;

      if (e)
        { 
          /* See if the edge is already there and has the correct callee.  It
             might be so because of indirect inlining has already updated
             it.  */
          if (new_call && e->callee && e->callee->decl == new_call)
            return;

          /* Otherwise remove edge and create new one; we can't simply redirect
             since function has changed, so inline plan and other information
             attached to edge is invalid.  */

and kill the inline plan.  This code is intended to handle bulitins, I guess
we will need to look out if the decl can be redirected to decl in the function.

Honza


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45621

Reply via email to