> > I am playing with doing some internal interface static analysis > using the first patch below (and looking at LTO bootstrap results). > > An example, obvious patch resulting from that is the 2nd patch, > resuling from the static analysis output > > /space/rguenther/src/svn/trunk/gcc/tree-ssa-pre.c:add_to_value can be made > static > /space/rguenther/src/svn/trunk/gcc/tree-ssa-pre.c:print_value_expressions > can be made static > > the static analysis is very verbose (and does not consider ipa-refs yet). > You also need to union results for building all frontends and all > targets (well, in theory, or you can simply manually verify things > which is a good idea anyway - even unused functions may be useful > exported when they implement a generic data structure for example). > > Excercise for the reader: turn the analysis into a plugin. > > Richard. > > > Index: gcc/lto/lto.c > =================================================================== > --- gcc/lto/lto.c (revision 185918) > +++ gcc/lto/lto.c (working copy) > @@ -2721,6 +2721,65 @@ 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) > + || resolution_used_from_other_file_p (node->resolution)) > + 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))); > + }
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? :) Honza