]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Makefile.in (lto-compress.o): Add dependency on LTO_STREAMER_H.
authorDiego Novillo <dnovillo@google.com>
Mon, 6 Jun 2011 16:49:11 +0000 (12:49 -0400)
committerDiego Novillo <dnovillo@gcc.gnu.org>
Mon, 6 Jun 2011 16:49:11 +0000 (12:49 -0400)
* Makefile.in (lto-compress.o): Add dependency on LTO_STREAMER_H.
(cgraph.o): Likewise.
(cgraphunit.o): Likewise.
* cgraphunit.c: Include lto-streamer.h
(cgraph_finalize_compilation_unit): Call lto_streamer_hooks_init
if LTO is enabled.
* lto-streamer-in.c (unpack_value_fields): Call
streamer_hooks.unpack_value_fields if set.
(lto_materialize_tree): For unhandled nodes, first try to
call lto_streamer_hooks.alloc_tree, if it exists.
(lto_input_ts_decl_common_tree_pointers): Move reading of
DECL_INITIAL to lto_streamer_read_tree.
(lto_read_tree): Call lto_streamer_hooks.read_tree if set.
(lto_streamer_read_tree): New.
(lto_reader_init): Rename from lto_init_reader.
Move initialization code to lto/lto.c.
* lto-streamer-out.c (pack_value_fields): Call
streamer_hooks.pack_value_fields if set.
(lto_output_tree_ref): For tree nodes that are not
normally indexable, call streamer_hooks.indexable_with_decls_p
before giving up.
(lto_output_ts_decl_common_tree_pointers): Move handling
for FUNCTION_DECL and TRANSLATION_UNIT_DECL to
lto_streamer_write_tree.
(lto_output_tree_header): Call streamer_hooks.is_streamable
instead of lto_is_streamable.
Call lto_streamer_hooks.output_tree_header if set.
(lto_write_tree): Call lto_streamer_hooks.write_tree if
set.
(lto_streamer_write_tree): New.
(lto_output): Call lto_streamer_init directly.
(lto_writer_init): Remove.
* lto-streamer.c (streamer_hooks): New.
(lto_streamer_cache_create): Call streamer_hooks.preload_common_nodes
instead of lto_preload_common_nodes.
(lto_is_streamable): Move from lto-streamer.h
(lto_streamer_hooks_init): New.
(streamer_hooks): New.
(streamer_hooks_init): New.
* lto-streamer.h (struct output_block): Forward declare.
(struct lto_input_block): Likewise.
(struct data_in): Likewise.
(struct bitpack_d): Likewise.
(struct streamer_hooks): Declare.
(streamer_hooks): Declare.
(lto_streamer_hooks_init): Declare.
(lto_streamer_write_tree): Declare.
(lto_streamer_read_tree): Declare.
(streamer_hooks_init): Declare.
(lto_is_streamable): Move to lto-streamer.c

lto/ChangeLog

* lto.c (lto_init): New.
(lto_main): Call it.

From-SVN: r174709

gcc/ChangeLog
gcc/Makefile.in
gcc/cgraphunit.c
gcc/lto-streamer-in.c
gcc/lto-streamer-out.c
gcc/lto-streamer.c
gcc/lto-streamer.h
gcc/lto/ChangeLog
gcc/lto/lto.c

