diff mbox

[1/n] Cleanup internal interfaces, GCC modularization

Message ID Pine.LNX.4.64.1203301416300.25270@jbgna.fhfr.qr
State New
Headers show

Commit Message

Richard Biener March 30, 2012, 12:17 p.m. UTC
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.
diff mbox

Patch

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)
       {