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;

Reply via email to