OSDN Git Service

* lto-cgraph.c (output_varpool): Forward declare; work on encoder.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 May 2010 10:21:42 +0000 (10:21 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 May 2010 10:21:42 +0000 (10:21 +0000)
(lto_varpool_encoder_new, lto_varpool_encoder_delete, lto_varpool_encoder_encode
lto_varpool_encoder_lookup, lto_varpool_encoder_deref, lto_varpool_encoder_size,
lto_varpool_encoder_encode_initializer_p,
lto_set_varpool_encoder_encode_initializer): New functions.
(lto_output_cgraph): Take vset parameter too; compute varpool encoder;
call output_varpool.
(input_varpool_node): Do not always set analyzed.
(input_cgraph_1): Return vector of cgraph nodes.
(input_varpool_1): Return vector of varpools.
(input_cgraph): Free the vectors.
* lto-streamer-out.c (lto_output_ts_decl_common_tree_pointers):
output only initializers needed.
(lto_output): Only call output_cgraph.
(produce_asm_for_decls): Call lto_varpool_encoder_delete.
* lto-section-out.c (lto_new_out_decl_state): Initialize
state->varpool_node_encoder.
* lto-streamer.h (lto_varpool_encoder_d): New.
(lto_out_decl_state, lto_file_decl_data): Add varpool_node_encoder.
(lto_cgraph_encoder_delete, output_cgraph): Update prototype.
(lto_varpool_encoder_deref, lto_varpool_encoder_lookup,
lto_varpool_encoder_encode, lto_varpool_encoder_delete,
lto_varpool_encoder_encode_initializer_p, lto_varpool_encoder_new):
Declare.
(output_varpool, input_varpool): Remove declarations.

* lto.c (lto_1_to_1_map): Partition only needed nodes.

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

gcc/ChangeLog
gcc/ipa-ref-inline.h [new file with mode: 0644]
gcc/ipa-ref.c [new file with mode: 0644]
gcc/ipa-ref.h [new file with mode: 0644]
gcc/lto-cgraph.c
gcc/lto-section-out.c
gcc/lto-streamer-out.c
gcc/lto-streamer.h
gcc/lto/ChangeLog
gcc/lto/lto.c

index 7f2f32a..3d751d2 100644 (file)
@@ -1,5 +1,33 @@
 2010-05-05  Jan Hubicka  <jh@suse.cz>
 
+       * lto-cgraph.c (output_varpool): Forward declare; work on encoder.
+       (lto_varpool_encoder_new, lto_varpool_encoder_delete, lto_varpool_encoder_encode
+       lto_varpool_encoder_lookup, lto_varpool_encoder_deref, lto_varpool_encoder_size,
+       lto_varpool_encoder_encode_initializer_p,
+       lto_set_varpool_encoder_encode_initializer): New functions.
+       (lto_output_cgraph): Take vset parameter too; compute varpool encoder;
+       call output_varpool.
+       (input_varpool_node): Do not always set analyzed.
+       (input_cgraph_1): Return vector of cgraph nodes.
+       (input_varpool_1): Return vector of varpools.
+       (input_cgraph): Free the vectors.
+       * lto-streamer-out.c (lto_output_ts_decl_common_tree_pointers):
+       output only initializers needed.
+       (lto_output): Only call output_cgraph.
+       (produce_asm_for_decls): Call lto_varpool_encoder_delete.
+       * lto-section-out.c (lto_new_out_decl_state): Initialize
+       state->varpool_node_encoder.
+       * lto-streamer.h (lto_varpool_encoder_d): New.
+       (lto_out_decl_state, lto_file_decl_data): Add varpool_node_encoder.     
+       (lto_cgraph_encoder_delete, output_cgraph): Update prototype.
+       (lto_varpool_encoder_deref, lto_varpool_encoder_lookup,
+       lto_varpool_encoder_encode, lto_varpool_encoder_delete,
+       lto_varpool_encoder_encode_initializer_p, lto_varpool_encoder_new):
+       Declare.
+       (output_varpool, input_varpool): Remove declarations.
+
+2010-05-05  Jan Hubicka  <jh@suse.cz>
+
        * lto-symtab.c (lto_symtab_resolve_can_prevail_p): Alias of variable
        with body can prevail.
 
diff --git a/gcc/ipa-ref-inline.h b/gcc/ipa-ref-inline.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gcc/ipa-ref.c b/gcc/ipa-ref.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gcc/ipa-ref.h b/gcc/ipa-ref.h
new file mode 100644 (file)
index 0000000..e69de29
index 3f7a22b..2c67fcb 100644 (file)
@@ -46,6 +46,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "lto-streamer.h"
 #include "gcov-io.h"
 
+static void output_varpool (varpool_node_set);
+
 /* Cgraph streaming is organized as set of record whose type
    is indicated by a tag.  */
 enum LTO_cgraph_tags
@@ -143,6 +145,105 @@ lto_cgraph_encoder_size (lto_cgraph_encoder_t encoder)
   return VEC_length (cgraph_node_ptr, encoder->nodes);
 }
 
