OSDN Git Service

* cgraph.h (cgraph_node, cgraph_varpool_node): Update docmentation of
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 Jul 2010 18:25:04 +0000 (18:25 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 Jul 2010 18:25:04 +0000 (18:25 +0000)
in_other_partition.
* lto-cgraph.c (referenced_from_other_partition_p,
reachable_from_other_partition_p): Use in_other_partition flags.
(output_node, output_varpool_node): COMDAT nodes always have private
copies and thus are never used from other partition.

* lto.c (add_cgraph_node_to_partition): Forward declare; walk also
nodes from same comdat group as well as all comdat functions referenced
here.
(add_varpool_node_to_partition, add_references_to_partition): New function.
(lto_1_1_map): Skip COMDAT fnctions/variables; use add_varpool_node_to_partition;
clear aux flags when done.
(lto_promote_cross_file_statics): Do not promote stuff that gets duplicated to
each ltrans.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161846 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cgraph.h
gcc/lto-cgraph.c
gcc/lto/ChangeLog
gcc/lto/lto.c

index d96152e..75b5645 100644 (file)
@@ -1,3 +1,12 @@
+2010-07-05  Jan Hubicka  <jh@suse.cz>
+
+       * cgraph.h (cgraph_node, cgraph_varpool_node): Update docmentation of
+       in_other_partition.
+       * lto-cgraph.c (referenced_from_other_partition_p,
+       reachable_from_other_partition_p): Use in_other_partition flags.
+       (output_node, output_varpool_node): COMDAT nodes always have private
+       copies and thus are never used from other partition.
+
 2010-07-05  Anatoly Sokolov  <aesok@post.ru>
 
        * config/ia64/ia64.h (MEMORY_MOVE_COST): Remove macro.
index ef556b9..bbce3d8 100644 (file)
@@ -286,7 +286,9 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node {
   /* Set once the function has been instantiated and its callee
      lists created.  */
   unsigned analyzed : 1;
-  /* Set when function is available in the other LTRANS partition.  */
+  /* Set when function is available in the other LTRANS partition.  
+     During WPA output it is used to mark nodes that are present in
+     multiple partitions.  */
   unsigned in_other_partition : 1;
   /* Set when function is scheduled to be processed by local passes.  */
   unsigned process : 1;
@@ -497,7 +499,9 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) varpool_node {
   unsigned alias : 1;
   /* Set when variable is used from other LTRANS partition.  */
   unsigned used_from_other_partition : 1;
-  /* Set when variable is available in the other LTRANS partition.  */
+  /* Set when variable is available in the other LTRANS partition.
+     During WPA output it is used to mark nodes that are present in
+     multiple partitions.  */
   unsigned in_other_partition : 1;
 };
 
@@ -556,6 +560,7 @@ struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
 struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple, int,
                                                 gcov_type, int, int);
 struct cgraph_node * cgraph_get_node (tree);
+struct cgraph_node * cgraph_get_node_or_alias (tree);
 struct cgraph_node *cgraph_node (tree);
 bool cgraph_same_body_alias (tree, tree);
 void cgraph_add_thunk (tree, tree, bool, HOST_WIDE_INT, HOST_WIDE_INT, tree, tree);
index 1542797..4217a71 100644 (file)
@@ -319,13 +319,15 @@ referenced_from_other_partition_p (struct ipa_ref_list *list, cgraph_node_set se
     {
       if (ref->refering_type == IPA_REF_CGRAPH)
        {
-         if (!cgraph_node_in_set_p (ipa_ref_refering_node (ref), set))
+         if (ipa_ref_refering_node (ref)->in_other_partition
+             || !cgraph_node_in_set_p (ipa_ref_refering_node (ref), set))
            return true;
        }
       else
        {
-         if (!varpool_node_in_set_p (ipa_ref_refering_varpool_node (ref),
-                                     vset))
+         if (ipa_ref_refering_varpool_node (ref)->in_other_partition
+             || !varpool_node_in_set_p (ipa_ref_refering_varpool_node (ref),
+                                        vset))
            return true;
        }
     }
@@ -343,7 +345,8 @@ reachable_from_other_partition_p (struct cgraph_node *node, cgraph_node_set set)
   if (node->global.inlined_to)
     return false;
   for (e = node->callers; e; e = e->next_caller)
-    if (!cgraph_node_in_set_p (e->caller, set))
+    if (e->caller->in_other_partition
+       || !cgraph_node_in_set_p (e->caller, set))
       return true;
   return false;
 }