index 59c7656f8173e1cb748d0ed3d482d9ba00c5a508..3166f93c28c7aedd99c37a713f381f4940505871 100644 (file)
@@ -1,3 +1,56 @@
+2011-06-04  Diego Novillo  <dnovillo@google.com>
+
+       * Makefile.in (lto-compress.o): Add dependency on LTO_STREAMER_H.
+       (cgraph.o): Likewise.
+       (cgraphunit.o): Likewise.
+       * cgraphunit.c: Include lto-streamer.h
+       (cgraph_finalize_compilation_unit): Call lto_streamer_hooks_init
+       if LTO is enabled.
+       * lto-streamer-in.c (unpack_value_fields): Call
+       streamer_hooks.unpack_value_fields if set.
+       (lto_materialize_tree): For unhandled nodes, first try to
+       call lto_streamer_hooks.alloc_tree, if it exists.
+       (lto_input_ts_decl_common_tree_pointers): Move reading of
+       DECL_INITIAL to lto_streamer_read_tree.
+       (lto_read_tree): Call lto_streamer_hooks.read_tree if set.
+       (lto_streamer_read_tree): New.
+       (lto_reader_init): Rename from lto_init_reader.
+       Move initialization code to lto/lto.c.
+       * lto-streamer-out.c (pack_value_fields): Call
+       streamer_hooks.pack_value_fields if set.
+       (lto_output_tree_ref): For tree nodes that are not
+       normally indexable, call streamer_hooks.indexable_with_decls_p
+       before giving up.
+       (lto_output_ts_decl_common_tree_pointers): Move handling
+       for FUNCTION_DECL and TRANSLATION_UNIT_DECL to
+       lto_streamer_write_tree.
+       (lto_output_tree_header): Call streamer_hooks.is_streamable
+       instead of lto_is_streamable.
+       Call lto_streamer_hooks.output_tree_header if set.
+       (lto_write_tree): Call lto_streamer_hooks.write_tree if
+       set.
+       (lto_streamer_write_tree): New.
+       (lto_output): Call lto_streamer_init directly.
+       (lto_writer_init): Remove.
+       * lto-streamer.c (streamer_hooks): New.
+       (lto_streamer_cache_create): Call streamer_hooks.preload_common_nodes
+       instead of lto_preload_common_nodes.
+       (lto_is_streamable): Move from lto-streamer.h
+       (lto_streamer_hooks_init): New.
+       (streamer_hooks): New.
+       (streamer_hooks_init): New.
+       * lto-streamer.h (struct output_block): Forward declare.
+       (struct lto_input_block): Likewise.
+       (struct data_in): Likewise.
+       (struct bitpack_d): Likewise.
+       (struct streamer_hooks): Declare.
+       (streamer_hooks): Declare.
+       (lto_streamer_hooks_init): Declare.
+       (lto_streamer_write_tree): Declare.
+       (lto_streamer_read_tree): Declare.
+       (streamer_hooks_init): Declare.
+       (lto_is_streamable): Move to lto-streamer.c
+
 2011-06-06  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
        * longlong.h (smul_ppmm): The resulting register pair contains the
index 81736a045a03e14bdd59452af5ef2ca7ebe425f7..496177cde633e8d1a4266ab979b5ce74dbc61b92 100644 (file)
@@ -2348,7 +2348,7 @@ double-int.o: double-int.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
 
 # lto-compress.o needs $(ZLIBINC) added to the include flags.
 lto-compress.o: lto-compress.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
-       $(TREE_H) langhooks.h $(LTO_HEADER_H) $(LTO_SECTION_H) \
+       $(TREE_H) langhooks.h $(LTO_STREAMER_H) $(LTO_SECTION_H) \
        lto-compress.h $(DIAGNOSTIC_CORE_H) $(DIAGNOSTIC_CORE_H)
        $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(ZLIBINC) $< $(OUTPUT_OPTION)
 
@@ -3030,14 +3030,15 @@ cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
    $(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) cif-code.def \
    value-prof.h $(EXCEPT_H) $(IPA_UTILS_H) $(DIAGNOSTIC_CORE_H) \
-   ipa-inline.h
+   ipa-inline.h $(LTO_STREAMER_H)
 cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) \
    $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) \
    $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \
    gt-cgraphunit.h tree-iterator.h $(COVERAGE_H) $(TREE_DUMP_H) \
-   tree-pretty-print.h gimple-pretty-print.h ipa-inline.h $(IPA_UTILS_H)
+   tree-pretty-print.h gimple-pretty-print.h ipa-inline.h $(IPA_UTILS_H) \
+   $(LTO_STREAMER_H)
 cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) $(IPA_UTILS_H) $(EXCEPT_H) \
index 834acb101e55e773c3facb6e5b1cb5171e90a75a..614b7858a3f9ab585ff5a71a7af9fb4118f691a6 100644 (file)
@@ -140,6 +140,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "plugin.h"
 #include "ipa-inline.h"
 #include "ipa-utils.h"
+#include "lto-streamer.h"
 
 static void cgraph_expand_all_functions (void);
 static void cgraph_mark_functions_to_output (void);
