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; + } + } }