diff mbox

Fix crossmodule inline hint

Message ID 20150203020507.GG3959@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka Feb. 3, 2015, 2:05 a.m. UTC
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.
diff mbox

Patch

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