@@ -1092,6 +1093,10 @@ cgraph_finalize_compilation_unit (void)
 {
   timevar_push (TV_CGRAPH);
 
+  /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE.  */
+  if (flag_lto)
+    lto_streamer_hooks_init ();
+
   /* If we're here there's no current function anymore.  Some frontends
      are lazy in clearing these.  */
   current_function_decl = NULL;
index 3a5eb5a63feaee9ab29e86fcb4d508bb1dc661fe..25ccb24a105764c61afe8454c6055903400eb233 100644 (file)
@@ -1841,6 +1841,9 @@ unpack_value_fields (struct bitpack_d *bp, tree expr)
 
   if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
     unpack_ts_translation_unit_decl_value_fields (bp, expr);
+
+  if (streamer_hooks.unpack_value_fields)
+    streamer_hooks.unpack_value_fields (bp, expr);
 }
 
 
@@ -1892,8 +1895,15 @@ lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
     }
   else
     {
-      /* All other nodes can be materialized with a raw make_node call.  */
-      result = make_node (code);
+      /* For all other nodes, see if the streamer knows how to allocate
+        it.  */
+      if (streamer_hooks.alloc_tree)
+       result = streamer_hooks.alloc_tree (code, ib, data_in);
+
+      /* If the hook did not handle it, materialize the tree with a raw
+        make_node call.  */
+      if (result == NULL_TREE)
+       result = make_node (code);
     }
 
 #ifdef LTO_STREAMER_DEBUG
@@ -1988,12 +1998,8 @@ lto_input_ts_decl_common_tree_pointers (struct lto_input_block *ib,
 {
   DECL_SIZE (expr) = lto_input_tree (ib, data_in);
   DECL_SIZE_UNIT (expr) = lto_input_tree (ib, data_in);
-
-  if (TREE_CODE (expr) != FUNCTION_DECL
-      && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
-    DECL_INITIAL (expr) = lto_input_tree (ib, data_in);
-
   DECL_ATTRIBUTES (expr) = lto_input_tree (ib, data_in);
+
   /* Do not stream DECL_ABSTRACT_ORIGIN.  We cannot handle debug information
      for early inlining so drop it on the floor instead of ICEing in
      dwarf2out.c.  */
@@ -2484,6 +2490,11 @@ lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
   /* Read all the pointer fields in RESULT.  */
   lto_input_tree_pointers (ib, data_in, result);
 
+  /* Call back into the streaming module to read anything else it
+     may need.  */
+  if (streamer_hooks.read_tree)
+    streamer_hooks.read_tree (ib, data_in, result);
+
   /* We should never try to instantiate an MD or NORMAL builtin here.  */
   if (TREE_CODE (result) == FUNCTION_DECL)
     gcc_assert (!lto_stream_as_builtin_p (result));
@@ -2500,6 +2511,21 @@ lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
 }
 
 
+/* LTO streamer hook for reading GIMPLE trees.  IB and DATA_IN are as in
+   lto_read_tree.  EXPR is the tree was materialized by lto_read_tree and
+   needs GIMPLE specific data to be filled in.  */
+
+void
+lto_streamer_read_tree (struct lto_input_block *ib, struct data_in *data_in,
+                       tree expr)
+{
+  if (DECL_P (expr)
+      && TREE_CODE (expr) != FUNCTION_DECL
+      && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
+    DECL_INITIAL (expr) = lto_input_tree (ib, data_in);
+}
+
+
 /* Read and INTEGER_CST node from input block IB using the per-file
    context in DATA_IN.  */
 
@@ -2581,17 +2607,11 @@ lto_input_tree (struct lto_input_block *ib, struct data_in *data_in)
 /* Initialization for the LTO reader.  */
 
 void
-lto_init_reader (void)
+lto_reader_init (void)
 {
   lto_streamer_init ();
-
-  memset (&lto_stats, 0, sizeof (lto_stats));
-  bitmap_obstack_initialize (NULL);
-
   file_name_hash_table = htab_create (37, hash_string_slot_node,
                                      eq_string_slot_node, free);
-
-  gimple_register_cfg_hooks ();
 }
 
 
index 66b1ac6f100448eae067ca83c02831171e60d6e0..02ac9583aced8f02e9c77a050ba19f11ff79169d 100644 (file)
@@ -591,6 +591,9 @@ pack_value_fields (struct bitpack_d *bp, tree expr)
 
   if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
     pack_ts_translation_unit_decl_value_fields (bp, expr);
+
+  if (streamer_hooks.pack_value_fields)
+    streamer_hooks.pack_value_fields (bp, expr);
 }
 
 
@@ -754,9 +757,22 @@ lto_output_tree_ref (struct output_block *ob, tree expr)
       break;
 
     default:
-      /* No other node is indexable, so it should have been handled
-        by lto_output_tree.  */
-      gcc_unreachable ();
+      {
+       /* See if the streamer allows this node to be indexable
+          like other global declarations.  */
+       if (streamer_hooks.indexable_with_decls_p
+           && streamer_hooks.indexable_with_decls_p (expr))
+         {
+           output_record_start (ob, LTO_global_decl_ref);
+           lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
+         }
+       else
+         {
+           /* No other node is indexable, so it should have been
+             handled by lto_output_tree.  */
+           gcc_unreachable ();
+         }
+      }
     }
 }
 
