Hi,
this patch fixes ICE while building Firefox (and probably xalancbmk, too)
with -O3 -flto.  I originally tested the whole patchset on several bigger apps
including the inline heuristics change which teach it that thunks are very 
cheap.
Mainline doesn't contain it that makes us to inline into thunks more heavilly
and results in some suprises.  I hope it is last one.

Bootstrapped/regtested x86_64-linux, I am re-testing with last minute change
and will commit afterwards.

Honza

        * ipa-inline-transform.c (preserve_function_body_p): Look for
        first non-thunk clone.
        * lto-cgraph.c (lto_output_edge): When streaming thunk do not look
        up call stmt id.
        (lto_output_node): Inline thunks don't need body in every
        partition.
        * lto-streamer-in.c: Do not fixup thunk clones.
Index: ipa-inline-transform.c
===================================================================
--- ipa-inline-transform.c      (revision 236275)
+++ ipa-inline-transform.c      (working copy)
@@ -587,9 +587,10 @@ preserve_function_body_p (struct cgraph_
   gcc_assert (symtab->global_info_ready);
   gcc_assert (!node->alias && !node->thunk.thunk_p);
 
-  /* Look if there is any clone around.  */
-  if (node->clones && !node->clones->thunk.thunk_p)
-    return true;
+  /* Look if there is any non-thunk clone around.  */
+  for (node = node->clones; node; node = node->next_sibling_clone)
+    if (!node->thunk.thunk_p)
+      return true;
   return false;
 }
 
Index: lto-cgraph.c
===================================================================
--- lto-cgraph.c        (revision 236275)
+++ lto-cgraph.c        (working copy)
@@ -259,7 +259,7 @@ lto_output_edge (struct lto_simple_outpu
   streamer_write_gcov_count_stream (ob->main_stream, edge->count);
 
   bp = bitpack_create (ob->main_stream);
-  uid = (!gimple_has_body_p (edge->caller->decl)
+  uid = (!gimple_has_body_p (edge->caller->decl) || edge->caller->thunk.thunk_p
         ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt) + 1);
   bp_pack_enum (&bp, cgraph_inline_failed_t,
                CIF_N_REASONS, edge->inline_failed);
@@ -398,7 +398,8 @@ lto_output_node (struct lto_simple_outpu
 
   boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node);
 
-  if (node->analyzed && (!boundary_p || node->alias || node->thunk.thunk_p))
+  if (node->analyzed && (!boundary_p || node->alias
+                        || (node->thunk.thunk_p && !node->global.inlined_to)))
     tag = LTO_symtab_analyzed_node;
   else
     tag = LTO_symtab_unavail_node;
Index: lto-streamer-in.c
===================================================================
--- lto-streamer-in.c   (revision 236275)
+++ lto-streamer-in.c   (working copy)
@@ -952,20 +952,21 @@ fixup_call_stmt_edges (struct cgraph_nod
   fixup_call_stmt_edges_1 (orig, stmts, fn);
   if (orig->clones)
     for (node = orig->clones; node != orig;)
-      {
-       fixup_call_stmt_edges_1 (node, stmts, fn);
-       if (node->clones)
-         node = node->clones;
-       else if (node->next_sibling_clone)
-         node = node->next_sibling_clone;
-       else
-         {
-           while (node != orig && !node->next_sibling_clone)
-             node = node->clone_of;
-           if (node != orig)
-             node = node->next_sibling_clone;
-         }
-      }
+      if (!node->thunk.thunk_p)
+       {
+         fixup_call_stmt_edges_1 (node, stmts, fn);
+         if (node->clones)
+           node = node->clones;
+         else if (node->next_sibling_clone)
+           node = node->next_sibling_clone;
+         else
+           {
+             while (node != orig && !node->next_sibling_clone)
+               node = node->clone_of;
+             if (node != orig)
+               node = node->next_sibling_clone;
+           }
+       }
 }
 
 

Reply via email to