@@ -503,6 +506,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
   bp_pack_value (&bp, node->abstract_and_needed, 1);
   bp_pack_value (&bp, tag == LTO_cgraph_analyzed_node
                 && !DECL_EXTERNAL (node->decl)
+                && !DECL_COMDAT (node->decl)
                 && (reachable_from_other_partition_p (node, set)
                     || referenced_from_other_partition_p (&node->ref_list, set, vset)), 1);
   bp_pack_value (&bp, node->lowered, 1);
@@ -576,7 +580,8 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node
   /* Constant pool initializers can be de-unified into individual ltrans units.
      FIXME: Alternatively at -Os we may want to avoid generating for them the local
      labels and share them across LTRANS partitions.  */
-  if (DECL_IN_CONSTANT_POOL (node->decl))
+  if (DECL_IN_CONSTANT_POOL (node->decl)
+      && !DECL_COMDAT (node->decl))
     {
       bp_pack_value (&bp, 0, 1);  /* used_from_other_parition.  */
       bp_pack_value (&bp, 0, 1);  /* in_other_partition.  */
index 567cfcd..a1a03b6 100644 (file)
@@ -1,3 +1,14 @@
+2010-07-05  Jan Hubicka  <jh@suse.cz>
+
+       * lto.c (add_cgraph_node_to_partition): Forward declare; walk also
+       nodes from same comdat group as well as all comdat functions referenced
+       here.
+       (add_varpool_node_to_partition, add_references_to_partition): New function.
+       (lto_1_1_map): Skip COMDAT fnctions/variables; use add_varpool_node_to_partition;
+       clear aux flags when done.
+       (lto_promote_cross_file_statics): Do not promote stuff that gets duplicated to
+       each ltrans.
+
 2010-07-04  Jan Hubicka  <jh@suse.cz>
 
         * lto.c (read_cgraph_and_symbols): Dump cgraph before merging.
index 27d2600..4ac1ac1 100644 (file)
@@ -525,6 +525,9 @@ DEF_VEC_ALLOC_P(ltrans_partition,gc);
 
 static GTY (()) VEC(ltrans_partition, gc) *ltrans_partitions;
 
+static void add_cgraph_node_to_partition (ltrans_partition part, struct cgraph_node *node);
+static void add_varpool_node_to_partition (ltrans_partition part, struct varpool_node *vnode);
+
 /* Create new partition with name NAME.  */
 static ltrans_partition
 new_partition (const char *name)
@@ -538,17 +541,77 @@ new_partition (const char *name)
   return part;
 }
 