@@ -865,27 +881,11 @@ lto_output_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
   lto_output_tree_or_ref (ob, DECL_SIZE (expr), ref_p);
   lto_output_tree_or_ref (ob, DECL_SIZE_UNIT (expr), ref_p);
 
-  if (TREE_CODE (expr) != FUNCTION_DECL
-      && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
-    {
-      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);
-    }
+  /* Note, DECL_INITIAL is not handled here.  Since DECL_INITIAL needs
+     special handling in LTO, it must be handled by streamer hooks.  */
 
   lto_output_tree_or_ref (ob, DECL_ATTRIBUTES (expr), ref_p);
+
   /* Do not stream DECL_ABSTRACT_ORIGIN.  We cannot handle debug information
      for early inlining so drop it on the floor instead of ICEing in
      dwarf2out.c.  */
@@ -1261,11 +1261,11 @@ lto_output_tree_header (struct output_block *ob, tree expr)
   enum LTO_tags tag;
   enum tree_code code;
 
-  /* We should not see any non-GIMPLE tree nodes here.  */
+  /* We should not see any tree nodes not handled by the streamer.  */
   code = TREE_CODE (expr);
-  if (!lto_is_streamable (expr))
-    internal_error ("tree code %qs is not supported in gimple streams",
-                   tree_code_name[code]);
+  if (!streamer_hooks.is_streamable (expr))
+    internal_error ("tree code %qs is not supported in %s streams",
+                   tree_code_name[code], streamer_hooks.name);
 
   /* The header of a tree node consists of its tag, the size of
      the node, and any other information needed to instantiate
@@ -1294,6 +1294,11 @@ lto_output_tree_header (struct output_block *ob, tree expr)
     output_sleb128 (ob, TREE_VEC_LENGTH (expr));
   else if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
     output_uleb128 (ob, BINFO_N_BASE_BINFOS (expr));
+
+  /* Allow the streamer to write any streamer-specific information
+     needed to instantiate the node when reading.  */
+  if (streamer_hooks.output_tree_header)
+    streamer_hooks.output_tree_header (ob, expr);
 }
 
 
@@ -1355,11 +1360,49 @@ lto_write_tree (struct output_block *ob, tree expr, bool ref_p)
   /* Write all the pointer fields in EXPR.  */
   lto_output_tree_pointers (ob, expr, ref_p);
 
+  /* Call back into the streaming module to see if it needs to write
+     anything that was not written by the common streamer.  */
+  if (streamer_hooks.write_tree)
+    streamer_hooks.write_tree (ob, expr, ref_p);
+
   /* Mark the end of EXPR.  */
   output_zero (ob);
 }
 
 
