OSDN Git Service

2012-04-13 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / gcc / lto-cgraph.c
index 5bcc342..5e899bc 100644 (file)
@@ -52,7 +52,10 @@ static void output_cgraph_opt_summary (cgraph_node_set set);
 static void input_cgraph_opt_summary (VEC (cgraph_node_ptr, heap) * nodes);
 
 /* Number of LDPR values known to GCC.  */
-#define LDPR_NUM_KNOWN (LDPR_RESOLVED_DYN + 1)
+#define LDPR_NUM_KNOWN (LDPR_PREVAILING_DEF_IRONLY_EXP + 1)
+
+/* All node orders are ofsetted by ORDER_BASE.  */
+static int order_base;
 
 /* Cgraph streaming is organized as set of record whose type
    is indicated by a tag.  */
@@ -425,6 +428,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
 
   streamer_write_enum (ob->main_stream, LTO_cgraph_tags, LTO_cgraph_last_tag,
                       tag);
+  streamer_write_hwi_stream (ob->main_stream, node->order);
 
   /* In WPA mode, we only output part of the call-graph.  Also, we
      fake cgraph node attributes.  There are two cases that we care.
@@ -495,6 +499,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
   bp_pack_value (&bp, node->local.local, 1);
   bp_pack_value (&bp, node->local.externally_visible, 1);
   bp_pack_value (&bp, node->local.finalized, 1);
+  bp_pack_value (&bp, node->local.versionable, 1);
   bp_pack_value (&bp, node->local.can_change_signature, 1);
   bp_pack_value (&bp, node->local.redefined_extern_inline, 1);
   bp_pack_value (&bp, node->needed, 1);
@@ -507,10 +512,17 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
                     || referenced_from_other_partition_p (&node->ref_list, set, vset)), 1);
   bp_pack_value (&bp, node->lowered, 1);
   bp_pack_value (&bp, in_other_partition, 1);
-  bp_pack_value (&bp, node->alias && !boundary_p, 1);
+  /* Real aliases in a boundary become non-aliases. However we still stream
+     alias info on weakrefs. 
+     TODO: We lose a bit of information here - when we know that variable is
+     defined in other unit, we may use the info on aliases to resolve 
+     symbol1 != symbol2 type tests that we can do only for locally defined objects
+     otherwise.  */
+  bp_pack_value (&bp, node->alias && (!boundary_p || DECL_EXTERNAL (node->decl)), 1);
   bp_pack_value (&bp, node->frequency, 2);
   bp_pack_value (&bp, node->only_called_at_startup, 1);
   bp_pack_value (&bp, node->only_called_at_exit, 1);
+  bp_pack_value (&bp, node->tm_clone, 1);
   bp_pack_value (&bp, node->thunk.thunk_p && !boundary_p, 1);
   bp_pack_enum (&bp, ld_plugin_symbol_resolution,
                LDPR_NUM_KNOWN, node->resolution);
@@ -525,7 +537,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
       streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset);
       streamer_write_uhwi_stream (ob->main_stream, node->thunk.virtual_value);
     }
-  if ((node->alias || node->thunk.thunk_p) && !boundary_p)
+  if ((node->alias || node->thunk.thunk_p)
+      && (!boundary_p || (node->alias && DECL_EXTERNAL (node->decl))))
     {
       streamer_write_hwi_in_range (ob->main_stream, 0, 1,
                                        node->thunk.alias != NULL);
@@ -547,6 +560,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node
   struct bitpack_d bp;
   int ref;
 
+  streamer_write_hwi_stream (ob->main_stream, node->order);
   lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->decl);
   bp = bitpack_create (ob->main_stream);
   bp_pack_value (&bp, node->externally_visible, 1);
@@ -816,7 +830,6 @@ output_cgraph (cgraph_node_set set, varpool_node_set vset)
   int i, n_nodes;
   lto_cgraph_encoder_t encoder;
   lto_varpool_encoder_t varpool_encoder;
-  struct cgraph_asm_node *can;
   static bool asm_nodes_output = false;
 
   if (flag_wpa)
