On Fri, 30 Mar 2012, Richard Guenther wrote:

> On Thu, 29 Mar 2012, Jan Hubicka wrote:
> 
> > With Mozilla folks I used the dumps from first WPA unreachable function 
> > removal pass
> > with some degree of success.  This gets a lot of non-trivial cases of dead 
> > code,
> > but also there are a lot of funny false positives wrt comdats etc.
> > > +   for (caller = node->callers; caller; caller = caller->next_caller)
> > > +     {
> > > +       if (!caller_tu)
> > > +         caller_tu = DECL_CONTEXT (caller->caller->decl);
> > > +       else if (caller_tu
> > > +                && DECL_CONTEXT (caller->caller->decl) != caller_tu)
> > > +         found = false;
> > > +     }
> > Extending to IPA-REF should be straighforward.
> > > +   if (found && caller_tu)
> > > +     {
> > > +       expanded_location loc1 = expand_location (DECL_SOURCE_LOCATION 
> > > (node->decl));
> > > +       expanded_location loc2 = expand_location (DECL_SOURCE_LOCATION 
> > > (node->callers->caller->decl));
> > > +
> > > +       if (DECL_CONTEXT (node->decl) == caller_tu)
> > > +         fprintf (f, "%s:%s can be made static\n",
> > > +                  loc1.file, IDENTIFIER_POINTER (DECL_NAME 
> > > (node->decl)));
> > Indeed, this is also useful. Any plans to turn this into general 
> > -W<something>,
> > or you will also stay just with an internal hack like I did? :)
> 
> ;)  The result has way too many false positives (LTO bootstrap produces
> quite some dead functions due to early inlining).  So yes, this will
> stay internal ;)

Btw, the following is the last incarnation of the patch - I've stopped
here for now.  If you LTO bootstrap with it you can find *.callers
files in the build tree (remember to use -O0 for added precision).

Richard.

Index: gcc/lto/lto.c
===================================================================
--- gcc/lto/lto.c       (revision 186007)
+++ gcc/lto/lto.c       (working copy)
@@ -2721,6 +2721,70 @@ read_cgraph_and_symbols (unsigned nfiles
   lto_symtab_merge_cgraph_nodes ();
   ggc_collect ();
 
+  if (flag_wpa)
+    {
+      struct cgraph_node *node;
+      FILE *f = fopen (concat (dump_base_name, ".callers", NULL), "w");
+      for (node = cgraph_nodes; node; node = node->next)
+       {
+         tree caller_tu = NULL_TREE;
+         struct cgraph_edge *caller;
+         bool found = true;
+
+         if (!TREE_PUBLIC (node->decl)
+             || !TREE_STATIC (node->decl)
+             || DECL_PRESERVE_P (node->decl)
+             || resolution_used_from_other_file_p (node->resolution))
+           continue;
+
+         /* For now, until we walk references.  */
+         if (node->address_taken)
+           continue;
+
+         if (!node->callers)
+           {
+             expanded_location loc = expand_location (DECL_SOURCE_LOCATION 
(node->decl));
+             fprintf (f, "%s:%s no calls\n",
+                      loc.file, IDENTIFIER_POINTER (DECL_NAME (node->decl)));
+           }
+         for (caller = node->callers; caller; caller = caller->next_caller)
+           {
+             if (!caller_tu)
+               caller_tu = DECL_CONTEXT (caller->caller->decl);
+             else if (caller_tu
+                      && DECL_CONTEXT (caller->caller->decl) != caller_tu)
+               found = false;
+           }
+         if (found && caller_tu)
+           {
+             expanded_location loc1 = expand_location (DECL_SOURCE_LOCATION 
(node->decl));
+             expanded_location loc2 = expand_location (DECL_SOURCE_LOCATION 
(node->callers->caller->decl));
+
+             if (DECL_CONTEXT (node->decl) == caller_tu)
+               fprintf (f, "%s:%s can be made static\n",
+                        loc1.file, IDENTIFIER_POINTER (DECL_NAME 
(node->decl)));
+             else
+               {
+                 struct cgraph_edge *callee;
+                 bool calls_nonpublic_static_fn = false;
+                 /* Check if we can move node to the caller TU without
+                    moving anything else.  */
+                 for (callee = node->callees; callee; callee = 
callee->next_callee)
+                   {
+                     if (!TREE_PUBLIC (callee->callee->decl)
+                         && TREE_STATIC (callee->callee->decl))
+                       calls_nonpublic_static_fn = true;
+                   }
+                 if (!calls_nonpublic_static_fn)
+                   fprintf (f, "%s:%s called only from %s\n",
+                            loc1.file, IDENTIFIER_POINTER (DECL_NAME 
(node->decl)),
+                            loc2.file);
+               }
+           }
+       }
+      fclose (f);
+    }
+
   if (flag_ltrans)
     for (node = cgraph_nodes; node; node = node->next)
       {

Reply via email to