-/* Add NODE to partition as well as the inline callees into partition PART. */
+/* See all references that go to comdat objects and bring them into partition too.  */
+static void
+add_references_to_partition (ltrans_partition part, struct ipa_ref_list *refs)
+{
+  int i;
+  struct ipa_ref *ref;
+  for (i = 0; ipa_ref_list_reference_iterate (refs, i, ref); i++)
+    {
+      if (ref->refered_type == IPA_REF_CGRAPH
+         && DECL_COMDAT (ipa_ref_node (ref)->decl)
+         && !cgraph_node_in_set_p (ipa_ref_node (ref), part->cgraph_set))
+       add_cgraph_node_to_partition (part, ipa_ref_node (ref));
+      else
+       if (ref->refered_type == IPA_REF_VARPOOL
+           && DECL_COMDAT (ipa_ref_varpool_node (ref)->decl)
+           && !varpool_node_in_set_p (ipa_ref_varpool_node (ref), part->varpool_set))
+         add_varpool_node_to_partition (part, ipa_ref_varpool_node (ref));
+    }
+}
+
+/* Add NODE to partition as well as the inline callees and referred comdats into partition PART. */
 
 static void
 add_cgraph_node_to_partition (ltrans_partition part, struct cgraph_node *node)
 {
   struct cgraph_edge *e;
+
   part->insns += node->local.inline_summary.self_size;
+
+  if (node->aux)
+    {
+      gcc_assert (node->aux != part);
+      node->in_other_partition = 1;
+    }
+  else
+    node->aux = part;
+
   cgraph_node_set_add (part->cgraph_set, node);
+
   for (e = node->callees; e; e = e->next_callee)
-    if (!e->inline_failed)
+    if ((!e->inline_failed || DECL_COMDAT (e->callee->decl))
+       && !cgraph_node_in_set_p (e->callee, part->cgraph_set))
       add_cgraph_node_to_partition (part, e->callee);
+
+  add_references_to_partition (part, &node->ref_list);
+
+  if (node->same_comdat_group
+      && !cgraph_node_in_set_p (node->same_comdat_group, part->cgraph_set))
+    add_cgraph_node_to_partition (part, node->same_comdat_group);
+}
+
+/* Add VNODE to partition as well as comdat references partition PART. */
+
+static void
+add_varpool_node_to_partition (ltrans_partition part, struct varpool_node *vnode)
+{
+  varpool_node_set_add (part->varpool_set, vnode);
+
+  if (vnode->aux)
+    {
+      gcc_assert (vnode->aux != part);
+      vnode->in_other_partition = 1;
+    }
+  else
+    vnode->aux = part;
+
+  add_references_to_partition (part, &vnode->ref_list);
+
+  if (vnode->same_comdat_group
+      && !varpool_node_in_set_p (vnode->same_comdat_group, part->varpool_set))
+    add_varpool_node_to_partition (part, vnode->same_comdat_group);
 }
 
 /* Group cgrah nodes by input files.  This is used mainly for testing
@@ -577,6 +640,10 @@ lto_1_to_1_map (void)
       /* Nodes without a body do not need partitioning.  */
       if (!node->analyzed)
        continue;
+      /* Extern inlines and comdat are always only in partitions they are needed.  */
+      if (DECL_EXTERNAL (node->decl)
+         || DECL_COMDAT (node->decl))
+       continue;
 
       file_data = node->local.lto_file_data;
       gcc_assert (!node->same_body_alias && file_data);
@@ -599,6 +666,10 @@ lto_1_to_1_map (void)
     {
       if (vnode->alias || !vnode->needed)
        continue;
+      /* Constant pool and comdat are always only in partitions they are needed.  */
+      if (DECL_IN_CONSTANT_POOL (vnode->decl)
+         || DECL_COMDAT (vnode->decl))
+       continue;
       file_data = vnode->lto_file_data;
       slot = pointer_map_contains (pmap, file_data);
       if (slot)
@@ -611,8 +682,12 @@ lto_1_to_1_map (void)
          npartitions++;
        }
 
-      varpool_node_set_add (partition->varpool_set, vnode);
+      add_varpool_node_to_partition (partition, vnode);
     }
+  for (node = cgraph_nodes; node; node = node->next)
+    node->aux = NULL;
+  for (vnode = varpool_nodes; vnode; vnode = vnode->next)
+    vnode->aux = NULL;
 
   /* If the cgraph is empty, create one cgraph node set so that there is still
      an output file for any variables that need to be exported in a DSO.  */
@@ -704,7 +779,7 @@ lto_promote_cross_file_statics (void)
            continue;
          if (node->global.inlined_to)
            continue;
-         if (!DECL_EXTERNAL (node->decl)
+         if ((!DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl))
              && (referenced_from_other_partition_p (&node->ref_list, set, vset)
                  || reachable_from_other_partition_p (node, set)))
            promote_fn (node);
@@ -715,10 +790,10 @@ lto_promote_cross_file_statics (void)
          /* Constant pool references use internal labels and thus can not
             be made global.  It is sensible to keep those ltrans local to
             allow better optimization.  */
-         if (!DECL_IN_CONSTANT_POOL (vnode->decl)
-            && !vnode->externally_visible && vnode->analyzed
-            && referenced_from_other_partition_p (&vnode->ref_list,
-                                                  set, vset))
+         if (!DECL_IN_CONSTANT_POOL (vnode->decl) && !DECL_COMDAT (vnode->decl)
+             && !vnode->externally_visible && vnode->analyzed
+             && referenced_from_other_partition_p (&vnode->ref_list,
+                                                   set, vset))
            promote_var (vnode);
        }