+/* GIMPLE hook for writing GIMPLE-specific parts of trees.  OB, EXPR
+   and REF_P are as in lto_write_tree.  */
+
+void
+lto_streamer_write_tree (struct output_block *ob, tree expr, bool ref_p)
+{
+  if (DECL_P (expr)
+      && TREE_CODE (expr) != FUNCTION_DECL
+      && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
+    {
+      /* Handle DECL_INITIAL for symbols.  */
+      tree initial = DECL_INITIAL (expr);
+      if (TREE_CODE (expr) == VAR_DECL
+         && (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
+         && initial)
+       {
+         lto_varpool_encoder_t varpool_encoder;
+         struct varpool_node *vnode;
+
+         varpool_encoder = ob->decl_state->varpool_node_encoder;
+         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);
+    }
+}
+
+
 /* Emit the integer constant CST to output block OB.  If REF_P is true,
    CST's type will be emitted as a reference.  */
 
@@ -2188,15 +2231,6 @@ copy_function (struct cgraph_node *node)
 }
 
 
-/* Initialize the LTO writer.  */
-
-static void
-lto_writer_init (void)
-{
-  lto_streamer_init ();
-}
-
-
 /* Main entry point from the pass manager.  */
 
 static void
@@ -2210,7 +2244,8 @@ lto_output (cgraph_node_set set, varpool_node_set vset)
   int i, n_nodes;
   lto_cgraph_encoder_t encoder = lto_get_out_decl_state ()->cgraph_node_encoder;
 
-  lto_writer_init ();
+  /* Initialize the streamer.  */
+  lto_streamer_init ();
 
   n_nodes = lto_cgraph_encoder_size (encoder);
   /* Process only the functions with bodies.  */
index 763ecc5e903e0f688e927618818af2059b934c00..0608b33a76bd610e81ba60f17aa020848ecb78a4 100644 (file)
@@ -37,6 +37,9 @@ along with GCC; see the file COPYING3.  If not see
 /* Statistics gathered during LTO, WPA and LTRANS.  */
 struct lto_stats_d lto_stats;
 
+/* Streamer hooks.  */
+struct streamer_hooks streamer_hooks;
+
 /* LTO uses bitmaps with different life-times.  So use a seperate
    obstack for all LTO bitmaps.  */
 static bitmap_obstack lto_obstack;
@@ -568,7 +571,7 @@ lto_streamer_cache_create (void)
   /* Load all the well-known tree nodes that are always created by
      the compiler on startup.  This prevents writing them out
      unnecessarily.  */
-  lto_preload_common_nodes (cache);
+  streamer_hooks.preload_common_nodes (cache);
 
   return cache;
 }
@@ -713,3 +716,52 @@ lto_check_version (int major, int minor)
                 major, minor,
                 LTO_major_version, LTO_minor_version);
 }
+
+
+/* Return true if EXPR is a tree node that can be written to disk.  */
+static inline bool
+lto_is_streamable (tree expr)
+{
+  enum tree_code code = TREE_CODE (expr);
+
+  /* Notice that we reject SSA_NAMEs as well.  We only emit the SSA
+     name version in lto_output_tree_ref (see output_ssa_names).  */
+  return !is_lang_specific (expr)
+        && code != SSA_NAME
+        && code != CALL_EXPR
+        && code != LANG_TYPE
+        && code != MODIFY_EXPR
+        && code != INIT_EXPR
+        && code != TARGET_EXPR
+        && code != BIND_EXPR
+        && code != WITH_CLEANUP_EXPR
+        && code != STATEMENT_LIST
+        && code != OMP_CLAUSE
+        && code != OPTIMIZATION_NODE
+        && (code == CASE_LABEL_EXPR
+            || code == DECL_EXPR
+            || TREE_CODE_CLASS (code) != tcc_statement);
+}
+
+
+/* Initialize all the streamer hooks used for streaming GIMPLE.  */
+
+void
+lto_streamer_hooks_init (void)
+{
+  streamer_hooks_init ();
+  streamer_hooks.name = "gimple";
+  streamer_hooks.preload_common_nodes = lto_preload_common_nodes;
+  streamer_hooks.is_streamable = lto_is_streamable;
+  streamer_hooks.write_tree = lto_streamer_write_tree;
+  streamer_hooks.read_tree = lto_streamer_read_tree;
+}
+
+
+/* Initialize the current set of streamer hooks.  */
+
+void
+streamer_hooks_init (void)
+{
+  memset (&streamer_hooks, 0, sizeof (streamer_hooks));
+}
index 5f69655fb98b0742a7a63f62786eb85ef6e60438..157e5c0052e4ef235757c43ca37b2a6b97170b52 100644 (file)
@@ -33,6 +33,12 @@ along with GCC; see the file COPYING3.  If not see
 #include "alloc-pool.h"
 #include "gcov-io.h"
 
