diff mbox

Consider polymorphic call targets to be part of boundary

Message ID 20130910135551.GC18625@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka Sept. 10, 2013, 1:55 p.m. UTC
Hi,
this patch adds polymorphic call targets into the boundary of an unit.  This enables
more late devirtualization. I briefly measured size on effect of WPA->ltrans files
on firefox and they still seem to be around 2GB.

Bootstrapped/regtested x86_64-linux, comitted.

	* lto-cgraph.c: Include ipa-utils.h.
	(compute_ltrans_boundary): Also add possible targets into the boundary.
diff mbox

Patch

Index: lto-cgraph.c
===================================================================
--- lto-cgraph.c	(revision 202445)
+++ lto-cgraph.c	(working copy)
@@ -49,6 +49,7 @@  along with GCC; see the file COPYING3.
 #include "profile.h"
 #include "context.h"
 #include "pass_manager.h"
+#include "ipa-utils.h"
 
 static void output_cgraph_opt_summary (void);
 static void input_cgraph_opt_summary (vec<symtab_node>  nodes);
@@ -766,6 +767,7 @@  compute_ltrans_boundary (lto_symtab_enco
   int i;
   lto_symtab_encoder_t encoder;
   lto_symtab_encoder_iterator lsei;
+  struct pointer_set_t *reachable_call_targets = pointer_set_create ();
 
   encoder = lto_symtab_encoder_new (false);
 
@@ -837,9 +839,40 @@  compute_ltrans_boundary (lto_symtab_enco
 	      add_node_to (encoder, callee, false);
 	    }
 	}
+      /* Add all possible targets for late devirtualization.  */
+      if (flag_devirtualize)
+	for (edge = node->indirect_calls; edge; edge = edge->next_callee)
+	  if (edge->indirect_info->polymorphic)
+	    {
+	      unsigned int i;
+	      void *cache_token;
+	      bool final;
+	      vec <cgraph_node *>targets
+		= possible_polymorphic_call_targets
+		    (edge, &final, &cache_token);
+	      if (!pointer_set_insert (reachable_call_targets,
+				       cache_token))
+		{
+		  for (i = 0; i < targets.length(); i++)
+		    {
+		      struct cgraph_node *callee = targets[i];
+
+		      /* Adding an external declarations into the unit serves
+			 no purpose and just increases its boundary.  */
+		      if (callee->symbol.definition
+			  && !lto_symtab_encoder_in_partition_p
+			       (encoder, (symtab_node)callee))
+			{
+			  gcc_assert (!callee->global.inlined_to);
+			  add_node_to (encoder, callee, false);
+			}
+		    }
+		}
+	    }
     }
- lto_symtab_encoder_delete (in_encoder);
- return encoder;
+  lto_symtab_encoder_delete (in_encoder);
+  pointer_set_destroy (reachable_call_targets);
+  return encoder;
 }
 
 /* Output the part of the symtab in SET and VSET.  */