+/* Create a new varpool encoder.  */
+
+lto_varpool_encoder_t
+lto_varpool_encoder_new (void)
+{
+  lto_varpool_encoder_t encoder = XCNEW (struct lto_varpool_encoder_d);
+  encoder->map = pointer_map_create ();
+  encoder->initializer = pointer_set_create ();
+  encoder->nodes = NULL;
+  return encoder;
+}
+
+
+/* Delete ENCODER and its components.  */
+
+void
+lto_varpool_encoder_delete (lto_varpool_encoder_t encoder)
+{
+   VEC_free (varpool_node_ptr, heap, encoder->nodes);
+   pointer_map_destroy (encoder->map);
+   pointer_set_destroy (encoder->initializer);
+   free (encoder);
+}
+
+
+/* Return the existing reference number of NODE in the varpool encoder in
+   output block OB.  Assign a new reference if this is the first time
+   NODE is encoded.  */
+
+int
+lto_varpool_encoder_encode (lto_varpool_encoder_t encoder,
+                          struct varpool_node *node)
+{
+  int ref;
+  void **slot;
+
+  slot = pointer_map_contains (encoder->map, node);
+  if (!slot)
+    {
+      ref = VEC_length (varpool_node_ptr, encoder->nodes);
+      slot = pointer_map_insert (encoder->map, node);
+      *slot = (void *) (intptr_t) ref;
+      VEC_safe_push (varpool_node_ptr, heap, encoder->nodes, node);
+    }
+  else
+    ref = (int) (intptr_t) *slot;
+
+  return ref;
+}
+
+/* Look up NODE in encoder.  Return NODE's reference if it has been encoded
+   or LCC_NOT_FOUND if it is not there.  */
+
+int
+lto_varpool_encoder_lookup (lto_varpool_encoder_t encoder,
+                          struct varpool_node *node)
+{
+  void **slot = pointer_map_contains (encoder->map, node);
+  return (slot ? (int) (intptr_t) *slot : LCC_NOT_FOUND);
+}
+
+
+/* Return the varpool node corresponding to REF using ENCODER.  */
+
+struct varpool_node *
+lto_varpool_encoder_deref (lto_varpool_encoder_t encoder, int ref)
+{
+  if (ref == LCC_NOT_FOUND)
+    return NULL;
+
+  return VEC_index (varpool_node_ptr, encoder->nodes, ref);
+}
+
+
+/* Return number of encoded nodes in ENCODER.  */
+
+static int
+lto_varpool_encoder_size (lto_varpool_encoder_t encoder)
+{
+  return VEC_length (varpool_node_ptr, encoder->nodes);
+}
+
+/* Return TRUE if we should encode initializer of NODE (if any).  */
+
+bool
+lto_varpool_encoder_encode_initializer_p (lto_varpool_encoder_t encoder,
+                                         struct varpool_node *node)
+{
+  return pointer_set_contains (encoder->initializer, node);
+}
+
+/* Return TRUE if we should encode initializer of NODE (if any).  */
+
+static void
+lto_set_varpool_encoder_encode_initializer (lto_varpool_encoder_t encoder,
+                                           struct varpool_node *node)
+{
+  pointer_set_insert (encoder->initializer, node);
+}
 
 /* Output the cgraph EDGE to OB using ENCODER.  */
 