@@ -853,6 +866,8 @@ output_cgraph (cgraph_node_set set, varpool_node_set vset)
 
   streamer_write_uhwi_stream (ob->main_stream, 0);
 
+  lto_destroy_simple_output_block (ob);
+
   /* Emit toplevel asms.
      When doing WPA we must output every asm just once.  Since we do not partition asm
      nodes at all, output them to first output.  This is kind of hack, but should work
@@ -860,19 +875,9 @@ output_cgraph (cgraph_node_set set, varpool_node_set vset)
   if (!asm_nodes_output)
     {
       asm_nodes_output = true;
-      for (can = cgraph_asm_nodes; can; can = can->next)
-       {
-         int len = TREE_STRING_LENGTH (can->asm_str);
-         streamer_write_uhwi_stream (ob->main_stream, len);
-         for (i = 0; i < len; ++i)
-           streamer_write_char_stream (ob->main_stream,
-                                       TREE_STRING_POINTER (can->asm_str)[i]);
-       }
+      lto_output_toplevel_asms ();
     }
 
-  streamer_write_uhwi_stream (ob->main_stream, 0);
-
-  lto_destroy_simple_output_block (ob);
   output_varpool (set, vset);
   output_refs (set, vset, encoder, varpool_encoder);
 }
@@ -896,6 +901,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
   node->local.local = bp_unpack_value (bp, 1);
   node->local.externally_visible = bp_unpack_value (bp, 1);
   node->local.finalized = bp_unpack_value (bp, 1);
+  node->local.versionable = bp_unpack_value (bp, 1);
   node->local.can_change_signature = bp_unpack_value (bp, 1);
   node->local.redefined_extern_inline = bp_unpack_value (bp, 1);
   node->needed = bp_unpack_value (bp, 1);
@@ -923,6 +929,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
   node->frequency = (enum node_frequency)bp_unpack_value (bp, 2);
   node->only_called_at_startup = bp_unpack_value (bp, 1);
   node->only_called_at_exit = bp_unpack_value (bp, 1);
+  node->tm_clone = bp_unpack_value (bp, 1);
   node->thunk.thunk_p = bp_unpack_value (bp, 1);
   node->resolution = bp_unpack_enum (bp, ld_plugin_symbol_resolution,
                                     LDPR_NUM_KNOWN);
@@ -967,7 +974,9 @@ input_node (struct lto_file_decl_data *file_data,
   unsigned decl_index;
   int ref = LCC_NOT_FOUND, ref2 = LCC_NOT_FOUND;
   int clone_ref;
+  int order;
 
+  order = streamer_read_hwi (ib) + order_base;
   clone_ref = streamer_read_hwi (ib);
 
   decl_index = streamer_read_uhwi (ib);
@@ -981,6 +990,10 @@ input_node (struct lto_file_decl_data *file_data,
   else
     node = cgraph_get_create_node (fn_decl);
 
+  node->order = order;
+  if (order >= cgraph_order)
+    cgraph_order = order + 1;
+
   node->count = streamer_read_hwi (ib);
   node->count_materialization_scale = streamer_read_hwi (ib);
 
@@ -1042,10 +1055,15 @@ input_varpool_node (struct lto_file_decl_data *file_data,
   struct bitpack_d bp;
   int ref = LCC_NOT_FOUND;
   bool non_null_aliasof;
+  int order;
 
+  order = streamer_read_hwi (ib) + order_base;
   decl_index = streamer_read_uhwi (ib);
   var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index);
   node = varpool_node (var_decl);
+  node->order = order;
+  if (order >= cgraph_order)
+    cgraph_order = order + 1;
   node->lto_file_data = file_data;
 
   bp = streamer_read_bitpack (ib);
@@ -1183,9 +1201,9 @@ input_cgraph_1 (struct lto_file_decl_data *file_data,
   VEC(cgraph_node_ptr, heap) *nodes = NULL;
   struct cgraph_node *node;
   unsigned i;
-  unsigned HOST_WIDE_INT len;
 
   tag = streamer_read_enum (ib, LTO_cgraph_tags, LTO_cgraph_last_tag);
+  order_base = cgraph_order;
   while (tag)
     {
       if (tag == LTO_cgraph_edge)
@@ -1204,18 +1222,8 @@ input_cgraph_1 (struct lto_file_decl_data *file_data,
       tag = streamer_read_enum (ib, LTO_cgraph_tags, LTO_cgraph_last_tag);
     }
 
-  /* Input toplevel asms.  */
-  len = streamer_read_uhwi (ib);
-  while (len)
-    {
-      char *str = (char *)xmalloc (len + 1);
-      for (i = 0; i < len; ++i)
-       str[i] = streamer_read_uchar (ib);
-      cgraph_add_asm_node (build_string (len, str));
-      free (str);
+  lto_input_toplevel_asms (file_data, order_base);
 
-      len = streamer_read_uhwi (ib);
-    }
   /* AUX pointers should be all non-zero for nodes read from the stream.  */
 #ifdef ENABLE_CHECKING
   FOR_EACH_VEC_ELT (cgraph_node_ptr, nodes, i, node)