+/* Forward declarations to avoid including unnecessary headers.  */
+struct output_block;
+struct lto_input_block;
+struct data_in;
+struct bitpack_d;
+
 /* Define when debugging the LTO streamer.  This causes the writer
    to output the numeric value for the memory address of the tree node
    being emitted.  When debugging a problem in the reader, check the
@@ -741,6 +747,86 @@ struct data_in
 };
 
 
+/* Streamer hooks.  These functions do additional processing as
+   needed by the module.  There are two types of callbacks, those that
+   replace the default behavior and those that supplement it.
+
+   Hooks marked [REQ] are required to be set.  Those marked [OPT] may
+   be NULL, if the streamer does not need to implement them.  */
+struct streamer_hooks {
+  /* [REQ] A string identifying this streamer.  */
+  const char *name;
+
+  /* [REQ] Called by lto_streamer_cache_create to instantiate a cache of
+     well-known nodes.  These are tree nodes that are always
+     instantiated by the compiler on startup.  Additionally, these
+     nodes need to be shared.  This function should call
+     lto_streamer_cache_append on every tree node that it wishes to
+     preload in the streamer cache.  This way, the writer will only
+     write out a reference to the tree and the reader will instantiate
+     the tree out of this pre-populated cache.  */
+  void (*preload_common_nodes) (struct lto_streamer_cache_d *);
+
+  /* [REQ] Return true if the given tree is supported by this streamer.  */
+  bool (*is_streamable) (tree);
+
+  /* [OPT] Called by lto_write_tree after writing all the common parts of
+     a tree.  If defined, the callback is in charge of writing all
+     the fields that lto_write_tree did not write out.  Arguments
+     are as in lto_write_tree.
+
+     The following tree fields are not handled by common code:
+
+       DECL_ABSTRACT_ORIGIN
+       DECL_INITIAL
+       DECL_SAVED_TREE
+
+     Callbacks may choose to ignore or handle them.  If handled,
+     the reader should read them in the exact same sequence written
+     by the writer.  */
+  void (*write_tree) (struct output_block *, tree, bool);
+
+  /* [OPT] Called by lto_read_tree after reading all the common parts of
+     a tree.  If defined, the callback is in charge of reading all
+     the fields that lto_read_tree did not read in.  Arguments
+     are as in lto_read_tree.  */
+  void (*read_tree) (struct lto_input_block *, struct data_in *, tree);
+
+  /* [OPT] Called by lto_output_tree_ref to determine if the given tree node
+     should be emitted as a reference to the table of declarations
+     (the same table that holds global declarations).  */
+  bool (*indexable_with_decls_p) (tree);
+
+  /* [OPT] Called by pack_value_fields to store any non-pointer fields
+     in the tree structure.  The arguments are as in pack_value_fields.  */
+  void (*pack_value_fields) (struct bitpack_d *, tree);
+
+  /* [OPT] Called by unpack_value_fields to retrieve any non-pointer fields
+     in the tree structure.  The arguments are as in unpack_value_fields.  */
+  void (*unpack_value_fields) (struct bitpack_d *, tree);
+
+  /* [OPT] Called by lto_materialize_tree for tree nodes that it does not
+     know how to allocate memory for.  If defined, this hook should
+     return a new tree node of the given code.  The data_in and
+     input_block arguments are passed in case the hook needs to
+     read more data from the stream to allocate the node.
+     If this hook returns NULL, then lto_materialize_tree will attempt
+     to allocate the tree by calling make_node directly.  */
+  tree (*alloc_tree) (enum tree_code, struct lto_input_block *,
+                      struct data_in *);
+
+  /* [OPT] Called by lto_output_tree_header to write any streamer-specific
+     information needed to allocate the tree.  This hook may assume
+     that the basic header data (tree code, etc) has already been
+     written.  It should only write any extra data needed to allocate
+     the node (e.g., in the case of CALL_EXPR, this hook would write
+     the number of arguments to the CALL_EXPR).  */
+  void (*output_tree_header) (struct output_block *, tree);
+};
+
+/* Streamer hooks.  */
+extern struct streamer_hooks streamer_hooks;
+
 /* In lto-section-in.c  */
 extern struct lto_input_block * lto_create_simple_input_block (
                               struct lto_file_decl_data *,
@@ -851,17 +937,20 @@ extern intptr_t lto_orig_address_get (tree);
 extern void lto_orig_address_remove (tree);
 #endif
 extern void lto_check_version (int, int);
-
+extern void lto_streamer_hooks_init (void);
+extern void lto_streamer_write_tree (struct output_block *, tree, bool);
+extern void lto_streamer_read_tree (struct lto_input_block *,
+                                    struct data_in *, tree);
+extern void streamer_hooks_init (void);
 
 /* In lto-streamer-in.c */
 extern void lto_input_cgraph (struct lto_file_decl_data *, const char *);
-extern void lto_init_reader (void);
+extern void lto_reader_init (void);
 extern tree lto_input_tree (struct lto_input_block *, struct data_in *);
 extern void lto_input_function_body (struct lto_file_decl_data *, tree,
                                     const char *);
 extern void lto_input_constructors_and_inits (struct lto_file_decl_data *,
                                              const char *);
-extern void lto_init_reader (void);
 extern struct data_in *lto_data_in_create (struct lto_file_decl_data *,
                                    const char *, unsigned,
                                    VEC(ld_plugin_symbol_resolution_t,heap) *);
@@ -1063,31 +1152,6 @@ lto_stream_as_builtin_p (tree expr)
              || DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD));
 }
 
