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.
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.  */

Reply via email to