From 530f3a1bf62964c0c52d6fcf4ca0d321ce9d5156 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 26 Oct 2010 18:40:16 +0200 Subject: re PR lto/45736 (ICE: in cgraph_remove_unreachable_nodes, at ipa.c:245 with -flto and attribute((constructor))) PR middle-end/45736 * cgraph.c (cgraph_set_readonly_flag): Rename to... (cgraph_set_const_flags) ... this one; get also looping argument; clear constructor/destructor flags. (cgraph_set_pure_flag): Likewise. (cgraph_set_looping_const_or_pure_flag): Remove. (cgraph_can_remove_if_no_direct_calls_and_refs): Do not try to optimize away static ctors/dtors; it does not work on inline clones; external functions can always be rmeoved. (cgraph_will_be_removed_from_program_if_no_direct_calls): Assert on inline clones; in LTO external functions always can go. (cgraph_used_from_object_file_p): Handle EXTERNAL functions correctly. (cgraph_mark_address_taken_node): Assert that we are not taking address of inline clone. (cgraph_can_remove_if_no_direct_calls_p): We always eventually remove external functions. * ipa-cp.c (ipcp_cloning_candidate_p): Do not clone functions with address taken. (ipcp_initialize_node_lattices): Only local functions can be handled without cloning. * cgraph.h (cgraph_set_readonly_flag, cgraph_set_looping_const_or_pure_flag): Remove. (cgraph_set_const_flag): Declare. (cgraph_set_pure_flag): Update. * ipa-pure-const (propagate_pure_const, local_pure_const): Update flags setting code. * ipa.c (cgraph_remove_unreachable_nodes): Fix formating; do not look at inline clones; fix handling of external definitions. (cgraph_postorder): Do not look at inline clones in the first pass. (function_and_variable_visibility): Drop constructors/destructor flags at pure and const functions. * tree-profile.c (tree_profiling): Update. * ipa-inline.c (cgraph_clone_inlined_nodes): Always clone functions with address taken; external functions do not account to whole program size. (cgraph_decide_inlining): Likewise; do not try to inline functions already inlined. * testsuite/gcc.dg/lto/pr45736_0.c: New function. From-SVN: r165972 --- gcc/ipa-inline.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'gcc/ipa-inline.c') diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 8d9db0b..7241dcb 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -250,6 +250,10 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, /* We may eliminate the need for out-of-line copy to be output. In that case just go ahead and re-use it. */ if (!e->callee->callers->next_caller + /* FIXME: When address is taken of DECL_EXTERNAL function we still can remove its + offline copy, but we would need to keep unanalyzed node in the callgraph so + references can point to it. */ + && !e->callee->address_taken && cgraph_can_remove_if_no_direct_calls_p (e->callee) /* Inlining might enable more devirtualizing, so we want to remove those only after all devirtualizable virtual calls are processed. @@ -264,7 +268,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, && !cgraph_new_nodes) { gcc_assert (!e->callee->global.inlined_to); - if (e->callee->analyzed) + if (e->callee->analyzed && !DECL_EXTERNAL (e->callee->decl)) { overall_size -= e->callee->global.size; nfunctions_inlined++; @@ -1449,7 +1453,8 @@ cgraph_decide_inlining (void) struct cgraph_edge *e; gcc_assert (inline_summary (node)->self_size == node->global.size); - initial_size += node->global.size; + if (!DECL_EXTERNAL (node->decl)) + initial_size += node->global.size; for (e = node->callees; e; e = e->next_callee) if (max_count < e->count) max_count = e->count; @@ -1512,6 +1517,7 @@ cgraph_decide_inlining (void) if (node->callers && !node->callers->next_caller + && !node->global.inlined_to && cgraph_will_be_removed_from_program_if_no_direct_calls (node) && node->local.inlinable && cgraph_function_body_availability (node) >= AVAIL_AVAILABLE -- cgit v1.1