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))); + } + 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) { 2012-03-29 Richard Guenther <rguent...@suse.de> * tree-flow.h (struct pre_expr_d): Remove forward declaration. (add_to_value): Remove. (print_value_expressions): Likewise. * tree-ssa-pre.c (add_to_value): Make static. (print_value_expressions): Likewise. Index: gcc/tree-flow.h =================================================================== *** gcc/tree-flow.h (revision 185918) --- gcc/tree-flow.h (working copy) *************** extern bool verify_eh_dispatch_edge (gim *** 794,803 **** extern void maybe_remove_unreachable_handlers (void); /* In tree-ssa-pre.c */ - struct pre_expr_d; - void add_to_value (unsigned int, struct pre_expr_d *); void debug_value_expressions (unsigned int); - void print_value_expressions (FILE *, unsigned int); /* In tree-ssa-sink.c */ bool is_hidden_global_store (gimple); --- 794,800 ---- Index: gcc/tree-ssa-pre.c =================================================================== *** gcc/tree-ssa-pre.c (revision 185918) --- gcc/tree-ssa-pre.c (working copy) *************** phi_trans_add (pre_expr e, pre_expr v, b *** 587,593 **** /* Add expression E to the expression set of value id V. */ ! void add_to_value (unsigned int v, pre_expr e) { bitmap_set_t set; --- 587,593 ---- /* Add expression E to the expression set of value id V. */ ! static void add_to_value (unsigned int v, pre_expr e) { bitmap_set_t set; *************** debug_bitmap_set (bitmap_set_t set) *** 1031,1037 **** /* Print out the expressions that have VAL to OUTFILE. */ ! void print_value_expressions (FILE *outfile, unsigned int val) { bitmap_set_t set = VEC_index (bitmap_set_t, value_expressions, val); --- 1031,1037 ---- /* Print out the expressions that have VAL to OUTFILE. */ ! static void print_value_expressions (FILE *outfile, unsigned int val) { bitmap_set_t set = VEC_index (bitmap_set_t, value_expressions, val);