-/* Return true if EXPR is a tree node that can be written to disk.  */
-static inline bool
-lto_is_streamable (tree expr)
-{
-  enum tree_code code = TREE_CODE (expr);
-
-  /* Notice that we reject SSA_NAMEs as well.  We only emit the SSA
-     name version in lto_output_tree_ref (see output_ssa_names).  */
-  return !is_lang_specific (expr)
-        && code != SSA_NAME
-        && code != CALL_EXPR
-        && code != LANG_TYPE
-        && code != MODIFY_EXPR
-        && code != INIT_EXPR
-        && code != TARGET_EXPR
-        && code != BIND_EXPR
-        && code != WITH_CLEANUP_EXPR
-        && code != STATEMENT_LIST
-        && code != OMP_CLAUSE
-        && code != OPTIMIZATION_NODE
-        && (code == CASE_LABEL_EXPR
-            || code == DECL_EXPR
-            || TREE_CODE_CLASS (code) != tcc_statement);
-}
-
 DEFINE_DECL_STREAM_FUNCS (TYPE, type)
 DEFINE_DECL_STREAM_FUNCS (FIELD_DECL, field_decl)
 DEFINE_DECL_STREAM_FUNCS (FN_DECL, fn_decl)
index b247dbbdd0758b5d969b55ff84649b3ea589437e..e8393c1f523762f8e150b69500529edeaddbe2e0 100644 (file)
@@ -1,3 +1,8 @@
+2011-06-04  Diego Novillo  <dnovillo@google.com>
+
+       * lto.c (lto_init): New.
+       (lto_main): Call it.
+
 2011-06-03  Diego Novillo  <dnovillo@google.com>
 
        * lto.c (get_resolution): Move from lto-streamer-in.c.
index 70d5bdee4580119900d734f092fa293fef9dbe20..74dfecdbc3e6028c0b5aa2bc0270cce8e31180f4 100644 (file)
@@ -2732,6 +2732,21 @@ lto_process_name (void)
     setproctitle ("lto1-ltrans");
 }
 
+
+/* Initialize the LTO front end.  */
+
+static void
+lto_init (void)
+{
+  lto_process_name ();
+  lto_streamer_hooks_init ();
+  lto_reader_init ();
+  memset (&lto_stats, 0, sizeof (lto_stats));
+  bitmap_obstack_initialize (NULL);
+  gimple_register_cfg_hooks ();
+}
+
+
 /* Main entry point for the GIMPLE front end.  This front end has
    three main personalities:
 
@@ -2755,9 +2770,8 @@ lto_process_name (void)
 void
 lto_main (void)
 {
-  lto_process_name ();
-
-  lto_init_reader ();
+  /* Initialize the LTO front end.  */
+  lto_init ();
 
   /* Read all the symbols and call graph from all the files in the
      command line.  */