@@ -1501,22 +1509,9 @@ input_cgraph (void)
 /* True when we need optimization summary for NODE.  */
 
 static int
-output_cgraph_opt_summary_p (struct cgraph_node *node, cgraph_node_set set)
+output_cgraph_opt_summary_p (struct cgraph_node *node,
+                            cgraph_node_set set ATTRIBUTE_UNUSED)
 {
-  struct cgraph_edge *e;
-
-  if (cgraph_node_in_set_p (node, set))
-    {
-      for (e = node->callees; e; e = e->next_callee)
-       if (e->indirect_info
-           && e->indirect_info->thunk_delta != 0)
-         return true;
-
-      for (e = node->indirect_calls; e; e = e->next_callee)
-       if (e->indirect_info->thunk_delta != 0)
-         return true;
-    }
-
   return (node->clone_of
          && (node->clone.tree_map
              || node->clone.args_to_skip
@@ -1525,13 +1520,9 @@ output_cgraph_opt_summary_p (struct cgraph_node *node, cgraph_node_set set)
 
 /* Output optimization summary for EDGE to OB.  */
 static void
-output_edge_opt_summary (struct output_block *ob,
-                        struct cgraph_edge *edge)
+output_edge_opt_summary (struct output_block *ob ATTRIBUTE_UNUSED,
+                        struct cgraph_edge *edge ATTRIBUTE_UNUSED)
 {
-  if (edge->indirect_info)
-    streamer_write_hwi (ob, edge->indirect_info->thunk_delta);
-  else
-    streamer_write_hwi (ob, 0);
 }
 
 /* Output optimization summary for NODE to OB.  */
@@ -1631,17 +1622,9 @@ output_cgraph_opt_summary (cgraph_node_set set)
 /* Input optimisation summary of EDGE.  */
 
 static void
-input_edge_opt_summary (struct cgraph_edge *edge,
-                       struct lto_input_block *ib_main)
+input_edge_opt_summary (struct cgraph_edge *edge ATTRIBUTE_UNUSED,
+                       struct lto_input_block *ib_main ATTRIBUTE_UNUSED)
 {
-  HOST_WIDE_INT thunk_delta;
-  thunk_delta = streamer_read_hwi (ib_main);
-  if (thunk_delta != 0)
-    {
-      gcc_assert (!edge->indirect_info);
-      edge->indirect_info = cgraph_allocate_init_indirect_info ();
-      edge->indirect_info->thunk_delta = thunk_delta;
-    }
 }
 
 /* Input optimisation summary of NODE.  */
@@ -1706,9 +1689,9 @@ input_cgraph_opt_section (struct lto_file_decl_data *file_data,
 {
   const struct lto_function_header *header =
     (const struct lto_function_header *) data;
-  const int32_t cfg_offset = sizeof (struct lto_function_header);
-  const int32_t main_offset = cfg_offset + header->cfg_size;
-  const int32_t string_offset = main_offset + header->main_size;
+  const int cfg_offset = sizeof (struct lto_function_header);
+  const int main_offset = cfg_offset + header->cfg_size;
+  const int string_offset = main_offset + header->main_size;
   struct data_in *data_in;
   struct lto_input_block ib_main;
   unsigned int i;