This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[lto][patch] Move input_cgraph to lto/lto-lang.c
- From: "Rafael Espindola" <espindola at google dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Cc: "Diego Novillo" <dnovillo at google dot com>
- Date: Mon, 6 Oct 2008 18:25:09 +0100
- Subject: [lto][patch] Move input_cgraph to lto/lto-lang.c
This patch moves the cgraph reading to lto/lto-lang.c so that in the
next patch I can change it to use functions defined in lto/*.
gcc/
2008-10-06 Rafael Espindola <espindola@google.com>
* cgraph.h (LTO_cgraph_tags, LCC_NOT_FOUND): Moved from lto-cgraph.c.
(LTO_cgraph_tag_names): declare.
* langhooks-def.h (lhd_input_cgraph, LANG_HOOKS_INPUT_CGRAPH): New.
(LANG_HOOKS_LTO): Add LANG_HOOKS_INPUT_CGRAPH.
* langhooks.c (lhd_input_cgraph): New.
* langhooks.h (lang_hooks_for_lto): Add input_cgraph.
* lto-cgraph.c (LTO_cgraph_tags, LCC_NOT_FOUND, input_overwrite_node,
input_node, input_edge, input_cgraph_1): Remove.
(LTO_cgraph_tag_names): Make in non-statitc.
(input_cgraph): Just call lang_hooks.lto.input_cgraph.
gcc/lto/
2008-10-06 Rafael Espindola <espindola@google.com>
* lto-lang.c: Include cgraph.h.
(input_overwrite_node, input_node, input_edge, input_cgraph_1,
input_cgraph): Moved from lto-cgraph.c.
(LANG_HOOKS_INPUT_CGRAPH): New.
Cheers,
--
Rafael Avila de Espindola
Google | Gordon House | Barrow Street | Dublin 4 | Ireland
Registered in Dublin, Ireland | Registration Number: 368047
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 90b5dd9..5020843 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -599,4 +599,20 @@ unsigned int compute_inline_parameters (struct cgraph_node *);
/* Create a new static variable of type TYPE. */
tree add_new_static_var (tree type);
+/* lto-cgraph.c */
+
+enum LTO_cgraph_tags
+{
+ /* Must leave 0 for the stopper. */
+ LTO_cgraph_avail_node = 1,
+ LTO_cgraph_overwritable_node,
+ LTO_cgraph_unavail_node,
+ LTO_cgraph_edge,
+ LTO_cgraph_last_tag
+};
+
+extern const char * LTO_cgraph_tag_names[LTO_cgraph_last_tag];
+
+#define LCC_NOT_FOUND (-1)
+
#endif /* GCC_CGRAPH_H */
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index b492a3a..88f1061 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -228,15 +228,18 @@ extern tree lhd_make_node (enum tree_code);
extern void lhd_begin_section (const char *);
extern void lhd_append_data (const void *, size_t, void *);
extern void lhd_end_section (void);
+extern void lhd_input_cgraph (void);
#define LANG_HOOKS_BEGIN_SECTION lhd_begin_section
#define LANG_HOOKS_APPEND_DATA lhd_append_data
#define LANG_HOOKS_END_SECTION lhd_end_section
+#define LANG_HOOKS_INPUT_CGRAPH lhd_input_cgraph
#define LANG_HOOKS_LTO { \
LANG_HOOKS_BEGIN_SECTION, \
LANG_HOOKS_APPEND_DATA, \
- LANG_HOOKS_END_SECTION \
+ LANG_HOOKS_END_SECTION, \
+ LANG_HOOKS_INPUT_CGRAPH \
}
/* The whole thing. The structure is defined in langhooks.h. */
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 262d11a..978e1c0 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -647,3 +647,9 @@ lhd_end_section (void)
saved_section = NULL;
}
}
+
+void
+lhd_input_cgraph (void)
+{
+ gcc_unreachable ();
+}
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 825dd0c..d3f2b2e 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -235,6 +235,9 @@ struct lang_hooks_for_lto
/* End the previously begun LTO section. */
void (*end_section) (void);
+
+ /* Read cgraph. */
+ void (*input_cgraph) (void);
};
/* Language-specific hooks. See langhooks-def.h for defaults. */
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 085c6aa..12fad49 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -74,16 +74,6 @@ Boston, MA 02110-1301, USA. */
is used to decode references to ndoes in the stream.
*/
-enum LTO_cgraph_tags
-{
- /* Must leave 0 for the stopper. */
- LTO_cgraph_avail_node = 1,
- LTO_cgraph_overwritable_node,
- LTO_cgraph_unavail_node,
- LTO_cgraph_edge,
- LTO_cgraph_last_tag
-};
-
struct lto_cgraph_encoder_def
{
struct pointer_map_t *map; /* Map nodes to reference number. */
@@ -91,8 +81,6 @@ struct lto_cgraph_encoder_def
};
typedef struct lto_cgraph_encoder_def *lto_cgraph_encoder_t;
-#define LCC_NOT_FOUND (-1)
-
/* Create a new encoder. */
static lto_cgraph_encoder_t
@@ -164,7 +152,7 @@ lto_cgraph_encoder_size (lto_cgraph_encoder_t encoder)
}
#ifdef LTO_STREAM_DEBUGGING
-static const char * LTO_cgraph_tag_names[LTO_cgraph_last_tag] =
+const char * LTO_cgraph_tag_names[LTO_cgraph_last_tag] =
{"", "avail", "overwrite", "unavail", "edge"};
#endif
@@ -468,279 +456,13 @@ output_cgraph (cgraph_node_set set)
}
-/* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS,
- STACK_SIZE and SELF_INSNS. This is called either to initialize
- NODE or to replace the values in it, for instance becasue the first
- time we saw it, the function body was not available but now it
- is. */
-
-static void
-input_overwrite_node (struct lto_file_decl_data* file_data,
- struct cgraph_node *node,
- enum LTO_cgraph_tags tag,
- unsigned HOST_WIDEST_INT flags,
- unsigned int stack_size,
- unsigned int self_insns)
-{
- node->aux = (void *)tag;
- node->local.inline_summary.estimated_self_stack_size = stack_size;
- node->local.inline_summary.self_insns = self_insns;
- node->global.insns = self_insns;
- node->local.lto_file_data = file_data;
-
- /* This list must be in the reverse order that they are set in
- output_node. */
- node->local.vtable_method = lto_get_flag (&flags);
- node->local.for_functions_valid = lto_get_flag (&flags);
- node->local.redefined_extern_inline = lto_get_flag (&flags);
- node->local.disregard_inline_limits = lto_get_flag (&flags);
- node->local.inlinable = lto_get_flag (&flags);
- node->local.finalized = lto_get_flag (&flags);
- node->local.externally_visible = lto_get_flag (&flags);
- node->local.local = lto_get_flag (&flags);
- node->needed = lto_get_flag (&flags);
- node->analyzed = node->local.finalized;
- node->lowered = node->local.finalized;
- if (cgraph_decide_is_function_needed (node))
- cgraph_mark_needed_node (node);
-}
-
-/* Read a node from input_block IB. TAG is the node's tag just read.
- Return the node read or overwriten. NODES points to a vector of nodes
- read so far. */
-
-static struct cgraph_node *
-input_node (struct lto_file_decl_data* file_data,
- struct lto_input_block *ib,
- enum LTO_cgraph_tags tag,
- VEC(cgraph_node_ptr, heap) *nodes)
-{
- tree fn_decl;
- struct cgraph_node *node, *master_clone;
- unsigned int flags;
- int stack_size = 0;
- int self_insns = 0;
- unsigned decl_index;
- bool clone_p;
- bool overwrite_p = false;
- int estimated_stack_size = 0;
- int stack_frame_offset = 0;
- int ref = LCC_NOT_FOUND;
- int insns = 0;
- int estimated_growth = 0;
- bool inlined = false;
-
- LTO_DEBUG_TOKEN ("clone_p");
- clone_p = lto_input_uleb128 (ib);
-
- if (clone_p)
- {
- LTO_DEBUG_TOKEN ("master");
- master_clone = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
- gcc_assert (master_clone);
- node = cgraph_clone_input_node (master_clone);
- }
- else
- {
- decl_index = lto_input_uleb128 (ib);
- fn_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index);
- LTO_DEBUG_FN_NAME (fn_decl);
- node = cgraph_node (fn_decl);
- }
-
- LTO_DEBUG_TOKEN ("flags");
- flags = lto_input_uleb128 (ib);
-
- if (tag == LTO_cgraph_avail_node)
- {
- LTO_DEBUG_TOKEN ("stack_size");
- stack_size = lto_input_sleb128 (ib);
- LTO_DEBUG_TOKEN ("self_insns");
- self_insns = lto_input_sleb128 (ib);
- }
-
- /* Read additional global data for LTRANS. */
- if (flag_ltrans)
- {
- LTO_DEBUG_TOKEN ("estimated_stack_size");
- estimated_stack_size = lto_input_sleb128 (ib);
- LTO_DEBUG_TOKEN ("stack_frame_offset");
- stack_frame_offset = lto_input_sleb128 (ib);
- LTO_DEBUG_TOKEN ("inlined_to");
- ref = lto_input_sleb128 (ib);
-
- LTO_DEBUG_TOKEN ("insns");
- insns = lto_input_sleb128 (ib);
- LTO_DEBUG_TOKEN ("estimated_growth");
- estimated_growth = lto_input_sleb128 (ib);
- LTO_DEBUG_TOKEN ("inlined");
- inlined = lto_input_uleb128 (ib);
- }
-
- switch (tag)
- {
- case LTO_cgraph_avail_node:
- /* We cannot have two avail functions that are the same. */
- gcc_assert (((enum LTO_cgraph_tags)(node->aux))
- != LTO_cgraph_avail_node);
- overwrite_p = true;
- break;
-
- case LTO_cgraph_unavail_node:
- /* We only overwrite the node if this is a brand new node. */
- if (!node->aux)
- overwrite_p = true;
- break;
-
- case LTO_cgraph_overwritable_node:
- /* FIXME lto: This code is written to take the last
- overwrittable version. I do not speak linker but if the
- linker supposed to take the first one, then we need to
- change the test. */
- if (((enum LTO_cgraph_tags)(node->aux)) != LTO_cgraph_avail_node)
- overwrite_p = true;
- break;
-
- default:
- gcc_unreachable ();
- }
-
- if (overwrite_p)
- {
- input_overwrite_node (file_data, node, tag, flags, stack_size,
- self_insns);
- if (flag_ltrans)
- {
- node->global.estimated_stack_size = estimated_stack_size;
- node->global.stack_frame_offset = stack_frame_offset;
- node->global.insns = insns;
- if (ref != LCC_NOT_FOUND)
- node->global.inlined_to = VEC_index (cgraph_node_ptr, nodes, ref);
- else
- node->global.inlined_to = NULL;
- node->global.estimated_growth = estimated_growth;
- node->global.inlined = inlined;
- }
- }
-
- return node;
-}
-
-/* Read an edge from IB. NODES points to a vector of previously read
- nodes for decoding caller and callee of the edge to be read. */
-
-static void
-input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes)
-{
- struct cgraph_node *caller, *callee;
- struct cgraph_edge *edge;
- unsigned int stmt_id;
- unsigned int count;
- unsigned int freq;
- unsigned int nest;
- cgraph_inline_failed_t inline_failed;
- unsigned HOST_WIDEST_INT flags;
-
- LTO_DEBUG_TOKEN ("caller");
- caller = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
- gcc_assert (caller);
-
- LTO_DEBUG_TOKEN ("callee");
- callee = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
- gcc_assert (callee);
-
- LTO_DEBUG_TOKEN ("stmt");
- stmt_id = lto_input_uleb128 (ib);
- LTO_DEBUG_TOKEN ("inline_failed");
- inline_failed = lto_input_uleb128 (ib);
- LTO_DEBUG_TOKEN ("count");
- count = lto_input_uleb128 (ib);
- LTO_DEBUG_TOKEN ("frequency");
- freq = lto_input_uleb128 (ib);
- LTO_DEBUG_TOKEN ("loop_next");
- nest = lto_input_uleb128 (ib);
- LTO_DEBUG_TOKEN ("flags");
- flags = lto_input_uleb128 (ib);
-
- edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest);
- edge->lto_stmt_uid = stmt_id;
- edge->inline_failed = inline_failed;
-
- /* This list must be in the reverse order that they are set in
- output_edge. */
- edge->call_stmt_cannot_inline_p = lto_get_flag (&flags);
- edge->indirect_call = lto_get_flag (&flags);
-}
-
-/* Input a cgraph from IB using the info in FILE_DATA. */
-
-static void
-input_cgraph_1 (struct lto_file_decl_data* file_data,
- struct lto_input_block *ib)
-{
- enum LTO_cgraph_tags tag;
- VEC(cgraph_node_ptr, heap) *nodes = NULL;
- struct cgraph_node *node;
-
- tag = lto_input_uleb128 (ib);
- while (tag)
- {
- LTO_DEBUG_INDENT (tag);
-
- if (tag == LTO_cgraph_edge)
- input_edge (ib, nodes);
- else
- {
- node = input_node (file_data, ib, tag, nodes);
- VEC_safe_push (cgraph_node_ptr, heap, nodes, node);
- }
-
- LTO_DEBUG_UNDENT();
- tag = lto_input_uleb128 (ib);
- }
-
- VEC_free (cgraph_node_ptr, heap, nodes);
-}
-
-
/* Input and merge the cgraph from each of the .o files passed to
lto1. */
static void
input_cgraph (void)
{
- struct lto_file_decl_data ** file_data_vec
- = lto_get_file_decl_data ();
- struct lto_file_decl_data * file_data;
- unsigned int j = 0;
- struct cgraph_node *node;
-
-#ifdef LTO_STREAM_DEBUGGING
- lto_debug_context.tag_names = LTO_cgraph_tag_names;
- lto_debug_context.stream_name = "cgraph";
-#endif
-
- while ((file_data = file_data_vec[j++]))
- {
- const char *data;
- size_t len;
- struct lto_input_block *ib
- = lto_create_simple_input_block (file_data,
- LTO_section_cgraph,
- &data, &len);
- input_cgraph_1 (file_data, ib);
- lto_destroy_simple_input_block (file_data,
- LTO_section_cgraph,
- ib, data, len);
- }
-
- /* Clear out the aux field that was used to store enough state to
- tell which nodes should be overwritten. */
- for (node = cgraph_nodes; node; node = node->next)
- {
- gcc_assert (node->local.lto_file_data);
- node->aux = NULL;
- }
+ lang_hooks.lto.input_cgraph ();
}
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index f936c67..7dfcdc2 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -37,6 +37,7 @@ Boston, MA 02110-1301, USA. */
#include "toplev.h"
#include "libfuncs.h"
#include "except.h"
+#include "cgraph.h"
static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
static tree handle_const_attribute (tree *, tree, tree, int, bool *);
@@ -1064,6 +1065,281 @@ static void lto_init_ts (void)
tree_contains_struct[NAMESPACE_DECL][TS_DECL_MINIMAL] = 1;
}
+
+/* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS,
+ STACK_SIZE and SELF_INSNS. This is called either to initialize
+ NODE or to replace the values in it, for instance becasue the first
+ time we saw it, the function body was not available but now it
+ is. */
+
+static void
+input_overwrite_node (struct lto_file_decl_data* file_data,
+ struct cgraph_node *node,
+ enum LTO_cgraph_tags tag,
+ unsigned HOST_WIDEST_INT flags,
+ unsigned int stack_size,
+ unsigned int self_insns)
+{
+ node->aux = (void *)tag;
+ node->local.inline_summary.estimated_self_stack_size = stack_size;
+ node->local.inline_summary.self_insns = self_insns;
+ node->global.insns = self_insns;
+ node->local.lto_file_data = file_data;
+
+ /* This list must be in the reverse order that they are set in
+ output_node. */
+ node->local.vtable_method = lto_get_flag (&flags);
+ node->local.for_functions_valid = lto_get_flag (&flags);
+ node->local.redefined_extern_inline = lto_get_flag (&flags);
+ node->local.disregard_inline_limits = lto_get_flag (&flags);
+ node->local.inlinable = lto_get_flag (&flags);
+ node->local.finalized = lto_get_flag (&flags);
+ node->local.externally_visible = lto_get_flag (&flags);
+ node->local.local = lto_get_flag (&flags);
+ node->needed = lto_get_flag (&flags);
+ node->analyzed = node->local.finalized;
+ node->lowered = node->local.finalized;
+ if (cgraph_decide_is_function_needed (node))
+ cgraph_mark_needed_node (node);
+}
+
+/* Read a node from input_block IB. TAG is the node's tag just read.
+ Return the node read or overwriten. NODES points to a vector of nodes
+ read so far. */
+
+static struct cgraph_node *
+input_node (struct lto_file_decl_data* file_data,
+ struct lto_input_block *ib,
+ enum LTO_cgraph_tags tag,
+ VEC(cgraph_node_ptr, heap) *nodes)
+{
+ tree fn_decl;
+ struct cgraph_node *node, *master_clone;
+ unsigned int flags;
+ int stack_size = 0;
+ int self_insns = 0;
+ unsigned decl_index;
+ bool clone_p;
+ bool overwrite_p = false;
+ int estimated_stack_size = 0;
+ int stack_frame_offset = 0;
+ int ref = LCC_NOT_FOUND;
+ int insns = 0;
+ int estimated_growth = 0;
+ bool inlined = false;
+
+ LTO_DEBUG_TOKEN ("clone_p");
+ clone_p = lto_input_uleb128 (ib);
+
+ if (clone_p)
+ {
+ LTO_DEBUG_TOKEN ("master");
+ master_clone = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
+ gcc_assert (master_clone);
+ node = cgraph_clone_input_node (master_clone);
+ }
+ else
+ {
+ decl_index = lto_input_uleb128 (ib);
+ fn_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index);
+ LTO_DEBUG_FN_NAME (fn_decl);
+ node = cgraph_node (fn_decl);
+ }
+
+ LTO_DEBUG_TOKEN ("flags");
+ flags = lto_input_uleb128 (ib);
+
+ if (tag == LTO_cgraph_avail_node)
+ {
+ LTO_DEBUG_TOKEN ("stack_size");
+ stack_size = lto_input_sleb128 (ib);
+ LTO_DEBUG_TOKEN ("self_insns");
+ self_insns = lto_input_sleb128 (ib);
+ }
+
+ /* Read additional global data for LTRANS. */
+ if (flag_ltrans)
+ {
+ LTO_DEBUG_TOKEN ("estimated_stack_size");
+ estimated_stack_size = lto_input_sleb128 (ib);
+ LTO_DEBUG_TOKEN ("stack_frame_offset");
+ stack_frame_offset = lto_input_sleb128 (ib);
+ LTO_DEBUG_TOKEN ("inlined_to");
+ ref = lto_input_sleb128 (ib);
+
+ LTO_DEBUG_TOKEN ("insns");
+ insns = lto_input_sleb128 (ib);
+ LTO_DEBUG_TOKEN ("estimated_growth");
+ estimated_growth = lto_input_sleb128 (ib);
+ LTO_DEBUG_TOKEN ("inlined");
+ inlined = lto_input_uleb128 (ib);
+ }
+
+ switch (tag)
+ {
+ case LTO_cgraph_avail_node:
+ /* We cannot have two avail functions that are the same. */
+ gcc_assert (((enum LTO_cgraph_tags)(node->aux))
+ != LTO_cgraph_avail_node);
+ overwrite_p = true;
+ break;
+
+ case LTO_cgraph_unavail_node:
+ /* We only overwrite the node if this is a brand new node. */
+ if (!node->aux)
+ overwrite_p = true;
+ break;
+
+ case LTO_cgraph_overwritable_node:
+ /* FIXME lto: This code is written to take the last
+ overwrittable version. I do not speak linker but if the
+ linker supposed to take the first one, then we need to
+ change the test. */
+ if (((enum LTO_cgraph_tags)(node->aux)) != LTO_cgraph_avail_node)
+ overwrite_p = true;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (overwrite_p)
+ {
+ input_overwrite_node (file_data, node, tag, flags, stack_size,
+ self_insns);
+ if (flag_ltrans)
+ {
+ node->global.estimated_stack_size = estimated_stack_size;
+ node->global.stack_frame_offset = stack_frame_offset;
+ node->global.insns = insns;
+ if (ref != LCC_NOT_FOUND)
+ node->global.inlined_to = VEC_index (cgraph_node_ptr, nodes, ref);
+ else
+ node->global.inlined_to = NULL;
+ node->global.estimated_growth = estimated_growth;
+ node->global.inlined = inlined;
+ }
+ }
+
+ return node;
+}
+
+/* Read an edge from IB. NODES points to a vector of previously read
+ nodes for decoding caller and callee of the edge to be read. */
+
+static void
+input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes)
+{
+ struct cgraph_node *caller, *callee;
+ struct cgraph_edge *edge;
+ unsigned int stmt_id;
+ unsigned int count;
+ unsigned int freq;
+ unsigned int nest;
+ cgraph_inline_failed_t inline_failed;
+ unsigned HOST_WIDEST_INT flags;
+
+ LTO_DEBUG_TOKEN ("caller");
+ caller = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
+ gcc_assert (caller);
+
+ LTO_DEBUG_TOKEN ("callee");
+ callee = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
+ gcc_assert (callee);
+
+ LTO_DEBUG_TOKEN ("stmt");
+ stmt_id = lto_input_uleb128 (ib);
+ LTO_DEBUG_TOKEN ("inline_failed");
+ inline_failed = lto_input_uleb128 (ib);
+ LTO_DEBUG_TOKEN ("count");
+ count = lto_input_uleb128 (ib);
+ LTO_DEBUG_TOKEN ("frequency");
+ freq = lto_input_uleb128 (ib);
+ LTO_DEBUG_TOKEN ("loop_next");
+ nest = lto_input_uleb128 (ib);
+ LTO_DEBUG_TOKEN ("flags");
+ flags = lto_input_uleb128 (ib);
+
+ edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest);
+ edge->lto_stmt_uid = stmt_id;
+ edge->inline_failed = inline_failed;
+
+ /* This list must be in the reverse order that they are set in
+ output_edge. */
+ edge->call_stmt_cannot_inline_p = lto_get_flag (&flags);
+ edge->indirect_call = lto_get_flag (&flags);
+}
+
+/* Input a cgraph from IB using the info in FILE_DATA. */
+
+static void
+input_cgraph_1 (struct lto_file_decl_data* file_data,
+ struct lto_input_block *ib)
+{
+ enum LTO_cgraph_tags tag;
+ VEC(cgraph_node_ptr, heap) *nodes = NULL;
+ struct cgraph_node *node;
+
+ tag = lto_input_uleb128 (ib);
+ while (tag)
+ {
+ LTO_DEBUG_INDENT (tag);
+
+ if (tag == LTO_cgraph_edge)
+ input_edge (ib, nodes);
+ else
+ {
+ node = input_node (file_data, ib, tag, nodes);
+ VEC_safe_push (cgraph_node_ptr, heap, nodes, node);
+ }
+
+ LTO_DEBUG_UNDENT();
+ tag = lto_input_uleb128 (ib);
+ }
+
+ VEC_free (cgraph_node_ptr, heap, nodes);
+}
+
+/* Input and merge the cgraph from each of the .o files passed to
+ lto1. */
+
+static void
+input_cgraph (void)
+{
+ struct lto_file_decl_data ** file_data_vec
+ = lto_get_file_decl_data ();
+ struct lto_file_decl_data * file_data;
+ unsigned int j = 0;
+ struct cgraph_node *node;
+
+#ifdef LTO_STREAM_DEBUGGING
+ lto_debug_context.tag_names = LTO_cgraph_tag_names;
+ lto_debug_context.stream_name = "cgraph";
+#endif
+
+ while ((file_data = file_data_vec[j++]))
+ {
+ const char *data;
+ size_t len;
+ struct lto_input_block *ib
+ = lto_create_simple_input_block (file_data,
+ LTO_section_cgraph,
+ &data, &len);
+ input_cgraph_1 (file_data, ib);
+ lto_destroy_simple_input_block (file_data,
+ LTO_section_cgraph,
+ ib, data, len);
+ }
+
+ /* Clear out the aux field that was used to store enough state to
+ tell which nodes should be overwritten. */
+ for (node = cgraph_nodes; node; node = node->next)
+ {
+ gcc_assert (node->local.lto_file_data);
+ node->aux = NULL;
+ }
+}
+
#undef LANG_HOOKS_NAME
#define LANG_HOOKS_NAME "GNU GIMPLE"
#undef LANG_HOOKS_INIT_OPTIONS
@@ -1115,6 +1391,8 @@ static void lto_init_ts (void)
#define LANG_HOOKS_APPEND_DATA lto_elf_append_data
#undef LANG_HOOKS_END_SECTION
#define LANG_HOOKS_END_SECTION lto_elf_end_section
+#undef LANG_HOOKS_INPUT_CGRAPH
+#define LANG_HOOKS_INPUT_CGRAPH input_cgraph
#undef LANG_HOOKS_INIT_TS
#define LANG_HOOKS_INIT_TS lto_init_ts