@@ -454,16 +555,19 @@ output_outgoing_cgraph_edges (struct cgraph_edge *edge,
 /* Output the part of the cgraph in SET.  */
 
 void
-output_cgraph (cgraph_node_set set)
+output_cgraph (cgraph_node_set set, varpool_node_set vset)
 {
   struct cgraph_node *node;
   struct lto_simple_output_block *ob;
   cgraph_node_set_iterator csi;
+  varpool_node_set_iterator vsi;
   struct cgraph_edge *edge;
   int i, n_nodes;
   bitmap written_decls;
   lto_cgraph_encoder_t encoder;
+  lto_varpool_encoder_t varpool_encoder;
   struct cgraph_asm_node *can;
+  struct varpool_node *vnode;
 
   ob = lto_create_simple_output_block (LTO_section_cgraph);
 
@@ -472,7 +576,9 @@ output_cgraph (cgraph_node_set set)
   /* An encoder for cgraph nodes should have been created by
      ipa_write_summaries_1.  */
   gcc_assert (ob->decl_state->cgraph_node_encoder);
+  gcc_assert (ob->decl_state->varpool_node_encoder);
   encoder = ob->decl_state->cgraph_node_encoder;
+  varpool_encoder = ob->decl_state->varpool_node_encoder;
 
   /* The FUNCTION_DECLs for which we have written a node.  The first
      node found is written as the "original" node, the remaining nodes
@@ -485,6 +591,33 @@ output_cgraph (cgraph_node_set set)
       node = csi_node (csi);
       add_node_to (encoder, node);
     }
+  for (vsi = vsi_start (vset); !vsi_end_p (vsi); vsi_next (&vsi))
+    {
+      struct varpool_node *vnode = vsi_node (vsi);
+      gcc_assert (!vnode->alias);
+      lto_varpool_encoder_encode (varpool_encoder, vnode);
+      lto_set_varpool_encoder_encode_initializer (varpool_encoder, vnode);
+    }
+  /* FIXME: We do not track references, so for now we need to include all possibly
+     used variables in the encoder set.  */
+  for (vnode = varpool_nodes; vnode; vnode = vnode->next)
+    if (vnode->needed)
+      lto_varpool_encoder_encode (varpool_encoder, vnode);
+  /* Pickle in also the initializer of all referenced readonly variables
+     to help folding.  Constant pool variables are not shared, so we must
+     pickle those too.  */
+  for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
+    {
+      struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i);
+      if (DECL_INITIAL (vnode->decl)
+         && !lto_varpool_encoder_encode_initializer_p (varpool_encoder,
+                                                       vnode)
+         && (DECL_IN_CONSTANT_POOL (vnode->decl)
+             ||  TREE_READONLY (vnode->decl)))
+       {
+         lto_set_varpool_encoder_encode_initializer (varpool_encoder, vnode);
+       }
+    }
 
   /* Go over all the nodes again to include callees that are not in
      SET.  */
@@ -538,6 +671,7 @@ output_cgraph (cgraph_node_set set)
   lto_output_uleb128_stream (ob->main_stream, 0);
 
   lto_destroy_simple_output_block (ob);
+  output_varpool (vset);
 }
 
 /* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS,
@@ -591,27 +725,23 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
 
 /* Output the part of the cgraph in SET.  */
 
-void
-output_varpool (varpool_node_set set)
+static void
+output_varpool (varpool_node_set vset)
 {
-  struct varpool_node *node;
-  struct lto_simple_output_block *ob;
-  int len = 0;
-
-  ob = lto_create_simple_output_block (LTO_section_varpool);
-
-  for (node = varpool_nodes; node; node = node->next)
-    if (node->needed && node->analyzed)
-      len++;
+  struct lto_simple_output_block *ob = lto_create_simple_output_block (LTO_section_varpool);
+  lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
+  int len = lto_varpool_encoder_size (varpool_encoder), i;
 
   lto_output_uleb128_stream (ob->main_stream, len);
 
   /* Write out the nodes.  We must first output a node and then its clones,
      otherwise at a time reading back the node there would be nothing to clone
      from.  */
-  for (node = varpool_nodes; node; node = node->next)
-    if (node->needed && node->analyzed)
-      lto_output_varpool_node (ob, node, set);
+  for (i = 0; i < len; i++)
+    {
+      lto_output_varpool_node (ob, lto_varpool_encoder_deref (varpool_encoder, i),
+                              vset);
+    }
 
   lto_destroy_simple_output_block (ob);
 }
