lto-streamer.c (write_symbol_vec): Rename to ...
authorJan Hubicka <jh@suse.cz>
Tue, 6 Jul 2010 13:26:28 +0000 (15:26 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 6 Jul 2010 13:26:28 +0000 (13:26 +0000)
* lto-streamer.c (write_symbol_vec): Rename to ...
(write_symbol) ... this one; write only symbol given and when
present in cache. Sanity check that what is defined is present
in cgraph/varpool with body/finalized decl.
(write_symbols_of_kind): Remove.
(produce_symtab): Take outputblock and sets; use cgraph/varpool/alias
pairs to produce symtab.
(produce_asm_for_decls): Update call of produce_symtab; don't do so
when doing WPA streaming.

From-SVN: r161868

gcc/ChangeLog
gcc/gimple-fold.c
gcc/lto-streamer-out.c

index 59455aac58a09b1f41c58f369cb970f68f142b72..7c3c3f128523afa8fb6817b9121449cbc8a4d0bd 100644 (file)
@@ -1,3 +1,15 @@
+2010-07-05  Jan Hubicka  <jh@suse.cz>
+
+       * lto-streamer.c (write_symbol_vec): Rename to ...
+       (write_symbol) ... this one; write only symbol given and when
+       present in cache. Sanity check that what is defined is present
+       in cgraph/varpool with body/finalized decl.
+       (write_symbols_of_kind): Remove.
+       (produce_symtab): Take outputblock and sets; use cgraph/varpool/alias
+       pairs to produce symtab.
+       (produce_asm_for_decls): Update call of produce_symtab; don't do so
+       when doing WPA streaming.
+
 2010-07-05  Jan Hubicka  <jh@suse.cz>
 
        * gimple-fold.c (gimple_fold_obj_type_ref_known_binfo): Check that
index 659102b988bd5d6a521b4dd29c86b3223798ef7f..5bf82822a903f405abea2b47b1ec59cbe0d36823 100644 (file)
@@ -1368,7 +1368,7 @@ gimple_fold_obj_type_ref_known_binfo (HOST_WIDE_INT token, tree known_binfo)
      devirtualize.  This can happen in WHOPR when the actual method
      ends up in other partition, because we found devirtualization
      possibility too late.  */
-  if ((!node || !node->analyzed)
+  if ((!node || (!node->analyzed && !node->in_other_partition))
       && (!TREE_PUBLIC (fndecl) || DECL_COMDAT (fndecl)))
     return NULL;
   return build_fold_addr_expr (fndecl);
index b7029519caea5455bc4e2b647ce35ea8ebcf923d..5ef7b126c6c8a5ccc986fb4419436ccad46c2347 100644 (file)
@@ -2266,155 +2266,159 @@ lto_out_decl_state_written_size (struct lto_out_decl_state *state)
 }
 
 
-/* Helper function of write_symbols_of_kind.  CACHE is the streamer
-   cache with all the pickled nodes.  STREAM is the stream where to
-   write the table.  V is a vector with the DECLs that should be on
-   the table.  SEEN is a bitmap of symbols written so far.  */
-
-static void
-write_symbol_vec (struct lto_streamer_cache_d *cache,
-                 struct lto_output_stream *stream,
-                 VEC(tree,heap) *v, bitmap seen)
-{
-  tree t;
-  int index;
+/* Write symbol T into STREAM in CACHE. SEEN specify symbols we wrote so
+   far.  */
+
+static void
+write_symbol (struct lto_streamer_cache_d *cache,
+             struct lto_output_stream *stream,
+             tree t, bitmap seen, bool alias)
+{
+  const char *name;
+  enum gcc_plugin_symbol_kind kind;
+  enum gcc_plugin_symbol_visibility visibility;
+  int slot_num;
+  uint64_t size;
+  const char *comdat;
+
+  /* None of the following kinds of symbols are needed in the
+     symbol table.  */
+  if (!TREE_PUBLIC (t)
+      || is_builtin_fn (t)
+      || DECL_ABSTRACT (t)
+      || TREE_CODE (t) == RESULT_DECL)
+    return;
+
+  gcc_assert (TREE_CODE (t) == VAR_DECL
+             || TREE_CODE (t) == FUNCTION_DECL);
+
+  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
+
+  /* FIXME lto: this is from assemble_name_raw in varasm.c. For some
+     architectures we might have to do the same name manipulations that
+     ASM_OUTPUT_LABELREF does. */
+  if (name[0] == '*')
+    name = &name[1];
+
+  lto_streamer_cache_lookup (cache, t, &slot_num);
+  gcc_assert (slot_num >= 0);
+
+  /* Avoid duplicate symbols. */
+  if (bitmap_bit_p (seen, slot_num))
+    return;
+  else
+    bitmap_set_bit (seen, slot_num);
 
-  for (index = 0; VEC_iterate(tree, v, index, t); index++)
+  if (DECL_EXTERNAL (t))
     {
-      const char *name;
-      enum gcc_plugin_symbol_kind kind;
-      enum gcc_plugin_symbol_visibility visibility;
-      int slot_num;
-      uint64_t size;
-      const char *comdat;
-
-      /* None of the following kinds of symbols are needed in the
-        symbol table.  */
-      if (!TREE_PUBLIC (t)
-         || is_builtin_fn (t)
-         || DECL_ABSTRACT (t)
-         || TREE_CODE (t) == RESULT_DECL)
-       continue;
-
-      gcc_assert (TREE_CODE (t) == VAR_DECL
-                 || TREE_CODE (t) == FUNCTION_DECL);
-
-      name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
-
-      /* FIXME lto: this is from assemble_name_raw in varasm.c. For some
-        architectures we might have to do the same name manipulations that
-        ASM_OUTPUT_LABELREF does. */
-      if (name[0] == '*')
-       name = &name[1];
-
-      lto_streamer_cache_lookup (cache, t, &slot_num);
-      gcc_assert (slot_num >= 0);
-
-      /* Avoid duplicate symbols. */
-      if (bitmap_bit_p (seen, slot_num))
-       continue;
-      else
-        bitmap_set_bit (seen, slot_num);
-
-      if (DECL_EXTERNAL (t))
-       {
-         if (DECL_WEAK (t))
-           kind = GCCPK_WEAKUNDEF;
-         else
-           kind = GCCPK_UNDEF;
-       }
-      else
-       {
-         if (DECL_WEAK (t))
-           kind = GCCPK_WEAKDEF;
-         else if (DECL_COMMON (t))
-           kind = GCCPK_COMMON;
-         else
-           kind = GCCPK_DEF;
-       }
-
-      switch (DECL_VISIBILITY(t))
-       {
-       case VISIBILITY_DEFAULT:
-         visibility = GCCPV_DEFAULT;
-         break;
-       case VISIBILITY_PROTECTED:
-         visibility = GCCPV_PROTECTED;
-         break;
-       case VISIBILITY_HIDDEN:
-         visibility = GCCPV_HIDDEN;
-         break;
-       case VISIBILITY_INTERNAL:
-         visibility = GCCPV_INTERNAL;
-         break;
-       }
-
-      if (kind == GCCPK_COMMON
-         && DECL_SIZE (t)
-         && TREE_CODE (DECL_SIZE (t)) == INTEGER_CST)
-       size = (((uint64_t) TREE_INT_CST_HIGH (DECL_SIZE (t))) << 32)
-         | TREE_INT_CST_LOW (DECL_SIZE (t));
+      if (DECL_WEAK (t))
+       kind = GCCPK_WEAKUNDEF;
       else
-       size = 0;
-
-      if (DECL_ONE_ONLY (t))
-       comdat = IDENTIFIER_POINTER (DECL_COMDAT_GROUP (t));
+       kind = GCCPK_UNDEF;
+    }
+  else
+    {
+      if (DECL_WEAK (t))
+       kind = GCCPK_WEAKDEF;
+      else if (DECL_COMMON (t))
+       kind = GCCPK_COMMON;
       else
-       comdat = "";
-
-      lto_output_data_stream (stream, name, strlen (name) + 1);
-      lto_output_data_stream (stream, comdat, strlen (comdat) + 1);
-      lto_output_data_stream (stream, &kind, 1);
-      lto_output_data_stream (stream, &visibility, 1);
-      lto_output_data_stream (stream, &size, 8);
-      lto_output_data_stream (stream, &slot_num, 4);
+       kind = GCCPK_DEF;
+
+      /* When something is defined, it should have a node attached.
+        FIXME: For fortran this is still not the case since wrapup global
+        decls is done after streaming.  */
+      gcc_assert (alias || TREE_CODE (t) != FUNCTION_DECL
+                 || (cgraph_get_node (t)
+                     && cgraph_get_node (t)->analyzed));
     }
-}
-
 
-/* Write IL symbols of KIND.  CACHE is the streamer cache with all the
-   pickled nodes.  SEEN is a bitmap of symbols written so far.  */
-
-static void
-write_symbols_of_kind (lto_decl_stream_e_t kind,
-                      struct lto_streamer_cache_d *cache, bitmap seen)
-{
-  struct lto_out_decl_state *out_state;
-  struct lto_output_stream stream;
-  unsigned num_fns =
-    VEC_length (lto_out_decl_state_ptr, lto_function_decl_states);
-  unsigned idx;
-
-  memset (&stream, 0, sizeof (stream));
-  out_state = lto_get_out_decl_state ();
-  write_symbol_vec (cache, &stream, out_state->streams[kind].trees, seen);
-
-  for (idx = 0; idx < num_fns; idx++)
+  switch (DECL_VISIBILITY(t))
     {
-      out_state =
-       VEC_index (lto_out_decl_state_ptr, lto_function_decl_states, idx);
-      write_symbol_vec (cache, &stream, out_state->streams[kind].trees, seen);
+    case VISIBILITY_DEFAULT:
+      visibility = GCCPV_DEFAULT;
+      break;
+    case VISIBILITY_PROTECTED:
+      visibility = GCCPV_PROTECTED;
+      break;
+    case VISIBILITY_HIDDEN:
+      visibility = GCCPV_HIDDEN;
+      break;
+    case VISIBILITY_INTERNAL:
+      visibility = GCCPV_INTERNAL;
+      break;
     }
 
-  lto_write_stream (&stream);
+  if (kind == GCCPK_COMMON
+      && DECL_SIZE (t)
+      && TREE_CODE (DECL_SIZE (t)) == INTEGER_CST)
+    size = (((uint64_t) TREE_INT_CST_HIGH (DECL_SIZE (t))) << 32)
+      | TREE_INT_CST_LOW (DECL_SIZE (t));
+  else
+    size = 0;
+
+  if (DECL_ONE_ONLY (t))
+    comdat = IDENTIFIER_POINTER (DECL_COMDAT_GROUP (t));
+  else
+    comdat = "";
+
+  lto_output_data_stream (stream, name, strlen (name) + 1);
+  lto_output_data_stream (stream, comdat, strlen (comdat) + 1);
+  lto_output_data_stream (stream, &kind, 1);
+  lto_output_data_stream (stream, &visibility, 1);
+  lto_output_data_stream (stream, &size, 8);
+  lto_output_data_stream (stream, &slot_num, 4);
 }
 
 
-/* Write an IL symbol table.  CACHE is the streamer cache with all the
-   pickled nodes.  */
+/* Write an IL symbol table to OB.
+   SET and VSET are cgraph/varpool node sets we are outputting.  */
 
 static void
-produce_symtab (struct lto_streamer_cache_d *cache)
+produce_symtab (struct output_block *ob,
+               cgraph_node_set set, varpool_node_set vset)
 {
+  struct lto_streamer_cache_d *cache = ob->writer_cache;
   char *section_name = lto_get_section_name (LTO_section_symtab, NULL);
   bitmap seen;
+  struct cgraph_node *node, *alias;
+  struct varpool_node *vnode, *valias;
+  struct lto_output_stream stream;
+  lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
+  lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
+  int i;
+  alias_pair *p;
 
   lto_begin_section (section_name, false);
   free (section_name);
 
   seen = lto_bitmap_alloc ();
-  write_symbols_of_kind (LTO_DECL_STREAM_FN_DECL, cache, seen);
-  write_symbols_of_kind (LTO_DECL_STREAM_VAR_DECL, cache, seen);
+  memset (&stream, 0, sizeof (stream));
+
+  /* Write all functions.  */
+  for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
+    {
+      node = lto_cgraph_encoder_deref (encoder, i);
+      write_symbol (cache, &stream, node->decl, seen, false);
+      for (alias = node->same_body; alias; alias = alias->next)
+        write_symbol (cache, &stream, alias->decl, seen, true);
+    }
+
+  /* Write all variables.  */
+  for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
+    {
+      vnode = lto_varpool_encoder_deref (varpool_encoder, i);
+      write_symbol (cache, &stream, vnode->decl, seen, false);
+      for (valias = vnode->extra_name; valias; valias = valias->next)
+        write_symbol (cache, &stream, valias->decl, seen, true);
+    }
+
+  /* Write all aliases.  */
+  for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); i++)
+    if (output_alias_pair_p (p, set, vset))
+      write_symbol (cache, &stream, p->decl, seen, true);
+
+  lto_write_stream (&stream);
   lto_bitmap_free (seen);
 
   lto_end_section ();
@@ -2517,8 +2521,10 @@ produce_asm_for_decls (cgraph_node_set set, varpool_node_set vset)
 
   lto_end_section ();
 
-  /* Write the symbol table. */
-  produce_symtab (ob->writer_cache);
+  /* Write the symbol table.  It is used by linker to determine dependencies
+     and thus we can skip it for WPA.  */
+  if (!flag_wpa)
+    produce_symtab (ob, set, vset);
 
   /* Write command line opts.  */
   lto_write_options ();