This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix crossmodule inline hint
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 3 Feb 2015 03:05:08 +0100
- Subject: Fix crossmodule inline hint
- Authentication-results: sourceware.org; auth=none
Hi,
inliner uses crossmodule hint that during LTO preffers in-module inlining
over cross-module. This hint is wrong for comdats that gets merged and
thus the module information is more or less random.
The patch fixes it by adding merged flag to cgraph_node indicating merged
comdats and always disabling the hint for those.
Bootstrapped/regtested x86_64-linux.
Honza
* ipa-inline-analysis.c (simple_edge_hints): Fix check for
cross-module inlining.
* cgraph.h (cgraph_node): Add flag merged.
* ipa-icf.c (sem_function::merge): Maintain it.
* lto-symtab.c (lto_cgraph_replace_node): Maintain merged flag.
Index: ipa-inline-analysis.c
===================================================================
--- ipa-inline-analysis.c (revision 220329)
+++ ipa-inline-analysis.c (working copy)
@@ -3702,13 +3702,15 @@ simple_edge_hints (struct cgraph_edge *e
int hints = 0;
struct cgraph_node *to = (edge->caller->global.inlined_to
? edge->caller->global.inlined_to : edge->caller);
+ struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
if (inline_summaries->get (to)->scc_no
&& inline_summaries->get (to)->scc_no == inline_summaries->get (edge->callee)->scc_no
&& !edge->recursive_p ())
hints |= INLINE_HINT_same_scc;
- if (to->lto_file_data && edge->callee->lto_file_data
- && to->lto_file_data != edge->callee->lto_file_data)
+ if (callee->lto_file_data && edge->caller->lto_file_data
+ && edge->caller->lto_file_data != callee->lto_file_data
+ && !callee->merged)
hints |= INLINE_HINT_cross_module;
return hints;
Index: ipa-icf.c
===================================================================
--- ipa-icf.c (revision 220329)
+++ ipa-icf.c (working copy)
@@ -711,6 +711,10 @@ sem_function::merge (sem_item *alias_ite
}
alias->icf_merged = true;
+ if (local_original->lto_file_data
+ && alias->lto_file_data
+ && local_original->lto_file_data != alias->lto_file_data)
+ local_original->merged = true;
/* The alias function is removed if symbol address
does not matter. */
@@ -725,6 +729,10 @@ sem_function::merge (sem_item *alias_ite
else if (create_alias)
{
alias->icf_merged = true;
+ if (local_original->lto_file_data
+ && alias->lto_file_data
+ && local_original->lto_file_data != alias->lto_file_data)
+ local_original->merged = true;
/* Remove the function's body. */
ipa_merge_profiles (original, alias);
@@ -762,6 +770,10 @@ sem_function::merge (sem_item *alias_ite
}
alias->icf_merged = true;
+ if (local_original->lto_file_data
+ && alias->lto_file_data
+ && local_original->lto_file_data != alias->lto_file_data)
+ local_original->merged = true;
ipa_merge_profiles (local_original, alias, true);
alias->create_wrapper (local_original);
Index: lto/lto-symtab.c
===================================================================
--- lto/lto-symtab.c (revision 220329)
+++ lto/lto-symtab.c (working copy)
@@ -88,6 +88,8 @@ lto_cgraph_replace_node (struct cgraph_n
gcc_assert (!prevailing_node->global.inlined_to);
prevailing_node->mark_address_taken ();
}
+ if (node->definition && prevailing_node->definition)
+ prevailing_node->merged = true;
/* Redirect all incoming edges. */
compatible_p
Index: cgraph.h
===================================================================
--- cgraph.h (revision 220329)
+++ cgraph.h (working copy)
@@ -1296,6 +1296,8 @@ public:
other operation that could make previously non-trapping memory
accesses trapping. */
unsigned nonfreeing_fn : 1;
+ /* True if there was multiple COMDAT bodies merged by lto-symtab. */
+ unsigned merged : 1;
};
/* A cgraph node set is a collection of cgraph nodes. A cgraph node