@@ -737,7 +867,7 @@ input_varpool_node (struct lto_file_decl_data *file_data,
   node->externally_visible = bp_unpack_value (bp, 1);
   node->force_output = bp_unpack_value (bp, 1);
   node->finalized = bp_unpack_value (bp, 1);
-  node->analyzed = 1
+  node->analyzed = node->finalized
   node->used_from_other_partition = bp_unpack_value (bp, 1);
   node->in_other_partition = bp_unpack_value (bp, 1);
   aliases_p = bp_unpack_value (bp, 1);
@@ -822,7 +952,7 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes,
 
 /* Read a cgraph from IB using the info in FILE_DATA.  */
 
-static void
+static VEC(cgraph_node_ptr, heap) *
 input_cgraph_1 (struct lto_file_decl_data *file_data,
                struct lto_input_block *ib)
 {
@@ -882,26 +1012,29 @@ input_cgraph_1 (struct lto_file_decl_data *file_data,
       else
        node->same_comdat_group = NULL;
     }
-
-  VEC_free (cgraph_node_ptr, heap, nodes);
+  return nodes;
 }
 
 /* Read a varpool from IB using the info in FILE_DATA.  */
 
-static void
+static VEC(varpool_node_ptr, heap) *
 input_varpool_1 (struct lto_file_decl_data *file_data,
                struct lto_input_block *ib)
 {
   unsigned HOST_WIDE_INT len;
+  VEC(varpool_node_ptr, heap) *varpool = NULL;
 
   len = lto_input_uleb128 (ib);
   while (len)
     {
-      input_varpool_node (file_data, ib);
+      VEC_safe_push (varpool_node_ptr, heap, varpool,
+                    input_varpool_node (file_data, ib));
       len--;
     }
+  return varpool;
 }
 
+
 static struct gcov_ctr_summary lto_gcov_summary;
 
 /* Input profile_info from IB.  */
@@ -948,20 +1081,25 @@ input_cgraph (void)
       const char *data;
       size_t len;
       struct lto_input_block *ib;
+      VEC(cgraph_node_ptr, heap) *nodes;
+      VEC(varpool_node_ptr, heap) *varpool;
 
       ib = lto_create_simple_input_block (file_data, LTO_section_cgraph,
                                          &data, &len);
       input_profile_summary (ib);
       file_data->cgraph_node_encoder = lto_cgraph_encoder_new ();
-      input_cgraph_1 (file_data, ib);
+      nodes = input_cgraph_1 (file_data, ib);
       lto_destroy_simple_input_block (file_data, LTO_section_cgraph,
                                      ib, data, len);
 
       ib = lto_create_simple_input_block (file_data, LTO_section_varpool,
                                          &data, &len);
-      input_varpool_1 (file_data, ib);
+      varpool = input_varpool_1 (file_data, ib);
       lto_destroy_simple_input_block (file_data, LTO_section_varpool,
                                      ib, data, len);
+
+      VEC_free (cgraph_node_ptr, heap, nodes);
+      VEC_free (varpool_node_ptr, heap, varpool);
     }
 
   /* Clear out the aux field that was used to store enough state to
index 09ecc07..8bcbdd7 100644 (file)
@@ -543,6 +543,7 @@ lto_new_out_decl_state (void)
     }
 
   state->cgraph_node_encoder = lto_cgraph_encoder_new ();
+  state->varpool_node_encoder = lto_varpool_encoder_new ();
 
   return state;
 }
index 77d98aa..cffaee5 100644 (file)
@@ -844,7 +844,23 @@ lto_output_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
   lto_output_tree_or_ref (ob, DECL_SIZE_UNIT (expr), ref_p);
 
   if (TREE_CODE (expr) != FUNCTION_DECL)
-    lto_output_tree_or_ref (ob, DECL_INITIAL (expr), ref_p);
+    {
+      tree initial = DECL_INITIAL (expr);
+      if (TREE_CODE (expr) == VAR_DECL
+         && (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
+         && initial)
+       {
+         lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
+         struct varpool_node *vnode = varpool_get_node (expr);
+         if (!vnode)
+           initial = error_mark_node;
+         else if (!lto_varpool_encoder_encode_initializer_p (varpool_encoder,
+                                                             vnode))
+           initial = NULL;
+       }
+    
+      lto_output_tree_or_ref (ob, initial, ref_p);
+    }
 
   lto_output_tree_or_ref (ob, DECL_ATTRIBUTES (expr), ref_p);
   lto_output_tree_or_ref (ob, DECL_ABSTRACT_ORIGIN (expr), ref_p);
@@ -2102,8 +2118,7 @@ lto_output (cgraph_node_set set, varpool_node_set vset)
      be done now to make sure that all the statements in every function
      have been renumbered so that edges can be associated with call
      statements using the statement UIDs.  */
-  output_cgraph (set);
-  output_varpool (vset);
+  output_cgraph (set, vset);
 
   lto_bitmap_free (output);
 }
