Hi, when I was upding ipa-reference.c to LTO I took the easiest possible approach keeping it to work only on statics without address taken at compile time and propagate at linktime. The idea was that soonish we will replace it by something more sane.
Well, this did not happen yet and this hack needed update with my symtab work so I decided to go ahead and make ipa-reference to analyze all variables and at execution time prune out non-statics and vars with address taken. This makes it stronger especially with LTO, but also without WRT cases where we optimize out the ADDR_EXPR operaitons. Not that this would be too important optimizaiton, but it is easy to do. Bootstrapped/regtested x86_64 and tested with Mozilla, comitted. Honza * ipa-reference.c (is_proper_for_analysis): Do not check flags that might change as result of global optimization. (analyze_function): Do not check analyzed and externally_visible flags; be happy about address dereferences. (propagate): Prune all_module_statics so it really contains just statics; prune all the local summaries. (ipa_reference_write_optimization_summary): Simplify. Index: ipa-reference.c =================================================================== --- ipa-reference.c (revision 187412) +++ ipa-reference.c (working copy) @@ -247,10 +247,6 @@ add_static_var (tree var) static inline bool is_proper_for_analysis (tree t) { - /* We handle only variables whose address is never taken. */ - if (TREE_ADDRESSABLE (t)) - return false; - /* If the variable has the "used" attribute, treat it as if it had a been touched by the devil. */ if (DECL_PRESERVE_P (t)) @@ -266,10 +262,6 @@ is_proper_for_analysis (tree t) if (TREE_READONLY (t)) return false; - /* We cannot touch decls where the type needs constructing. */ - if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t))) - return false; - /* This is a variable we care about. Check if we have seen it before, and if not add it the set of variables we care about. */ if (all_module_statics @@ -438,9 +430,7 @@ analyze_function (struct cgraph_node *fn if (!symtab_variable_p (ref->referred)) continue; var = ipa_ref_varpool_node (ref)->symbol.decl; - if (ipa_ref_varpool_node (ref)->symbol.externally_visible - || !ipa_ref_varpool_node (ref)->analyzed - || !is_proper_for_analysis (var)) + if (!is_proper_for_analysis (var)) continue; switch (ref->use) { @@ -453,7 +443,6 @@ analyze_function (struct cgraph_node *fn bitmap_set_bit (local->statics_written, DECL_UID (var)); break; case IPA_REF_ADDR: - gcc_unreachable (); break; } } @@ -613,6 +602,7 @@ static unsigned int propagate (void) { struct cgraph_node *node; + struct varpool_node *vnode; struct cgraph_node *w; struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); @@ -625,6 +615,28 @@ propagate (void) ipa_discover_readonly_nonaddressable_vars (); generate_summary (); + /* Now we know what vars are realy statics; prune out those that aren't. */ + FOR_EACH_VARIABLE (vnode) + if (vnode->symbol.externally_visible + || TREE_ADDRESSABLE (vnode->symbol.decl) + || TREE_READONLY (vnode->symbol.decl) + || !is_proper_for_analysis (vnode->symbol.decl) + || !vnode->analyzed) + bitmap_clear_bit (all_module_statics, DECL_UID (vnode->symbol.decl)); + + /* Forget info we collected "just for fun" on variables that turned out to be + non-local. */ + FOR_EACH_DEFINED_FUNCTION (node) + { + ipa_reference_local_vars_info_t node_l; + + node_l = &get_reference_vars_info (node)->local; + if (node_l->statics_read != all_module_statics) + bitmap_and_into (node_l->statics_read, all_module_statics); + if (node_l->statics_written != all_module_statics) + bitmap_and_into (node_l->statics_written, all_module_statics); + } + /* Propagate the local information thru the call graph to produce the global information. All the nodes within a cycle will have the same info so we collapse cycles first. Then we can do the @@ -1034,9 +1046,7 @@ ipa_reference_write_optimization_summary for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++) { struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i); - if (!vnode->symbol.externally_visible - && vnode->analyzed - && bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl)) + if (bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl)) && referenced_from_this_partition_p (&vnode->symbol.ref_list, set, vset)) { tree decl = vnode->symbol.decl;