@@ -2507,6 +2522,7 @@ produce_asm_for_decls (cgraph_node_set set, varpool_node_set vset)
 
   /* Deallocate memory and clean up.  */
   lto_cgraph_encoder_delete (ob->decl_state->cgraph_node_encoder);
+  lto_varpool_encoder_delete (ob->decl_state->varpool_node_encoder);
   VEC_free (lto_out_decl_state_ptr, heap, lto_function_decl_states);
   lto_function_decl_states = NULL;
   destroy_output_block (ob);
index cc1922a..3d8617b 100644 (file)
@@ -466,6 +466,20 @@ struct lto_cgraph_encoder_d
 
 typedef struct lto_cgraph_encoder_d *lto_cgraph_encoder_t;
 
+/* Encoder data structure used to stream callgraph nodes.  */
+struct lto_varpool_encoder_d
+{
+  /* Map nodes to reference number. */
+  struct pointer_map_t *map;
+
+  /* Map reference number to node. */
+  VEC(varpool_node_ptr,heap) *nodes;
+
+  /* Map of nodes where we want to output initializer.  */
+  struct pointer_set_t *initializer;
+};
+typedef struct lto_varpool_encoder_d *lto_varpool_encoder_t;
+
 /* Mapping from indices to trees.  */
 struct GTY(()) lto_tree_ref_table
 {
@@ -520,6 +534,9 @@ struct lto_out_decl_state
   /* Encoder for cgraph nodes.  */
   lto_cgraph_encoder_t cgraph_node_encoder;
 
+  /* Encoder for varpool nodes.  */
+  lto_varpool_encoder_t varpool_node_encoder;
+
   /* If this out-decl state belongs to a function, fn_decl points to that
      function.  Otherwise, it is NULL. */
   tree fn_decl;
@@ -546,6 +563,9 @@ struct GTY(()) lto_file_decl_data
   /* Table of cgraph nodes present in this file.  */
   lto_cgraph_encoder_t GTY((skip)) cgraph_node_encoder;
 
+  /* Table of varpool nodes present in this file.  */
+  lto_varpool_encoder_t GTY((skip)) varpool_node_encoder;
+
   /* Hash table maps lto-related section names to location in file.  */
   htab_t GTY((param_is (struct lto_in_decl_state))) function_decl_states;
 
@@ -825,11 +845,16 @@ struct cgraph_node *lto_cgraph_encoder_deref (lto_cgraph_encoder_t, int);
 int lto_cgraph_encoder_lookup (lto_cgraph_encoder_t, struct cgraph_node *);
 lto_cgraph_encoder_t lto_cgraph_encoder_new (void);
 int lto_cgraph_encoder_encode (lto_cgraph_encoder_t, struct cgraph_node *);
-void lto_cgraph_encoder_delete (lto_cgraph_encoder_t encoder);
-void output_cgraph (cgraph_node_set);
+void lto_cgraph_encoder_delete (lto_cgraph_encoder_t);
+struct varpool_node *lto_varpool_encoder_deref (lto_varpool_encoder_t, int);
+int lto_varpool_encoder_lookup (lto_varpool_encoder_t, struct varpool_node *);
+lto_varpool_encoder_t lto_varpool_encoder_new (void);
+int lto_varpool_encoder_encode (lto_varpool_encoder_t, struct varpool_node *);
+void lto_varpool_encoder_delete (lto_varpool_encoder_t);
+bool lto_varpool_encoder_encode_initializer_p (lto_varpool_encoder_t,
+                                              struct varpool_node *);
+void output_cgraph (cgraph_node_set, varpool_node_set);
 void input_cgraph (void);
-void output_varpool (varpool_node_set);
-void input_varpool (void);
 
 
 /* In lto-symtab.c.  */
index c17da3b..72a8028 100644 (file)
@@ -1,3 +1,7 @@
+2010-05-05  Jan Hubicka  <jh@suse.cz>
+
+       * lto.c (lto_1_to_1_map): Partition only needed nodes.
+
 2010-04-30  Jan Hubicka  <jh@suse.cz>
 
        * lto.c (get_filename_for_set): Look for cgraph node and if none found, use
index d306580..d653b04 100644 (file)
@@ -584,7 +584,7 @@ lto_1_to_1_map (void)
 
   for (vnode = varpool_nodes; vnode; vnode = vnode->next)
     {
-      if (vnode->alias)
+      if (vnode->alias || !vnode->needed)
        continue;
       slot = pointer_map_contains (vpmap, file_data);
       if (slot)