aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Zadeck <zadeck@naturalbridge.com>2008-02-10 04:03:15 +0000
committerKenneth Zadeck <zadeck@naturalbridge.com>2008-02-10 04:03:15 +0000
commitbdc903d3f1d7f78c975865fa35da936496479200 (patch)
treeacc898ad40137913ab9e29039cc890eead4d542d
parent8c87bf47da20e1c7f16ff707bb40c16971abaaf4 (diff)
2008-02-09 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto.c (lto_read_variable_formal_parameter_const): Remove code to reconstruct static initializers. (lto_get_body, lto_materialize_function): Add lto_section_type as a parameter. (lto_materialize_constructors_and_inits, lto_materialize_file_data): New function. (lto_materialize_function, lto_read_subroutine_type_subprogram_DIE): Renamed unmap_fn_body to unmap_section and map_fn_body to map_section. (lto_set_cu_context): Process functions and static inits differently. * Make-lang.in (LTO_H, lto/lto-function-in.o, lto/lto-section-in.o): Update dependencies. * lto/lto-elf.c (lto_elf_map_optional_lto_section): Add lto_section_type parameter. (lto_elf_unmap_fn_body): Renamed to lto_elf_unmap_section. * lto.h (lto_file_vtable_struct): Removed two of the fields and renamed the other two so that there is only one map function and one unmap function and each takes a section type parameter. (lto_read_function_body): Renamed to lto_input_function_body and added file_data parameter. (lto_read_var_init): Removed. (lto_input_constructors_and_inits): New function. * lto-section-in.c (lto_read_decls): New function. * lto-function-in.c (data_in): Moved fields field_decls, fn_decls, var_decls, type_decls, types to lto_file_decl_data. (input_type_ref, input_expr_operand, lto_read_body): Get field_decls, fn_decls, var_decls, type_decls, types from different structure. (input_globals, input_constructor, lto_read_var_init): Removed. (input_constructors_or_inits): New function. (lto_read_function_body, lto_input_constructors_and_inits): Renamed to lto_input_function_body and takes file_data parameter. * lto-section-in.h (lto_file_decl_data): New structure. 2008-02-09 Kenneth Zadeck <zadeck@naturalbridge.com> * tree-pass.h: (pass_ipa_lto_out): Renamed to pass_ipa_lto_gimple_out. (pass_ipa_lto_finish_out): New pass. * lto-function-out.c (decl_slot, hash_decl_slot_node, eq_decl_slot_node, hash_type_slot_node, eq_type_slot_node, output_decl_index): Moved to lto-section-out.c, made public and and renamed to have "lto_" prefix. (eq_label_slot_node, hash_label_slot_node): Uses lto_decl_slot rather than decl_slot. (output_block): Deleted these fields: field_decl_hash_table, next_field_decl_index, field_decls, fn_decl_hash_table, next_fn_decl_index, fn_decls, var_decl_hash_table, next_var_decl_index, var_decls, type_decl_hash_table, next_type_decl_index, type_decls, type_hash_table, next_type_index, types. Added cgraph_node and current_stmt_id. (create_output_block): Now takes lto_section_type. Removed code to init hash tables moved to lto_section_out.c. (destroy_output_block): Removed is_function parameter. Removed code to destroy tables moved to lto_section_out.c (output_type_ref, output_local_decl_ref, output_label_ref, output_expr_operand): Modified to call functions moved to lto_section_out. (output_bb): Properly set current_stmt_id. (write_references): Moved to lto_section_out.c. (produce_asm): tripped of all of the function that was moved to lto_section_out.c. (output_constructor_or_init): Renamed output_constructors_and_inits and writes all initializers in a single section rather than one per section. (lto_output): Moved loop over all constructors to output_constructors_and_inits. (gate_lto_out): Moved to lto-section-out.c. * tree-ssa-sccvn.c (init_scc_vn): Removed unused bb var. * lto-header.h (lto_section_type): Changed prefix of all elements to "LTO_section". (lto_get_section_name): New function. (lto_get_section): Move from lto-section.h. (LTO_STREAM_DEBUGGING, LTO_DEBUG_INDENT, LTO_DEBUG_INDENT_TOKEN, LTO_DEBUG_INTEGER, LTO_DEBUG_STRING, LTO_DEBUG_TOKEN, LTO_DEBUG_TREE_FLAGS, LTO_DEBUG_UNDENT, LTO_DEBUG_WIDE, lto_debug_context, lto_debug_out): Moved from lto-tags.h. * lto-section.h: New file. * lto-tags.h (lto_function_header): Moved fields num_field_decls, num_fn_decls, num_var_decls, num_type_decls, num_types. to lto_decl_header in lto-section.h. (LTO_STREAM_DEBUGGING, LTO_DEBUG_INDENT, LTO_DEBUG_INDENT_TOKEN, LTO_DEBUG_INTEGER, LTO_DEBUG_STRING, LTO_DEBUG_TOKEN, LTO_DEBUG_TREE_FLAGS, LTO_DEBUG_UNDENT, LTO_DEBUG_WIDE, lto_debug_context, lto_debug_out): Moved to lto-tags.h. * lto-stream-debug.c: Include lto-header.h. * Makefile.in (LTO_TAGS_H, lto-stream-debug.o, lto-function-out.o, lto-section-out.o): Updated dependencies. (LTO_SECTION_H): New. * passes.c: (pass_ipa_lto_out): Renamed to pass_ipa_lto_gimple_out. (pass_ipa_lto_finish_out): New pass. * lto-section-out.c (lto_hash_decl_slot_node, lto_eq_decl_slot_node, lto_hash_type_slot_node, lto_eq_type_slot_node, lto_output_decl_index): Moved from lto-function-out.c and renamed with "lto_" prefix. (lto_get_section_name, lto_get_out_decl_state, produce_asm_for_decls): New function. (write_references, gate_lto_out): Moved from lto-function-out.c. * lto-section-out.h (lto_out_decl_state): New structure. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/lto@132210 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.lto64
-rw-r--r--gcc/Makefile.in10
-rw-r--r--gcc/lto-function-out.c401
-rw-r--r--gcc/lto-header.h80
-rw-r--r--gcc/lto-section-out.c289
-rw-r--r--gcc/lto-section-out.h51
-rw-r--r--gcc/lto-section.h39
-rw-r--r--gcc/lto-stream-debug.c1
-rw-r--r--gcc/lto-tags.h83
-rw-r--r--gcc/lto/ChangeLog37
-rw-r--r--gcc/lto/Make-lang.in8
-rw-r--r--gcc/lto/lto-elf.c15
-rw-r--r--gcc/lto/lto-function-in.c197
-rw-r--r--gcc/lto/lto-section-in.c76
-rw-r--r--gcc/lto/lto-section-in.h19
-rw-r--r--gcc/lto/lto.c69
-rw-r--r--gcc/lto/lto.h60
-rw-r--r--gcc/passes.c7
-rw-r--r--gcc/tree-pass.h3
-rw-r--r--gcc/tree-ssa-sccvn.c1
20 files changed, 941 insertions, 569 deletions
diff --git a/gcc/ChangeLog.lto b/gcc/ChangeLog.lto
index 0c02a23d57d..1d5fa4d7f0f 100644
--- a/gcc/ChangeLog.lto
+++ b/gcc/ChangeLog.lto
@@ -1,3 +1,67 @@
+2008-02-09 Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ * tree-pass.h: (pass_ipa_lto_out): Renamed to pass_ipa_lto_gimple_out.
+ (pass_ipa_lto_finish_out): New pass.
+ * lto-function-out.c (decl_slot, hash_decl_slot_node, eq_decl_slot_node,
+ hash_type_slot_node, eq_type_slot_node, output_decl_index): Moved to
+ lto-section-out.c, made public and and renamed to have "lto_"
+ prefix.
+ (eq_label_slot_node, hash_label_slot_node): Uses lto_decl_slot rather than
+ decl_slot.
+ (output_block): Deleted these fields: field_decl_hash_table,
+ next_field_decl_index, field_decls, fn_decl_hash_table,
+ next_fn_decl_index, fn_decls, var_decl_hash_table,
+ next_var_decl_index, var_decls, type_decl_hash_table,
+ next_type_decl_index, type_decls, type_hash_table,
+ next_type_index, types.
+ Added cgraph_node and current_stmt_id.
+ (create_output_block): Now takes lto_section_type. Removed code
+ to init hash tables moved to lto_section_out.c.
+ (destroy_output_block): Removed is_function parameter.
+ Removed code to destroy tables moved to lto_section_out.c
+ (output_type_ref, output_local_decl_ref, output_label_ref,
+ output_expr_operand): Modified to call functions moved to lto_section_out.
+ (output_bb): Properly set current_stmt_id.
+ (write_references): Moved to lto_section_out.c.
+ (produce_asm): tripped of all of the function that was moved
+ to lto_section_out.c.
+ (output_constructor_or_init): Renamed
+ output_constructors_and_inits and writes all initializers in a
+ single section rather than one per section.
+ (lto_output): Moved loop over all constructors to
+ output_constructors_and_inits.
+ (gate_lto_out): Moved to lto-section-out.c.
+ * tree-ssa-sccvn.c (init_scc_vn): Removed unused bb var.
+ * lto-header.h (lto_section_type): Changed prefix of all
+ elements to "LTO_section".
+ (lto_get_section_name): New function.
+ (lto_get_section): Move from lto-section.h.
+ (LTO_STREAM_DEBUGGING, LTO_DEBUG_INDENT, LTO_DEBUG_INDENT_TOKEN,
+ LTO_DEBUG_INTEGER, LTO_DEBUG_STRING, LTO_DEBUG_TOKEN,
+ LTO_DEBUG_TREE_FLAGS, LTO_DEBUG_UNDENT, LTO_DEBUG_WIDE,
+ lto_debug_context, lto_debug_out): Moved from lto-tags.h.
+ * lto-section.h: New file.
+ * lto-tags.h (lto_function_header): Moved fields num_field_decls,
+ num_fn_decls, num_var_decls, num_type_decls, num_types. to
+ lto_decl_header in lto-section.h.
+ (LTO_STREAM_DEBUGGING, LTO_DEBUG_INDENT, LTO_DEBUG_INDENT_TOKEN,
+ LTO_DEBUG_INTEGER, LTO_DEBUG_STRING, LTO_DEBUG_TOKEN,
+ LTO_DEBUG_TREE_FLAGS, LTO_DEBUG_UNDENT, LTO_DEBUG_WIDE,
+ lto_debug_context, lto_debug_out): Moved to lto-tags.h.
+ * lto-stream-debug.c: Include lto-header.h.
+ * Makefile.in (LTO_TAGS_H, lto-stream-debug.o, lto-function-out.o,
+ lto-section-out.o): Updated dependencies.
+ (LTO_SECTION_H): New.
+ * passes.c: (pass_ipa_lto_out): Renamed to pass_ipa_lto_gimple_out.
+ (pass_ipa_lto_finish_out): New pass.
+ * lto-section-out.c (lto_hash_decl_slot_node, lto_eq_decl_slot_node,
+ lto_hash_type_slot_node, lto_eq_type_slot_node,
+ lto_output_decl_index): Moved from lto-function-out.c and
+ renamed with "lto_" prefix.
+ (lto_get_section_name, lto_get_out_decl_state, produce_asm_for_decls): New function.
+ (write_references, gate_lto_out): Moved from lto-function-out.c.
+ * lto-section-out.h (lto_out_decl_state): New structure.
+
2008-01-28 Kenneth Zadeck <zadeck@naturalbridge.com>
* cgraph.h (cgraph_edge.lto_stmt_uid): New field.
* lto-function-out.c (output_constructor, output_expr_operand,
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 86d9fc9e916..723de475788 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -839,7 +839,8 @@ TREE_INLINE_H = tree-inline.h $(VARRAY_H) pointer-set.h
REAL_H = real.h $(MACHMODE_H)
DBGCNT_H = dbgcnt.h dbgcnt.def
EBIMAP_H = ebitmap.h sbitmap.h
-LTO_TAGS_H = lto-tags.h tree.h sbitmap.h
+LTO_TAGS_H = lto-tags.h tree.h sbitmap.h lto-header.h
+LTO_SECTION_H = lto-section.h lto-header.h
TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H)
#
@@ -1962,18 +1963,19 @@ double-int.o: double-int.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H)
lto-stream-debug.o : lto-stream-debug.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
toplev.h $(FLAGS_H) $(PARAMS_H) input.h debug.h $(LTO_TAGS_H) \
- lto-tree-flags.def lto-tree-tags.def $(TREE_H)
+ lto-header.h lto-tree-flags.def lto-tree-tags.def $(TREE_H)
lto-function-out.o : lto-function-out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) toplev.h $(TREE_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h \
$(VARRAY_H) $(HASHTAB_H) langhooks.h $(BASIC_BLOCK_H) tree-iterator.h \
tree-pass.h tree-flow.h $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_H) \
except.h debug.h $(TIMEVAR_H) $(LTO_TAGS_H) lto-tree-flags.def lto-tree-tags.def \
- lto-tags.h lto-section-out.h output.h dwarf2asm.h dwarf2out.h
+ lto-tags.h lto-header.h lto-section-out.h output.h dwarf2asm.h dwarf2out.h
lto-section-out.o : lto-section-out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) toplev.h $(TREE_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h \
$(VARRAY_H) $(HASHTAB_H) langhooks.h $(BASIC_BLOCK_H) tree-iterator.h \
tree-pass.h tree-flow.h $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_H) \
- except.h debug.h $(TIMEVAR_H) lto-section-out.h output.h dwarf2asm.h dwarf2out.h
+ except.h debug.h $(TIMEVAR_H) lto-header.h lto-section-out.h output.h \
+ dwarf2asm.h dwarf2out.h
langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) toplev.h $(TREE_INLINE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) \
langhooks.h $(LANGHOOKS_DEF_H) $(FLAGS_H) $(GGC_H) $(DIAGNOSTIC_H) intl.h \
diff --git a/gcc/lto-function-out.c b/gcc/lto-function-out.c
index 32cd9a4459b..2d7df6f4f7a 100644
--- a/gcc/lto-function-out.c
+++ b/gcc/lto-function-out.c
@@ -1,7 +1,7 @@
/* Write the gimple representation of a function and it's local
variables to a .o file.
- Copyright 2006 Free Software Foundation, Inc.
+ Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
This file is part of GCC.
@@ -70,82 +70,29 @@ const char *LTO_tag_names[LTO_last_tag];
static int last_eh_region_seen;
static unsigned int expr_to_tag[NUM_TREE_CODES];
-struct decl_slot {
- tree t;
- int slot_num;
-};
-
-/* Returns a hash code for P. */
-
-static hashval_t
-hash_decl_slot_node (const void *p)
-{
- const struct decl_slot *ds = (const struct decl_slot *) p;
- return (hashval_t) DECL_UID (ds->t);
-}
-
-
/* Returns nonzero if P1 and P2 are equal. */
static int
-eq_decl_slot_node (const void *p1, const void *p2)
+eq_label_slot_node (const void *p1, const void *p2)
{
- const struct decl_slot *ds1 =
- (const struct decl_slot *) p1;
- const struct decl_slot *ds2 =
- (const struct decl_slot *) p2;
+ const struct lto_decl_slot *ds1 =
+ (const struct lto_decl_slot *) p1;
+ const struct lto_decl_slot *ds2 =
+ (const struct lto_decl_slot *) p2;
- return DECL_UID (ds1->t) == DECL_UID (ds2->t);
+ return LABEL_DECL_UID (ds1->t) == LABEL_DECL_UID (ds2->t);
}
-
-/* Returns a hash code for P. */
-
-static hashval_t
-hash_type_slot_node (const void *p)
-{
- const struct decl_slot *ds = (const struct decl_slot *) p;
- return (hashval_t) TYPE_UID (ds->t);
-}
-
-
-/* Returns nonzero if P1 and P2 are equal. */
-
-static int
-eq_type_slot_node (const void *p1, const void *p2)
-{
- const struct decl_slot *ds1 =
- (const struct decl_slot *) p1;
- const struct decl_slot *ds2 =
- (const struct decl_slot *) p2;
-
- return TYPE_UID (ds1->t) == TYPE_UID (ds2->t);
-}
-
-
/* Returns a hash code for P. */
static hashval_t
hash_label_slot_node (const void *p)
{
- const struct decl_slot *ds = (const struct decl_slot *) p;
+ const struct lto_decl_slot *ds = (const struct lto_decl_slot *) p;
return (hashval_t) LABEL_DECL_UID (ds->t);
}
-/* Returns nonzero if P1 and P2 are equal. */
-
-static int
-eq_label_slot_node (const void *p1, const void *p2)
-{
- const struct decl_slot *ds1 =
- (const struct decl_slot *) p1;
- const struct decl_slot *ds2 =
- (const struct decl_slot *) p2;
-
- return LABEL_DECL_UID (ds1->t) == LABEL_DECL_UID (ds2->t);
-}
-
struct string_slot {
const char *s;
@@ -189,6 +136,9 @@ eq_string_slot_node (const void *p1, const void *p2)
struct output_block
{
+ enum lto_section_type section_type;
+ struct lto_out_decl_state *decl_state;
+
/* The stream that the main tree codes are written to. */
struct lto_output_stream *main_stream;
/* The stream that contains the indexes for the local name table. */
@@ -243,40 +193,19 @@ struct output_block
#endif
VEC(tree,heap) *local_decls;
- /* The hash table that contains the set of field_decls we have
- seen so far and the indexes assigned to them. */
- htab_t field_decl_hash_table;
- unsigned int next_field_decl_index;
- VEC(tree,heap) *field_decls;
-
- /* The hash table that contains the set of function_decls we have
- seen so far and the indexes assigned to them. */
- htab_t fn_decl_hash_table;
- unsigned int next_fn_decl_index;
- VEC(tree,heap) *fn_decls;
-
- /* The hash table that contains the set of var_decls we have
- seen so far and the indexes assigned to them. */
- htab_t var_decl_hash_table;
- unsigned int next_var_decl_index;
- VEC(tree,heap) *var_decls;
-
- /* The hash table that contains the set of type_decls we have
- seen so far and the indexes assigned to them. */
- htab_t type_decl_hash_table;
- unsigned int next_type_decl_index;
- VEC(tree,heap) *type_decls;
-
/* The hash table that contains the set of strings we have seen so
far and the indexes assigned to them. */
htab_t string_hash_table;
unsigned int next_string_index;
- /* The hash table that contains the set of type we have seen so far
- and the indexes assigned to them. */
- htab_t type_hash_table;
- unsigned int next_type_index;
- VEC(tree,heap) *types;
+
+ /* The current cgraph_node that we are currently serializing. Null
+ if we are serializing something else. */
+ struct cgraph_node *cgraph_node;
+
+ /* The current stmt_uid of the statement we are serializing. -1 if
+ we are not serializing a statement. */
+ int current_stmt_uid;
/* These are the last file and line that were seen in the stream.
If the current node differs from these, it needs to insert
@@ -306,17 +235,20 @@ clear_line_info (struct output_block *ob)
}
-/* Create the output block and return it. IS_FUNTION is true if this
- is for a function and false for a constructor. */
+/* Create the output block and return it. SECTION_TYPE is LTO_section_function_body or
+lto_static_initializer. */
static struct output_block *
-create_output_block (bool is_function)
+create_output_block (enum lto_section_type section_type)
{
struct output_block *ob = xcalloc (1, sizeof (struct output_block));
+ ob->section_type = section_type;
ob->main_stream = xcalloc (1, sizeof (struct lto_output_stream));
ob->string_stream = xcalloc (1, sizeof (struct lto_output_stream));
- if (is_function)
+ ob->decl_state = lto_get_out_decl_state ();
+
+ if (section_type == LTO_section_function_body)
{
ob->local_decl_index_stream = xcalloc (1, sizeof (struct lto_output_stream));
ob->local_decl_stream = xcalloc (1, sizeof (struct lto_output_stream));
@@ -331,26 +263,16 @@ create_output_block (bool is_function)
clear_line_info (ob);
- if (is_function)
+ if (section_type == LTO_section_function_body)
{
ob->label_hash_table
= htab_create (37, hash_label_slot_node, eq_label_slot_node, free);
ob->local_decl_hash_table
- = htab_create (37, hash_decl_slot_node, eq_decl_slot_node, free);
+ = htab_create (37, lto_hash_decl_slot_node, lto_eq_decl_slot_node, free);
}
- ob->field_decl_hash_table
- = htab_create (37, hash_decl_slot_node, eq_decl_slot_node, free);
- ob->fn_decl_hash_table
- = htab_create (37, hash_decl_slot_node, eq_decl_slot_node, free);
- ob->var_decl_hash_table
- = htab_create (37, hash_decl_slot_node, eq_decl_slot_node, free);
- ob->type_decl_hash_table
- = htab_create (37, hash_decl_slot_node, eq_decl_slot_node, free);
ob->string_hash_table
= htab_create (37, hash_string_slot_node, eq_string_slot_node, free);
- ob->type_hash_table
- = htab_create (37, hash_type_slot_node, eq_type_slot_node, free);
/* The unnamed labels must all be negative. */
ob->next_unnamed_label_index = -1;
@@ -358,27 +280,23 @@ create_output_block (bool is_function)
}
-/* Destroy the output block OB. IS_FUNTION is true if this is for a
- function and false for a constructor. */
+/* Destroy the output block OB. */
static void
-destroy_output_block (struct output_block * ob, bool is_function)
+destroy_output_block (struct output_block * ob)
{
- if (is_function)
+ enum lto_section_type section_type = ob->section_type;
+
+ if (section_type == LTO_section_function_body)
{
htab_delete (ob->label_hash_table);
htab_delete (ob->local_decl_hash_table);
}
- htab_delete (ob->field_decl_hash_table);
- htab_delete (ob->fn_decl_hash_table);
- htab_delete (ob->var_decl_hash_table);
- htab_delete (ob->type_decl_hash_table);
htab_delete (ob->string_hash_table);
- htab_delete (ob->type_hash_table);
free (ob->main_stream);
free (ob->string_stream);
- if (is_function)
+ if (section_type == LTO_section_function_body)
{
free (ob->local_decl_index_stream);
free (ob->local_decl_stream);
@@ -388,7 +306,7 @@ destroy_output_block (struct output_block * ob, bool is_function)
}
LTO_CLEAR_DEBUGGING_STREAM (debug_main_stream);
- if (is_function)
+ if (section_type == LTO_section_function_body)
{
LTO_CLEAR_DEBUGGING_STREAM (debug_label_stream);
LTO_CLEAR_DEBUGGING_STREAM (debug_ssa_names_stream);
@@ -397,7 +315,7 @@ destroy_output_block (struct output_block * ob, bool is_function)
LTO_CLEAR_DEBUGGING_STREAM (debug_decl_index_stream);
}
- if (is_function)
+ if (section_type == LTO_section_function_body)
{
VEC_free (int, heap, ob->local_decls_index);
VEC_free (int, heap, ob->unexpanded_local_decls_index);
@@ -407,10 +325,6 @@ destroy_output_block (struct output_block * ob, bool is_function)
VEC_free (tree, heap, ob->named_labels);
}
VEC_free (tree, heap, ob->local_decls);
- VEC_free (tree, heap, ob->field_decls);
- VEC_free (tree, heap, ob->fn_decls);
- VEC_free (tree, heap, ob->var_decls);
- VEC_free (tree, heap, ob->types);
free (ob);
}
@@ -526,47 +440,6 @@ output_integer (struct output_block *ob, tree t)
}
-/* Lookup NAME in TABLE. If NAME is not found, create a new entry in
- TABLE for NAME with NEXT_INDEX and increment NEXT_INDEX. Then
- print the index to OBS. True is returned if NAME was added to the
- table. The resulting index is store in THIS_INDEX.
-
- If OBS is NULL, the only action is to add NAME to the table. */
-
-static bool
-output_decl_index (struct lto_output_stream * obs, htab_t table,
- unsigned int *next_index, tree name,
- unsigned int *this_index)
-{
- void **slot;
- struct decl_slot d_slot;
- d_slot.t = name;
-
- slot = htab_find_slot (table, &d_slot, INSERT);
- if (*slot == NULL)
- {
- struct decl_slot *new_slot = xmalloc (sizeof (struct decl_slot));
- int index = (*next_index)++;
-
- new_slot->t = name;
- new_slot->slot_num = index;
- *this_index = index;
- *slot = new_slot;
- if (obs)
- lto_output_uleb128_stream (obs, index);
- return true;
- }
- else
- {
- struct decl_slot *old_slot = (struct decl_slot *)*slot;
- *this_index = old_slot->slot_num;
- if (obs)
- lto_output_uleb128_stream (obs, old_slot->slot_num);
- return false;
- }
-}
-
-
/* Build a densely packed word that contains only the flags that are
used for this type of tree EXPR and write the word in uleb128 to
the OB. IF CODE is 0 (ERROR_MARK), put the flags anyway.
@@ -751,11 +624,13 @@ output_type_ref (struct output_block *ob, tree node)
unsigned int index;
LTO_DEBUG_TOKEN ("type");
- new = output_decl_index (ob->main_stream, ob->type_hash_table,
- &ob->next_type_index, node, &index);
+ new = lto_output_decl_index (ob->main_stream,
+ ob->decl_state->type_hash_table,
+ &ob->decl_state->next_type_index,
+ node, &index);
if (new)
- VEC_safe_push (tree, heap, ob->types, node);
+ VEC_safe_push (tree, heap, ob->decl_state->types, node);
}
@@ -766,10 +641,10 @@ static unsigned int
output_local_decl_ref (struct output_block *ob, tree name, bool write)
{
unsigned int index;
- bool new = output_decl_index (write ? ob->main_stream : NULL,
- ob->local_decl_hash_table,
- &ob->next_local_decl_index,
- name, &index);
+ bool new = lto_output_decl_index (write ? ob->main_stream : NULL,
+ ob->local_decl_hash_table,
+ &ob->next_local_decl_index,
+ name, &index);
/* Push the new local var or param onto a vector for later
processing. */
if (new)
@@ -790,13 +665,13 @@ static void
output_label_ref (struct output_block *ob, tree label)
{
void **slot;
- struct decl_slot d_slot;
+ struct lto_decl_slot d_slot;
d_slot.t = label;
slot = htab_find_slot (ob->label_hash_table, &d_slot, INSERT);
if (*slot == NULL)
{
- struct decl_slot *new_slot = xmalloc (sizeof (struct decl_slot));
+ struct lto_decl_slot *new_slot = xmalloc (sizeof (struct lto_decl_slot));
/* Named labels are given positive integers and unnamed labels are
given negative indexes. */
@@ -813,7 +688,7 @@ output_label_ref (struct output_block *ob, tree label)
}
else
{
- struct decl_slot *old_slot = (struct decl_slot *)*slot;
+ struct lto_decl_slot *old_slot = (struct lto_decl_slot *)*slot;
output_sleb128 (ob, old_slot->slot_num);
}
}
@@ -1170,10 +1045,12 @@ output_expr_operand (struct output_block *ob, tree expr)
bool new;
output_record_start (ob, NULL, NULL, tag);
- new = output_decl_index (ob->main_stream, ob->field_decl_hash_table,
- &ob->next_field_decl_index, expr, &index);
+ new = lto_output_decl_index (ob->main_stream,
+ ob->decl_state->field_decl_hash_table,
+ &ob->decl_state->next_field_decl_index,
+ expr, &index);
if (new)
- VEC_safe_push (tree, heap, ob->field_decls, expr);
+ VEC_safe_push (tree, heap, ob->decl_state->field_decls, expr);
}
break;
@@ -1183,10 +1060,12 @@ output_expr_operand (struct output_block *ob, tree expr)
bool new;
output_record_start (ob, NULL, NULL, tag);
- new = output_decl_index (ob->main_stream, ob->fn_decl_hash_table,
- &ob->next_fn_decl_index, expr, &index);
+ new = lto_output_decl_index (ob->main_stream,
+ ob->decl_state->fn_decl_hash_table,
+ &ob->decl_state->next_fn_decl_index,
+ expr, &index);
if (new)
- VEC_safe_push (tree, heap, ob->fn_decls, expr);
+ VEC_safe_push (tree, heap, ob->decl_state->fn_decls, expr);
}
break;
@@ -1198,10 +1077,12 @@ output_expr_operand (struct output_block *ob, tree expr)
bool new;
output_record_start (ob, NULL, NULL, LTO_var_decl1);
- new = output_decl_index (ob->main_stream, ob->var_decl_hash_table,
- &ob->next_var_decl_index, expr, &index);
+ new = lto_output_decl_index (ob->main_stream,
+ ob->decl_state->var_decl_hash_table,
+ &ob->decl_state->next_var_decl_index,
+ expr, &index);
if (new)
- VEC_safe_push (tree, heap, ob->var_decls, expr);
+ VEC_safe_push (tree, heap, ob->decl_state->var_decls, expr);
}
else
{
@@ -1217,10 +1098,12 @@ output_expr_operand (struct output_block *ob, tree expr)
bool new;
output_record_start (ob, NULL, NULL, tag);
- new = output_decl_index (ob->main_stream, ob->type_decl_hash_table,
- &ob->next_type_decl_index, expr, &index);
+ new = lto_output_decl_index (ob->main_stream,
+ ob->decl_state->type_decl_hash_table,
+ &ob->decl_state->next_type_decl_index,
+ expr, &index);
if (new)
- VEC_safe_push (tree, heap, ob->type_decls, expr);
+ VEC_safe_push (tree, heap, ob->decl_state->type_decls, expr);
}
break;
@@ -1270,6 +1153,17 @@ output_expr_operand (struct output_block *ob, tree expr)
{
unsigned int count = TREE_INT_CST_LOW (TREE_OPERAND (expr, 0));
unsigned int i;
+ struct cgraph_edge *e = ob->cgraph_node->callees;
+
+
+ gcc_assert (ob->cgraph_node);
+ gcc_assert (ob->current_stmt_uid != -1);
+
+ while (e)
+ {
+ e->lto_stmt_uid = ob->current_stmt_uid;
+ e = e->next_callee;
+ }
/* Operand 2 is the call chain. */
if (TREE_OPERAND (expr, 2))
@@ -1837,7 +1731,9 @@ output_bb (struct output_block *ob, basic_block bb, struct function *fn)
!bsi_end_p (bsi); bsi_next (&bsi))
{
tree stmt = bsi_stmt (bsi);
-
+
+ ob->current_stmt_uid = gimple_stmt_uid (stmt);
+
LTO_DEBUG_INDENT_TOKEN ("stmt");
output_expr_operand (ob, stmt);
@@ -1862,6 +1758,8 @@ output_bb (struct output_block *ob, basic_block bb, struct function *fn)
LTO_DEBUG_INDENT_TOKEN ("stmt");
output_zero (ob);
+ ob->current_stmt_uid = -1;
+
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
{
LTO_DEBUG_INDENT_TOKEN ("phi");
@@ -1879,55 +1777,35 @@ output_bb (struct output_block *ob, basic_block bb, struct function *fn)
#endif
}
-/* Write the references for the objects in V to section SEC in the
- assembly file. Use REF_FN to compute the reference. */
+/* Create the header in the file using OB. If the section type is for
+ a function, set FN to the decl for that function. */
static void
-write_references (VEC(tree,heap) *v, section *sec,
- void (*ref_fn) (tree, lto_out_ref *))
+produce_asm (struct output_block *ob, tree fn)
{
- int index;
- tree t;
- lto_out_ref out_ref = {0, NULL, NULL};
+ enum lto_section_type section_type = ob->section_type;
+ struct lto_function_header header;
+ section *section;
- for (index = 0; VEC_iterate(tree, v, index, t); index++)
+ if (section_type == LTO_section_function_body)
{
- ref_fn (t, &out_ref);
- /* We always call switch_to_section as the act of creating a
- handle we can reference may have dumped some bits into the
- assembly. */
- switch_to_section (sec);
- dw2_asm_output_data (8, out_ref.section, " ");
- dw2_asm_output_delta (8, out_ref.label, out_ref.base_label, " ");
+ const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn));
+ section = lto_get_section (section_type, name);
}
-}
-
-/* Create the header in the file using OB for t. */
-
-static void
-produce_asm (struct output_block *ob, tree t, enum lto_section_type section_type)
-{
- const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
- struct lto_function_header header;
- section *section = lto_get_section (section_type, name);
-
+ else
+ section = lto_get_section (section_type, NULL);
+
memset (&header, 0, sizeof (struct lto_function_header));
/* The entire header is stream computed here. */
switch_to_section (section);
- /* Write the header which says how to decode the pieces of the
- t. */
+ /* Write the header. */
header.lto_header.major_version = LTO_major_version;
header.lto_header.minor_version = LTO_minor_version;
header.lto_header.section_type = section_type;
- header.num_field_decls = VEC_length (tree, ob->field_decls);
- header.num_fn_decls = VEC_length (tree, ob->fn_decls);
- header.num_var_decls = VEC_length (tree, ob->var_decls);
- header.num_type_decls = VEC_length (tree, ob->type_decls);
- header.num_types = VEC_length (tree, ob->types);
- if (section_type == lto_function_body)
+ if (section_type == LTO_section_function_body)
{
header.num_local_decls = VEC_length (tree, ob->local_decls);
header.num_named_labels = ob->next_named_label_index;
@@ -1935,7 +1813,7 @@ produce_asm (struct output_block *ob, tree t, enum lto_section_type section_type
}
header.compressed_size = 0;
- if (section_type == lto_function_body)
+ if (section_type == LTO_section_function_body)
{
header.named_label_size = ob->named_label_stream->total_size;
header.ssa_names_size = ob->ssa_names_stream->total_size;
@@ -1946,7 +1824,7 @@ produce_asm (struct output_block *ob, tree t, enum lto_section_type section_type
header.main_size = ob->main_stream->total_size;
header.string_size = ob->string_stream->total_size;
#ifdef LTO_STREAM_DEBUGGING
- if (section_type == lto_function_body)
+ if (section_type == LTO_section_function_body)
{
header.debug_decl_index_size = ob->debug_decl_index_stream->total_size;
header.debug_decl_size = ob->debug_decl_stream->total_size;
@@ -1967,24 +1845,9 @@ produce_asm (struct output_block *ob, tree t, enum lto_section_type section_type
assemble_string ((const char *)&header,
sizeof (struct lto_function_header));
- /* Write the global field references. */
- write_references (ob->field_decls, section, lto_field_ref);
-
- /* Write the global function references. */
- write_references (ob->fn_decls, section, lto_fn_ref);
-
- /* Write the global var references. */
- write_references (ob->var_decls, section, lto_var_ref);
-
- /* Write the global type_decl references. */
- write_references (ob->type_decls, section, lto_typedecl_ref);
-
- /* Write the global type references. */
- write_references (ob->types, section, lto_type_ref);
-
/* Put all of the gimple and the string table out the asm file as a
block of text. */
- if (section_type == lto_function_body)
+ if (section_type == LTO_section_function_body)
{
lto_write_stream (ob->named_label_stream);
lto_write_stream (ob->ssa_names_stream);
@@ -1995,7 +1858,7 @@ produce_asm (struct output_block *ob, tree t, enum lto_section_type section_type
lto_write_stream (ob->main_stream);
lto_write_stream (ob->string_stream);
#ifdef LTO_STREAM_DEBUGGING
- if (section_type == lto_function_body)
+ if (section_type == LTO_section_function_body)
{
lto_write_stream (ob->debug_decl_index_stream);
lto_write_stream (ob->debug_decl_stream);
@@ -2127,10 +1990,12 @@ output_function (struct cgraph_node* node)
tree function = node->decl;
struct function *fn = DECL_STRUCT_FUNCTION (function);
basic_block bb;
- struct output_block *ob = create_output_block (true);
+ struct output_block *ob = create_output_block (LTO_section_function_body);
LTO_SET_DEBUGGING_STREAM (debug_main_stream, main_data);
clear_line_info (ob);
+ ob->cgraph_node = node;
+ ob->current_stmt_uid = -1;
gcc_assert (!current_function_decl && !cfun);
@@ -2195,9 +2060,9 @@ output_function (struct cgraph_node* node)
/* Create a file to hold the pickled output of this function. This
is a temp standin until we start writing sections. */
- produce_asm (ob, function, lto_function_body);
+ produce_asm (ob, function);
- destroy_output_block (ob, true);
+ destroy_output_block (ob);
current_function_decl = NULL;
@@ -2205,12 +2070,16 @@ output_function (struct cgraph_node* node)
}
-/* Output constructor for VAR. */
+/* Output constructor for static or external vars. */
static void
-output_constructor_or_init (tree var)
+output_constructors_and_inits (void)
{
- struct output_block *ob = create_output_block (false);
+ struct output_block *ob = create_output_block (LTO_section_static_initializer);
+ struct varpool_node *vnode;
+
+ ob->cgraph_node = NULL;
+ ob->current_stmt_uid = -1;
LTO_SET_DEBUGGING_STREAM (debug_main_stream, main_data);
clear_line_info (ob);
@@ -2218,14 +2087,24 @@ output_constructor_or_init (tree var)
/* Make string 0 be a NULL string. */
lto_output_1_stream (ob->string_stream, 0);
- LTO_DEBUG_INDENT_TOKEN ("init");
- output_expr_operand (ob, DECL_INITIAL (var));
-
+ /* Process the global static vars that have initializers or
+ constructors. */
+ FOR_EACH_STATIC_INITIALIZER (vnode)
+ {
+ tree var = vnode->decl;
+ if (DECL_CONTEXT (var) == NULL_TREE)
+ {
+ output_expr_operand (ob, var);
+
+ LTO_DEBUG_TOKEN ("init");
+ output_expr_operand (ob, DECL_INITIAL (var));
+ }
+ }
/* The terminator for the constructor. */
output_zero (ob);
-
- produce_asm (ob, var, lto_static_initializer);
- destroy_output_block (ob, false);
+
+ produce_asm (ob, NULL);
+ destroy_output_block (ob);
}
@@ -2235,8 +2114,6 @@ static unsigned int
lto_output (void)
{
struct cgraph_node *node;
- struct varpool_node *vnode;
-
section *saved_section = in_section;
lto_static_init_local ();
@@ -2250,11 +2127,7 @@ lto_output (void)
if (node->analyzed && cgraph_is_master_clone (node, false))
output_function (node);
- /* Process the global static vars that have initializers or
- constructors. */
- FOR_EACH_STATIC_INITIALIZER (vnode)
- if (DECL_CONTEXT (vnode->decl) == NULL_TREE)
- output_constructor_or_init (vnode->decl);
+ output_constructors_and_inits ();
/* Put back the assembly section that was there before we started
writing lto info. */
@@ -2266,17 +2139,9 @@ lto_output (void)
return 0;
}
-static bool
-gate_lto_out (void)
-{
- return (flag_generate_lto
- /* Don't bother doing anything if the program has errors. */
- && !(errorcount || sorrycount));
-}
-
-struct tree_opt_pass pass_ipa_lto_out =
+struct tree_opt_pass pass_ipa_lto_gimple_out =
{
- "lto_function_out", /* name */
+ "lto_gimple_out", /* name */
gate_lto_out, /* gate */
lto_output, /* execute */
NULL, /* sub */
diff --git a/gcc/lto-header.h b/gcc/lto-header.h
index a61c8bf2446..6d5dd54b7f2 100644
--- a/gcc/lto-header.h
+++ b/gcc/lto-header.h
@@ -32,11 +32,16 @@
#define LTO_major_version 1
#define LTO_minor_version 0
+/* This is all of the section types that are in the .o file. This
+ list will grow as the number of ipa passes grows since each ipa
+ pass will need it's own section type to store it's summary
+ information. */
enum lto_section_type
{
- lto_function_body,
- lto_static_initializer,
- lto_cgraph
+ LTO_section_decls,
+ LTO_section_function_body,
+ LTO_section_static_initializer,
+ LTO_section_cgraph
};
struct lto_header
@@ -46,4 +51,73 @@ struct lto_header
enum lto_section_type section_type;
};
+/* In lto-section-out.c. */
+const char *lto_get_section_name (enum lto_section_type, const char *);
+section *lto_get_section (enum lto_section_type, const char *);
+
+/* Define this symbol if you want to debug an lto stream. This causes
+ a set of redundant streams to be written into the .o files that can
+ pinpoint problems where the reader is not in sync with the writers.
+ The cost is a large amount of time and space, but this is the
+ necessary to debug a stream protocol with little redundancy. */
+#define LTO_STREAM_DEBUGGING
+
+#ifdef LTO_STREAM_DEBUGGING
+#define LTO_DEBUG_INDENT(tag) \
+ lto_debug_indent (&lto_debug_context, tag)
+#define LTO_DEBUG_INDENT_TOKEN(value) \
+ lto_debug_indent_token (&lto_debug_context, value)
+#define LTO_DEBUG_INTEGER(tag,high,low) \
+ lto_debug_integer (&lto_debug_context, tag, high, low)
+#define LTO_DEBUG_STRING(value,len) \
+ lto_debug_string (&lto_debug_context, value, len)
+#define LTO_DEBUG_TOKEN(value) \
+ lto_debug_token (&lto_debug_context, value)
+#define LTO_DEBUG_TREE_FLAGS(code,value) \
+ lto_debug_tree_flags (&lto_debug_context, code, flags)
+#define LTO_DEBUG_UNDENT() \
+ lto_debug_undent (&lto_debug_context)
+#define LTO_DEBUG_WIDE(tag,value) \
+ lto_debug_wide (&lto_debug_context, tag, value)
+
+
+struct lto_debug_context;
+
+typedef void (*lto_debug_out) (struct lto_debug_context *context, char c);
+
+struct lto_debug_context
+{
+ lto_debug_out out;
+ int indent;
+ void * current_data;
+ void * decl_index_data;
+ void * decl_data;
+ void * label_data;
+ void * ssa_names_data;
+ void * cfg_data;
+ void * main_data;
+};
+
+extern struct lto_debug_context lto_debug_context;
+
+extern void lto_debug_indent (struct lto_debug_context *, int);
+extern void lto_debug_indent_token (struct lto_debug_context *, const char *);
+extern void lto_debug_integer (struct lto_debug_context *, const char *, HOST_WIDE_INT, HOST_WIDE_INT);
+extern void lto_debug_string (struct lto_debug_context *, const char *, int);
+extern void lto_debug_token (struct lto_debug_context *, const char *);
+extern void lto_debug_undent (struct lto_debug_context *);
+extern void lto_debug_wide (struct lto_debug_context *, const char *, HOST_WIDE_INT);
+
+#else
+#define LTO_DEBUG_INDENT(tag) (void)0
+#define LTO_DEBUG_INDENT_TOKEN(value) (void)0
+#define LTO_DEBUG_INTEGER(tag,high,low) (void)0
+#define LTO_DEBUG_STRING(value,len) (void)0
+#define LTO_DEBUG_TOKEN(value) (void)0
+#define LTO_DEBUG_TREE_FLAGS(code, value) (void)0
+#define LTO_DEBUG_UNDENT() (void)0
+#define LTO_DEBUG_WIDE(tag,value) (void)0
+#endif
+
+
#endif /* lto-header.h */
diff --git a/gcc/lto-section-out.c b/gcc/lto-section-out.c
index 989e56b3f86..406e88b4996 100644
--- a/gcc/lto-section-out.c
+++ b/gcc/lto-section-out.c
@@ -47,37 +47,104 @@ along with GCC; see the file COPYING3. If not see
#include "dwarf2asm.h"
#include "dwarf2out.h"
#include "output.h"
-#include "lto-tags.h"
+#include "lto-section.h"
#include "lto-section-out.h"
#include <ctype.h>
-/* Get a section for writing of a particular type or name. The NAME
- field is only used if SECTION_TYPE is lto_function_body or
- lto_static_initializer. */
-section *
-lto_get_section (enum lto_section_type section_type, const char * name)
+
+/* Returns a hash code for P. */
+
+hashval_t
+lto_hash_decl_slot_node (const void *p)
+{
+ const struct lto_decl_slot *ds = (const struct lto_decl_slot *) p;
+ return (hashval_t) DECL_UID (ds->t);
+}
+
+
+/* Returns nonzero if P1 and P2 are equal. */
+
+int
+lto_eq_decl_slot_node (const void *p1, const void *p2)
+{
+ const struct lto_decl_slot *ds1 =
+ (const struct lto_decl_slot *) p1;
+ const struct lto_decl_slot *ds2 =
+ (const struct lto_decl_slot *) p2;
+
+ return DECL_UID (ds1->t) == DECL_UID (ds2->t);
+}
+
+
+/* Returns a hash code for P. */
+
+hashval_t
+lto_hash_type_slot_node (const void *p)
{
- char *section_name;
- section *section;
+ const struct lto_decl_slot *ds = (const struct lto_decl_slot *) p;
+ return (hashval_t) TYPE_UID (ds->t);
+}
+
+
+/* Returns nonzero if P1 and P2 are equal. */
+
+int
+lto_eq_type_slot_node (const void *p1, const void *p2)
+{
+ const struct lto_decl_slot *ds1 =
+ (const struct lto_decl_slot *) p1;
+ const struct lto_decl_slot *ds2 =
+ (const struct lto_decl_slot *) p2;
+
+ return TYPE_UID (ds1->t) == TYPE_UID (ds2->t);
+}
+
+/* Get a section name for a particular type or name. The NAME field
+ is only used if SECTION_TYPE is LTO_section_function_body or
+ lto_static_initializer. For all others it is ignored. The callee
+ of this function is responcible to free the returned name. */
+const char *
+lto_get_section_name (enum lto_section_type section_type, const char * name)
+{
switch (section_type)
{
- case lto_function_body:
- case lto_static_initializer:
- section_name = concat (LTO_SECTION_NAME_PREFIX, name, NULL);
- break;
-
- case lto_cgraph:
- section_name = concat (LTO_SECTION_NAME_PREFIX, ".cgraph", NULL);
- break;
+ case LTO_section_function_body:
+ return concat (LTO_SECTION_NAME_PREFIX, name, NULL);
+
+ case LTO_section_static_initializer:
+ return concat (LTO_SECTION_NAME_PREFIX, ".statics", NULL);
+
+ case LTO_section_decls:
+ return concat (LTO_SECTION_NAME_PREFIX, ".decls", NULL);
+
+ case LTO_section_cgraph:
+ return concat (LTO_SECTION_NAME_PREFIX, ".cgraph", NULL);
+
+ default:
+ gcc_unreachable ();
}
+}
+
- section = get_section (section_name, SECTION_DEBUG, NULL);
- free (section_name);
+/* Get a section for particular type or name. The NAME field is only
+ used if SECTION_TYPE is LTO_section_function_body or
+ lto_static_initializer. */
+section *
+lto_get_section (enum lto_section_type section_type, const char * name)
+{
+ const char *section_name = lto_get_section_name (section_type, name);
+ section *section = get_section (section_name, SECTION_DEBUG, NULL);
+ free ((char *)section_name);
return section;
}
+/*****************************************************************************/
+/* Output routines shared by all of the serialization passes. */
+/*****************************************************************************/
+
+
/* Write all of the chars in OBS to the assembler. Recycle the blocks
in obs as this is being done. */
@@ -274,6 +341,192 @@ lto_output_integer_stream (struct lto_output_stream *obs, tree t)
while (more);
}
+
+/* Lookup NAME in TABLE. If NAME is not found, create a new entry in
+ TABLE for NAME with NEXT_INDEX and increment NEXT_INDEX. Then
+ print the index to OBS. True is returned if NAME was added to the
+ table. The resulting index is store in THIS_INDEX.
+
+ If OBS is NULL, the only action is to add NAME to the table. */
+
+bool
+lto_output_decl_index (struct lto_output_stream * obs, htab_t table,
+ unsigned int *next_index, tree name,
+ unsigned int *this_index)
+{
+ void **slot;
+ struct lto_decl_slot d_slot;
+ d_slot.t = name;
+
+ slot = htab_find_slot (table, &d_slot, INSERT);
+ if (*slot == NULL)
+ {
+ struct lto_decl_slot *new_slot = xmalloc (sizeof (struct lto_decl_slot));
+ int index = (*next_index)++;
+
+ new_slot->t = name;
+ new_slot->slot_num = index;
+ *this_index = index;
+ *slot = new_slot;
+ if (obs)
+ lto_output_uleb128_stream (obs, index);
+ return true;
+ }
+ else
+ {
+ struct lto_decl_slot *old_slot = (struct lto_decl_slot *)*slot;
+ *this_index = old_slot->slot_num;
+ if (obs)
+ lto_output_uleb128_stream (obs, old_slot->slot_num);
+ return false;
+ }
+}
+
+
+/*****************************************************************************/
+/* This part is used to store all of the global decls and types that are */
+/* serialized out in this file so that a table for this file can be built */
+/* that allows the decls and types to be reconnected to the code or the */
+/* ipa summary information. */
+/*****************************************************************************/
+static struct lto_out_decl_state *out_state;
+
+struct lto_out_decl_state *
+lto_get_out_decl_state (void)
+{
+ if (!out_state)
+ {
+ out_state = xcalloc (1, sizeof (struct lto_out_decl_state));
+
+ out_state->field_decl_hash_table
+ = htab_create (37, lto_hash_decl_slot_node, lto_eq_decl_slot_node, free);
+ out_state->fn_decl_hash_table
+ = htab_create (37, lto_hash_decl_slot_node, lto_eq_decl_slot_node, free);
+ out_state->type_hash_table
+ = htab_create (37, lto_hash_type_slot_node, lto_eq_type_slot_node, free);
+ out_state->type_decl_hash_table
+ = htab_create (37, lto_hash_decl_slot_node, lto_eq_decl_slot_node, free);
+ out_state->var_decl_hash_table
+ = htab_create (37, lto_hash_decl_slot_node, lto_eq_decl_slot_node, free);
+ }
+ return out_state;
+}
+
+/* Write the references for the objects in V to section SEC in the
+ assembly file. Use REF_FN to compute the reference. */
+
+static void
+write_references (VEC(tree,heap) *v, section *sec,
+ void (*ref_fn) (tree, lto_out_ref *))
+{
+ int index;
+ tree t;
+ lto_out_ref out_ref = {0, NULL, NULL};
+
+ for (index = 0; VEC_iterate(tree, v, index, t); index++)
+ {
+ ref_fn (t, &out_ref);
+ /* We always call switch_to_section as the act of creating a
+ handle we can reference may have dumped some bits into the
+ assembly. */
+ switch_to_section (sec);
+ dw2_asm_output_data (8, out_ref.section, " ");
+ dw2_asm_output_delta (8, out_ref.label, out_ref.base_label, " ");
+ }
+}
+
+/* This pass is run after all of the functions are serialized and all
+ of the ipa passes have written their serialized forms. This pass
+ cases the vector of all of the global decls and types used from
+ this file to be written in to a section that can then be read in to
+ recover these on other side. */
+static unsigned int
+produce_asm_for_decls (void)
+{
+ struct lto_decl_header header;
+ section *section = lto_get_section (LTO_section_decls, NULL);
+ struct lto_out_decl_state *out_state = lto_get_out_decl_state ();
+
+ memset (&header, 0, sizeof (struct lto_decl_header));
+
+ /* The entire header is stream computed here. */
+ switch_to_section (section);
+
+ header.lto_header.major_version = LTO_major_version;
+ header.lto_header.minor_version = LTO_minor_version;
+ header.lto_header.section_type = LTO_section_decls;
+
+ header.num_field_decls = VEC_length (tree, out_state->field_decls);
+ header.num_fn_decls = VEC_length (tree, out_state->fn_decls);
+ header.num_var_decls = VEC_length (tree, out_state->var_decls);
+ header.num_type_decls = VEC_length (tree, out_state->type_decls);
+ header.num_types = VEC_length (tree, out_state->types);
+
+ assemble_string ((const char *)&header,
+ sizeof (struct lto_decl_header));
+
+ /* Write the global field references. */
+ write_references (out_state->field_decls, section, lto_field_ref);
+
+ /* Write the global function references. */
+ write_references (out_state->fn_decls, section, lto_fn_ref);
+
+ /* Write the global var references. */
+ write_references (out_state->var_decls, section, lto_var_ref);
+
+ /* Write the global type_decl references. */
+ write_references (out_state->type_decls, section, lto_typedecl_ref);
+
+ /* Write the global type references. */
+ write_references (out_state->types, section, lto_type_ref);
+
+ htab_delete (out_state->field_decl_hash_table);
+ htab_delete (out_state->fn_decl_hash_table);
+ htab_delete (out_state->var_decl_hash_table);
+ htab_delete (out_state->type_decl_hash_table);
+ htab_delete (out_state->type_hash_table);
+
+ VEC_free (tree, heap, out_state->field_decls);
+ VEC_free (tree, heap, out_state->fn_decls);
+ VEC_free (tree, heap, out_state->var_decls);
+ VEC_free (tree, heap, out_state->type_decls);
+ VEC_free (tree, heap, out_state->types);
+
+ free (out_state);
+
+ return 0;
+}
+
+
+/* Gate function for all lto streaming passes. */
+bool
+gate_lto_out (void)
+{
+ return (flag_generate_lto
+ /* Don't bother doing anything if the program has errors. */
+ && !(errorcount || sorrycount));
+}
+
+
+struct tree_opt_pass pass_ipa_lto_finish_out =
+{
+ "lto_decls_out", /* name */
+ gate_lto_out, /* gate */
+ produce_asm_for_decls, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_IPA_LTO_OUT, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+ 0 /* letter */
+};
+
+
+
#ifdef LTO_STREAM_DEBUGGING
struct lto_debug_context lto_debug_context;
diff --git a/gcc/lto-section-out.h b/gcc/lto-section-out.h
index 949a5e4906a..4a4b796ae30 100644
--- a/gcc/lto-section-out.h
+++ b/gcc/lto-section-out.h
@@ -66,8 +66,54 @@ do { \
#define LTO_CLEAR_DEBUGGING_STREAM(STREAM) (void)0
#endif
+struct lto_decl_slot {
+ tree t;
+ int slot_num;
+};
+
+
+/* The structure that holds all of the vectors of global types and
+ decls used in lto serialization for this file. */
+
+struct lto_out_decl_state
+{
+ /* The hash table that contains the set of field_decls we have
+ seen so far and the indexes assigned to them. */
+ htab_t field_decl_hash_table;
+ unsigned int next_field_decl_index;
+ VEC(tree,heap) *field_decls;
+
+ /* The hash table that contains the set of function_decls we have
+ seen so far and the indexes assigned to them. */
+ htab_t fn_decl_hash_table;
+ unsigned int next_fn_decl_index;
+ VEC(tree,heap) *fn_decls;
-section *lto_get_section (enum lto_section_type, const char *);
+ /* The hash table that contains the set of var_decls we have
+ seen so far and the indexes assigned to them. */
+ htab_t var_decl_hash_table;
+ unsigned int next_var_decl_index;
+ VEC(tree,heap) *var_decls;
+
+ /* The hash table that contains the set of type_decls we have
+ seen so far and the indexes assigned to them. */
+ htab_t type_decl_hash_table;
+ unsigned int next_type_decl_index;
+ VEC(tree,heap) *type_decls;
+
+ /* The hash table that contains the set of type we have seen so far
+ and the indexes assigned to them. */
+ htab_t type_hash_table;
+ unsigned int next_type_index;
+ VEC(tree,heap) *types;
+};
+
+hashval_t lto_hash_decl_slot_node (const void *);
+int lto_eq_decl_slot_node (const void *, const void *);
+hashval_t lto_hash_type_slot_node (const void *);
+int lto_eq_type_slot_node (const void *, const void *);
+
+struct lto_out_decl_state *lto_get_out_decl_state (void);
void lto_write_stream (struct lto_output_stream *);
void lto_output_1_stream (struct lto_output_stream *, char);
void lto_output_uleb128_stream (struct lto_output_stream *, unsigned HOST_WIDE_INT);
@@ -75,5 +121,6 @@ void lto_output_widest_uint_uleb128_stream (struct lto_output_stream *,
unsigned HOST_WIDEST_INT);
void lto_output_sleb128_stream (struct lto_output_stream *, HOST_WIDE_INT);
void lto_output_integer_stream (struct lto_output_stream *, tree);
-
+bool lto_output_decl_index (struct lto_output_stream *, htab_t, unsigned int *, tree, unsigned int *);
+bool gate_lto_out (void);
#endif /* GCC_LTO_SECTION_OUT_H */
diff --git a/gcc/lto-section.h b/gcc/lto-section.h
new file mode 100644
index 00000000000..52c11d9ec9c
--- /dev/null
+++ b/gcc/lto-section.h
@@ -0,0 +1,39 @@
+/* Declarations and definitions of codes relating to the
+ encoding of global decls and types into the object files.
+
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2, or (at your option) any later
+ version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#ifndef GCC_LTO_SECTION_H
+#define GCC_LTO_SECTION_H
+
+#include "lto-header.h"
+
+struct lto_decl_header
+{
+ struct lto_header lto_header; /* The header for all types of sections. */
+ int32_t num_field_decls; /* Number of FIELD_DECLS. */
+ int32_t num_fn_decls; /* Number of FUNCTION_DECLS. */
+ int32_t num_var_decls; /* Number of non local VAR_DECLS. */
+ int32_t num_type_decls; /* Number of TYPE_DECLs. */
+ int32_t num_types; /* Number of types. */
+};
+
+#endif /* GCC_LTO_SECTION_H */
diff --git a/gcc/lto-stream-debug.c b/gcc/lto-stream-debug.c
index 2f5b83870f6..f0e828f7938 100644
--- a/gcc/lto-stream-debug.c
+++ b/gcc/lto-stream-debug.c
@@ -28,6 +28,7 @@ Boston, MA 02110-1301, USA. */
#include "params.h"
#include "input.h"
#include "debug.h"
+#include "lto-header.h"
#include "lto-tags.h"
#include <ctype.h>
diff --git a/gcc/lto-tags.h b/gcc/lto-tags.h
index 35d78cc4b67..05bcf021149 100644
--- a/gcc/lto-tags.h
+++ b/gcc/lto-tags.h
@@ -65,11 +65,6 @@
struct lto_function_header
{
struct lto_header lto_header; /* The header for all types of sections. */
- int32_t num_field_decls; /* Number of FIELD_DECLS. */
- int32_t num_fn_decls; /* Number of FUNCTION_DECLS. */
- int32_t num_var_decls; /* Number of non local VAR_DECLS. */
- int32_t num_type_decls; /* Number of TYPE_DECLs. */
- int32_t num_types; /* Number of types. */
int32_t num_local_decls; /* Number of local VAR_DECLS and PARM_DECLS. */
int32_t num_named_labels; /* Number of labels with names. */
int32_t num_unnamed_labels; /* Number of labels without names. */
@@ -479,55 +474,6 @@ extern sbitmap lto_flags_needed_for;
void lto_static_init (void);
-#define LTO_STREAM_DEBUGGING
-
-#ifdef LTO_STREAM_DEBUGGING
-#define LTO_DEBUG_INDENT(tag) \
- lto_debug_indent (&lto_debug_context, tag)
-#define LTO_DEBUG_INDENT_TOKEN(value) \
- lto_debug_indent_token (&lto_debug_context, value)
-#define LTO_DEBUG_INTEGER(tag,high,low) \
- lto_debug_integer (&lto_debug_context, tag, high, low)
-#define LTO_DEBUG_STRING(value,len) \
- lto_debug_string (&lto_debug_context, value, len)
-#define LTO_DEBUG_TOKEN(value) \
- lto_debug_token (&lto_debug_context, value)
-#define LTO_DEBUG_TREE_FLAGS(code,value) \
- lto_debug_tree_flags (&lto_debug_context, code, flags)
-#define LTO_DEBUG_UNDENT() \
- lto_debug_undent (&lto_debug_context)
-#define LTO_DEBUG_WIDE(tag,value) \
- lto_debug_wide (&lto_debug_context, tag, value)
-
-
-struct lto_debug_context;
-
-typedef void (*lto_debug_out) (struct lto_debug_context *context, char c);
-
-struct lto_debug_context
-{
- lto_debug_out out;
- int indent;
- void * current_data;
- void * decl_index_data;
- void * decl_data;
- void * label_data;
- void * ssa_names_data;
- void * cfg_data;
- void * main_data;
-};
-
-extern struct lto_debug_context lto_debug_context;
-
-/* The VAR_DECL tree code has more than 32 bits in flags. On some hosts,
- HOST_WIDE_INT is not wide enough. */
-typedef unsigned HOST_WIDEST_INT lto_flags_type;
-#define BITS_PER_LTO_FLAGS_TYPE HOST_BITS_PER_WIDEST_INT
-
-#if BITS_PER_LTO_FLAGS_TYPE <= 32
-# error "Your host should support integer types wider than 32 bits."
-#endif
-
/* The serialization plan is that when any of the current file, line,
or col change (from the state last serialized), we write the
changed entity and only that entity into the stream. We also
@@ -545,27 +491,18 @@ typedef unsigned HOST_WIDEST_INT lto_flags_type;
#define LTO_SOURCE_HAS_LOC 0x8
#define LTO_SOURCE_LOC_BITS 4
-extern const char * LTO_tag_names[LTO_last_tag];
+/* The VAR_DECL tree code has more than 32 bits in flags. On some hosts,
+ HOST_WIDE_INT is not wide enough. */
+typedef unsigned HOST_WIDEST_INT lto_flags_type;
+#define BITS_PER_LTO_FLAGS_TYPE HOST_BITS_PER_WIDEST_INT
-extern void lto_debug_indent (struct lto_debug_context *, int);
-extern void lto_debug_indent_token (struct lto_debug_context *, const char *);
-extern void lto_debug_integer (struct lto_debug_context *, const char *, HOST_WIDE_INT, HOST_WIDE_INT);
-extern void lto_debug_string (struct lto_debug_context *, const char *, int);
-extern void lto_debug_token (struct lto_debug_context *, const char *);
+#if BITS_PER_LTO_FLAGS_TYPE <= 32
+# error "Your host should support integer types wider than 32 bits."
+#endif
+
+#ifdef LTO_STREAM_DEBUGGING
+extern const char * LTO_tag_names[LTO_last_tag];
extern void lto_debug_tree_flags (struct lto_debug_context *, enum tree_code, lto_flags_type);
-extern void lto_debug_undent (struct lto_debug_context *);
-extern void lto_debug_wide (struct lto_debug_context *, const char *, HOST_WIDE_INT);
-
-
-#else
-#define LTO_DEBUG_INDENT(tag) (void)0
-#define LTO_DEBUG_INDENT_TOKEN(value) (void)0
-#define LTO_DEBUG_INTEGER(tag,high,low) (void)0
-#define LTO_DEBUG_STRING(value,len) (void)0
-#define LTO_DEBUG_TOKEN(value) (void)0
-#define LTO_DEBUG_TREE_FLAGS(code, value) (void)0
-#define LTO_DEBUG_UNDENT() (void)0
-#define LTO_DEBUG_WIDE(tag,value) (void)0
#endif
#endif /* lto-tags.h */
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index 67c76fc263f..1269dd7e442 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,40 @@
+2008-02-09 Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ * lto.c (lto_read_variable_formal_parameter_const): Remove code to
+ reconstruct static initializers.
+ (lto_get_body, lto_materialize_function): Add lto_section_type as
+ a parameter.
+ (lto_materialize_constructors_and_inits,
+ lto_materialize_file_data): New function.
+ (lto_materialize_function,
+ lto_read_subroutine_type_subprogram_DIE): Renamed unmap_fn_body to
+ unmap_section and map_fn_body to map_section.
+ (lto_set_cu_context): Process functions and static inits
+ differently.
+ * Make-lang.in (LTO_H, lto/lto-function-in.o,
+ lto/lto-section-in.o): Update dependencies.
+ * lto/lto-elf.c (lto_elf_map_optional_lto_section): Add
+ lto_section_type parameter.
+ (lto_elf_unmap_fn_body): Renamed to lto_elf_unmap_section.
+ * lto.h (lto_file_vtable_struct): Removed two of the fields and
+ renamed the other two so that there is only one map function and
+ one unmap function and each takes a section type parameter.
+ (lto_read_function_body): Renamed to lto_input_function_body and
+ added file_data parameter.
+ (lto_read_var_init): Removed.
+ (lto_input_constructors_and_inits): New function.
+ * lto-section-in.c (lto_read_decls): New function.
+ * lto-function-in.c (data_in): Moved fields field_decls, fn_decls,
+ var_decls, type_decls, types to lto_file_decl_data.
+ (input_type_ref, input_expr_operand, lto_read_body): Get
+ field_decls, fn_decls, var_decls, type_decls, types from different
+ structure.
+ (input_globals, input_constructor, lto_read_var_init): Removed.
+ (input_constructors_or_inits): New function.
+ (lto_read_function_body, lto_input_constructors_and_inits):
+ Renamed to lto_input_function_body and takes file_data parameter.
+ * lto-section-in.h (lto_file_decl_data): New structure.
+
2008-01-28 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-function-in.c (input_globals.c): Changed input type to
diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in
index 9ecfa8cf043..7ee9e17557c 100644
--- a/gcc/lto/Make-lang.in
+++ b/gcc/lto/Make-lang.in
@@ -28,7 +28,7 @@ LTO_EXE = lto1$(exeext)
# The LTO-specific object files inclued in $(LTO_EXE).
LTO_OBJS = lto/lto-lang.o lto/lto.o lto/lto-elf.o lto/lto-function-in.o \
lto/lto-section-in.o lto/lto-symtab.o attribs.o
-LTO_H = lto/lto.h $(HASHTAB_H) $(TREE_H)
+LTO_H = lto/lto.h lto-header.h lto/lto-section-in.h $(HASHTAB_H) $(TREE_H)
########################################################################
# Rules
@@ -91,12 +91,12 @@ lto/lto-function-in.o: lto/lto-function-in.c $(CONFIG_H) $(SYSTEM_H) \
$(PARAMS_H) input.h $(VARRAY_H) $(HASHTAB_H) langhooks.h \
$(BASIC_BLOCK_H) tree-iterator.h tree-pass.h tree-flow.h \
$(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_H) \
- except.h debug.h $(TIMEVAR_H) $(LTO_TAGS_H) lto-tree-flags.def \
+ except.h debug.h $(TIMEVAR_H) lto/lto.h $(LTO_TAGS_H) lto-tree-flags.def \
lto-tree-tags.def lto/lto-section-in.h output.h dwarf2asm.h dwarf2out.h
lto/lto-section-in.o: lto/lto-section-in.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) toplev.h $(LTO_H) $(EXPR_H) $(FLAGS_H) \
$(PARAMS_H) input.h $(VARRAY_H) $(HASHTAB_H) langhooks.h \
$(BASIC_BLOCK_H) tree-iterator.h tree-pass.h tree-flow.h \
$(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_H) \
- except.h debug.h $(TIMEVAR_H) $(LTO_TAGS_H) lto-tree-flags.def \
- lto-tree-tags.def lto/lto-section-in.h output.h dwarf2asm.h dwarf2out.h
+ except.h debug.h $(TIMEVAR_H) lto-tree-flags.def \
+ lto-tree-tags.def lto/lto.h lto/lto-section-in.h output.h dwarf2asm.h dwarf2out.h
diff --git a/gcc/lto/lto-elf.c b/gcc/lto/lto-elf.c
index a16c9b47c6b..c5a1fc47a56 100644
--- a/gcc/lto/lto-elf.c
+++ b/gcc/lto/lto-elf.c
@@ -61,17 +61,17 @@ typedef struct lto_elf_file lto_elf_file;
/* Forward Declarations */
static const void *
-lto_elf_map_optional_lto_section (lto_file *file, const char *id);
+lto_elf_map_optional_lto_section (lto_file *file,
+ enum lto_section_type section_type,
+ const char *id);
static void
-lto_elf_unmap_fn_body (lto_file *file, const char *fn, const void *data);
+lto_elf_unmap_section (lto_file *file, const char *fn, const void *data);
/* The vtable for ELF input files. */
static const lto_file_vtable lto_elf_file_vtable = {
lto_elf_map_optional_lto_section,
- lto_elf_unmap_fn_body,
- lto_elf_map_optional_lto_section,
- lto_elf_unmap_fn_body
+ lto_elf_unmap_section,
};
/* Return the section header for SECTION. The return value is never
@@ -359,11 +359,12 @@ lto_elf_file_close (lto_file *file)
static const void *
lto_elf_map_optional_lto_section (lto_file *file,
+ enum lto_section_type section_type,
const char *id)
{
/* Look in the ELF file to find the actual data, which should be
in the section named LTO_SECTION_NAME_PREFIX || "the function name". */
- const char *name = concat (LTO_SECTION_NAME_PREFIX, id, NULL);
+ const char *name = lto_get_section_name (section_type, id);
Elf_Data *data = lto_elf_find_section_data ((lto_elf_file *)file, name);
free ((void *)name);
@@ -375,7 +376,7 @@ lto_elf_map_optional_lto_section (lto_file *file,
}
static void
-lto_elf_unmap_fn_body (lto_file *file ATTRIBUTE_UNUSED,
+lto_elf_unmap_section (lto_file *file ATTRIBUTE_UNUSED,
const char *fn ATTRIBUTE_UNUSED,
const void *data ATTRIBUTE_UNUSED)
{
diff --git a/gcc/lto/lto-function-in.c b/gcc/lto/lto-function-in.c
index b2e1fcc73a1..752b761e77a 100644
--- a/gcc/lto/lto-function-in.c
+++ b/gcc/lto/lto-function-in.c
@@ -51,7 +51,6 @@ Boston, MA 02110-1301, USA. */
#include "output.h"
#include "lto-tags.h"
#include "lto.h"
-#include "lto-section-in.h"
#include <ctype.h>
#include "cpplib.h"
@@ -62,20 +61,31 @@ static int flags_length_for_code[NUM_TREE_CODES];
struct data_in
{
- tree *field_decls; /* The field decls. */
- tree *fn_decls; /* The function decls. */
- tree *var_decls; /* The global or static var_decls. */
- tree *type_decls; /* The type_decls. */
- tree *types; /* All of the types. */
- int *local_decls_index; /* The offsets to decode the local_decls. */
- int *unexpanded_indexes; /* A table to reconstruct the unexpanded_vars_list. */
+ /* That global decls and types. */
+ struct lto_file_decl_data* file_data;
+
+ /* The offsets to decode the local_decls. */
+ int *local_decls_index;
+
+ /* A table to reconstruct the unexpanded_vars_list. */
+ int *unexpanded_indexes;
+
#ifdef LTO_STREAM_DEBUGGING
- int *local_decls_index_d; /* The offsets to decode the local_decls debug info. */
+ /* The offsets to decode the local_decls debug info. */
+ int *local_decls_index_d;
#endif
- tree *local_decls; /* The local var_decls and the parm_decls. */
- tree *labels; /* All of the labels. */
- const char * strings; /* The string table. */
- unsigned int strings_len; /* The length of the string table. */
+
+ /* The local var_decls and the parm_decls. */
+ tree *local_decls;
+
+ /* All of the labels. */
+ tree *labels;
+
+ /* The string table. */
+ const char * strings;
+
+ /* The length of the string table. */
+ unsigned int strings_len;
/* Number of named labels. Used to find the index of unnamed labels
since they share space with the named labels. */
unsigned int num_named_labels;
@@ -87,7 +97,6 @@ struct data_in
};
-
/* This hash table is used to hash the file names in the
source_location field. Unlike other structures here, this is a
persistent structure whose data lives for the entire
@@ -228,7 +237,7 @@ input_type_ref (struct data_in *data_in, struct lto_input_block *ib)
LTO_DEBUG_TOKEN ("type");
index = lto_input_uleb128 (ib);
- return data_in->types[index];
+ return data_in->file_data->types[index];
}
/* Set all of the FLAGS for NODE. */
@@ -603,16 +612,16 @@ input_expr_operand (struct lto_input_block *ib, struct data_in *data_in,
break;
case FIELD_DECL:
- result = data_in->field_decls [lto_input_uleb128 (ib)];
+ result = data_in->file_data->field_decls [lto_input_uleb128 (ib)];
break;
case FUNCTION_DECL:
- result = data_in->fn_decls [lto_input_uleb128 (ib)];
+ result = data_in->file_data->fn_decls [lto_input_uleb128 (ib)];
gcc_assert (result);
break;
case TYPE_DECL:
- result = data_in->type_decls [lto_input_uleb128 (ib)];
+ result = data_in->file_data->type_decls [lto_input_uleb128 (ib)];
gcc_assert (result);
break;
@@ -621,7 +630,7 @@ input_expr_operand (struct lto_input_block *ib, struct data_in *data_in,
if (tag == LTO_var_decl1)
{
/* Static or externs are here. */
- result = data_in->var_decls [lto_input_uleb128 (ib)];
+ result = data_in->file_data->var_decls [lto_input_uleb128 (ib)];
varpool_mark_needed_node (varpool_node (result));
}
else
@@ -1038,48 +1047,6 @@ input_expr_operand (struct lto_input_block *ib, struct data_in *data_in,
}
-/* Load in the global vars and all of the types from the main symbol
- table. */
-
-static void
-input_globals (struct lto_function_header * header,
- lto_info_fd *fd,
- lto_context *context,
- struct data_in *data_in,
- lto_ref in_field_decls[],
- lto_ref in_fn_decls[],
- lto_ref in_var_decls[],
- lto_ref in_type_decls[],
- lto_ref in_types[])
-{
- int i;
- data_in->field_decls = xcalloc (header->num_field_decls, sizeof (tree*));
- data_in->fn_decls = xcalloc (header->num_fn_decls, sizeof (tree*));
- data_in->var_decls = xcalloc (header->num_var_decls, sizeof (tree*));
- data_in->type_decls = xcalloc (header->num_type_decls, sizeof (tree*));
- data_in->types = xcalloc (header->num_types, sizeof (tree*));
-
- for (i=0; i<header->num_field_decls; i++)
- data_in->field_decls[i]
- = lto_resolve_field_ref (fd, context, &in_field_decls[i]);
-
- for (i=0; i<header->num_fn_decls; i++)
- data_in->fn_decls[i]
- = lto_resolve_fn_ref (fd, context, &in_fn_decls[i]);
-
- for (i=0; i<header->num_var_decls; i++)
- data_in->var_decls[i]
- = lto_resolve_var_ref (fd, context, &in_var_decls[i]);
-
- for (i=0; i<header->num_type_decls; i++)
- data_in->type_decls[i]
- = lto_resolve_typedecl_ref (fd, context, &in_type_decls[i]);
-
- for (i=0; i<header->num_types; i++)
- data_in->types[i] = lto_resolve_type_ref (fd, context, &in_types[i]);
-}
-
-
/* Load NAMED_COUNT named labels and constuct UNNAMED_COUNT unnamed
labels from DATA segment SIZE bytes long using DATA_IN. */
@@ -1582,18 +1549,25 @@ input_function (tree fn_decl, struct data_in *data_in,
}
-/* Fill in the body of VAR. */
+/* Fill in the initializers of the public statics. */
static void
-input_constructor (tree var, struct data_in *data_in,
- struct lto_input_block *ib)
+input_constructors_or_inits (struct data_in *data_in,
+ struct lto_input_block *ib)
{
enum LTO_tags tag;
clear_line_info (data_in);
- LTO_DEBUG_INDENT_TOKEN ("init");
tag = input_record_start (ib);
- DECL_INITIAL (var) = input_expr_operand (ib, data_in, NULL, tag);
+ while (tag)
+ {
+ tree var;
+ var = input_expr_operand (ib, data_in, NULL, tag);
+ LTO_DEBUG_TOKEN ("init");
+ tag = input_record_start (ib);
+ DECL_INITIAL (var) = input_expr_operand (ib, data_in, NULL, tag);
+ tag = input_record_start (ib);
+ }
}
@@ -1706,14 +1680,14 @@ lto_static_init_local (void)
}
-/* Read the body form DATA for tree T and fill it in. FD and CONTEXT
- are magic cookies used to resolve global decls and types.
- SECTION_TYPE is either lto_function_body or
- lto_static_initializer. */
+/* Read the body form DATA for tree T and fill it in. File_data are
+ the global decls and types. SECTION_TYPE is either
+ LTO_section_function_body or LTO_section_static_initializer. IF
+ section type is LTO_section_function_body, FN must be the decl for
+ that function. */
static void
-lto_read_body (lto_info_fd *fd,
- lto_context *context,
- tree t,
+lto_read_body (struct lto_file_decl_data* file_data,
+ tree fn_decl,
const void *data,
enum lto_section_type section_type)
{
@@ -1721,17 +1695,7 @@ lto_read_body (lto_info_fd *fd,
= (struct lto_function_header *) data;
struct data_in data_in;
- int32_t fields_offset = sizeof (struct lto_function_header);
- int32_t fns_offset
- = fields_offset + (header->num_field_decls * sizeof (lto_ref));
- int32_t vars_offset
- = fns_offset + (header->num_fn_decls * sizeof (lto_ref));
- int32_t type_decls_offset
- = vars_offset + (header->num_var_decls * sizeof (lto_ref));
- int32_t types_offset
- = type_decls_offset + (header->num_type_decls * sizeof (lto_ref));
- int32_t named_label_offset
- = types_offset + (header->num_types * sizeof (lto_ref));
+ int32_t named_label_offset = sizeof (struct lto_function_header);
int32_t ssa_names_offset
= named_label_offset + header->named_label_size;
int32_t cfg_offset
@@ -1761,17 +1725,8 @@ lto_read_body (lto_info_fd *fd,
= {data + debug_cfg_offset, 0, header->debug_cfg_size};
struct lto_input_block debug_main
= {data + debug_main_offset, 0, header->debug_main_size};
-
- lto_debug_context.out = lto_debug_in_fun;
- lto_debug_context.indent = 0;
#endif
- lto_ref *in_field_decls = (lto_ref*)(data + fields_offset);
- lto_ref *in_fn_decls = (lto_ref*)(data + fns_offset);
- lto_ref *in_var_decls = (lto_ref*)(data + vars_offset);
- lto_ref *in_type_decls = (lto_ref*)(data + type_decls_offset);
- lto_ref *in_types = (lto_ref*)(data + types_offset);
-
struct lto_input_block ib_named_labels
= {data + named_label_offset, 0, header->named_label_size};
struct lto_input_block ib_ssa_names
@@ -1785,7 +1740,12 @@ lto_read_body (lto_info_fd *fd,
struct lto_input_block ib_main
= {data + main_offset, 0, header->main_size};
+#ifdef LTO_STREAM_DEBUGGING
+ lto_debug_context.out = lto_debug_in_fun;
+ lto_debug_context.indent = 0;
+#endif
memset (&data_in, 0, sizeof (struct data_in));
+ data_in.file_data = file_data;
data_in.strings = data + string_offset;
data_in.strings_len = header->string_size;
@@ -1795,13 +1755,9 @@ lto_read_body (lto_info_fd *fd,
gcc_assert (header->lto_header.major_version == LTO_major_version);
gcc_assert (header->lto_header.minor_version == LTO_minor_version);
- input_globals (header, fd, context, &data_in,
- in_field_decls, in_fn_decls,
- in_var_decls, in_type_decls, in_types);
-
- if (section_type == lto_function_body)
+ if (section_type == LTO_section_function_body)
{
- struct function *fn = DECL_STRUCT_FUNCTION (t);
+ struct function *fn = DECL_STRUCT_FUNCTION (fn_decl);
push_cfun (fn);
init_tree_ssa (fn);
data_in.num_named_labels = header->num_named_labels;
@@ -1835,19 +1791,20 @@ lto_read_body (lto_info_fd *fd,
/* Ensure that all our variables have annotations attached to them
so building SSA doesn't choke. */
{
- int i;
+ unsigned int i;
+ int j;
- for (i = 0; i < header->num_var_decls; i++)
- add_referenced_var (data_in.var_decls[i]);
- for (i =0; i < header->num_local_decls; i++)
- add_referenced_var (data_in.local_decls[i]);
+ for (i = 0; i < file_data->num_var_decls; i++)
+ add_referenced_var (file_data->var_decls[i]);
+ for (j = 0; j < header->num_local_decls; j++)
+ add_referenced_var (data_in.local_decls[j]);
}
#ifdef LTO_STREAM_DEBUGGING
lto_debug_context.current_data = &debug_main;
#endif
/* Set up the struct function. */
- input_function (t, &data_in, &ib_main);
+ input_function (fn_decl, &data_in, &ib_main);
/* We should now be in SSA. */
cfun->gimple_df->in_ssa_p = true;
@@ -1861,16 +1818,11 @@ lto_read_body (lto_info_fd *fd,
#ifdef LTO_STREAM_DEBUGGING
lto_debug_context.current_data = &debug_main;
#endif
- input_constructor (t, &data_in, &ib_main);
+ input_constructors_or_inits (&data_in, &ib_main);
}
clear_line_info (&data_in);
- free (data_in.field_decls);
- free (data_in.fn_decls);
- free (data_in.var_decls);
- free (data_in.type_decls);
- free (data_in.types);
- if (section_type == lto_function_body)
+ if (section_type == LTO_section_function_body)
{
free (data_in.labels);
free (data_in.local_decls_index);
@@ -1879,27 +1831,24 @@ lto_read_body (lto_info_fd *fd,
}
-/* Read in FN_DECL using DATA. FD and CONTEXT are magic cookies. */
+/* Read in FN_DECL using DATA. File_data are the global decls and types. */
void
-lto_read_function_body (lto_info_fd *fd,
- lto_context *context,
- tree fn_decl,
- const void *data)
+lto_input_function_body (struct lto_file_decl_data* file_data,
+ tree fn_decl,
+ const void *data)
{
current_function_decl = fn_decl;
- lto_read_body (fd, context, fn_decl, data, lto_function_body);
+ lto_read_body (file_data, fn_decl, data, LTO_section_function_body);
}
-/* Read in VAR_DECL using DATA. FD and CONTEXT are magic cookies. */
+/* Read in VAR_DECL using DATA. File_data are the global decls and types. */
void
-lto_read_var_init (lto_info_fd *fd,
- lto_context *context,
- tree var_decl,
- const void *data)
+lto_input_constructors_and_inits (struct lto_file_decl_data* file_data,
+ const void *data)
{
- lto_read_body (fd, context, var_decl, data, lto_static_initializer);
+ lto_read_body (file_data, NULL, data, LTO_section_static_initializer);
}
diff --git a/gcc/lto/lto-section-in.c b/gcc/lto/lto-section-in.c
index e5b815e3dbd..9c483e70a57 100644
--- a/gcc/lto/lto-section-in.c
+++ b/gcc/lto/lto-section-in.c
@@ -48,9 +48,8 @@ Boston, MA 02110-1301, USA. */
#include "dwarf2asm.h"
#include "dwarf2out.h"
#include "output.h"
-#include "lto-tags.h"
#include "lto.h"
-#include "lto-section-in.h"
+#include "lto-section.h"
#include <ctype.h>
#include "cpplib.h"
@@ -185,6 +184,79 @@ lto_input_integer (struct lto_input_block *ib, tree type)
}
}
}
+/*****************************************************************************/
+/* This part is used to recover all of the global decls and types that are */
+/* serialized out so that a table for this file can be built. */
+/* that allows the decls and types to be reconnected to the code or the */
+/* ipa summary information. */
+/*****************************************************************************/
+
+/* Load in the global vars and all of the types from the main symbol
+ table. */
+
+struct lto_file_decl_data*
+lto_read_decls (lto_info_fd *fd,
+ lto_context *context,
+ const void *data)
+{
+ struct lto_decl_header * header
+ = (struct lto_decl_header *) data;
+ struct lto_file_decl_data *data_in = xmalloc (sizeof (struct lto_file_decl_data));
+
+ int32_t fields_offset = sizeof (struct lto_decl_header);
+ int32_t fns_offset
+ = fields_offset + (header->num_field_decls * sizeof (lto_ref));
+ int32_t vars_offset
+ = fns_offset + (header->num_fn_decls * sizeof (lto_ref));
+ int32_t type_decls_offset
+ = vars_offset + (header->num_var_decls * sizeof (lto_ref));
+ int32_t types_offset
+ = type_decls_offset + (header->num_type_decls * sizeof (lto_ref));
+
+ lto_ref *in_field_decls = (lto_ref*)(data + fields_offset);
+ lto_ref *in_fn_decls = (lto_ref*)(data + fns_offset);
+ lto_ref *in_var_decls = (lto_ref*)(data + vars_offset);
+ lto_ref *in_type_decls = (lto_ref*)(data + type_decls_offset);
+ lto_ref *in_types = (lto_ref*)(data + types_offset);
+ int i;
+
+ data_in->field_decls = xcalloc (header->num_field_decls, sizeof (tree*));
+ data_in->fn_decls = xcalloc (header->num_fn_decls, sizeof (tree*));
+ data_in->var_decls = xcalloc (header->num_var_decls, sizeof (tree*));
+ data_in->type_decls = xcalloc (header->num_type_decls, sizeof (tree*));
+ data_in->types = xcalloc (header->num_types, sizeof (tree*));
+
+ for (i=0; i<header->num_field_decls; i++)
+ data_in->field_decls[i]
+ = lto_resolve_field_ref (fd, context, &in_field_decls[i]);
+ data_in->num_field_decls = header->num_field_decls;
+
+ for (i=0; i<header->num_fn_decls; i++)
+ data_in->fn_decls[i]
+ = lto_resolve_fn_ref (fd, context, &in_fn_decls[i]);
+ data_in->num_fn_decls = header->num_fn_decls;
+
+ for (i=0; i<header->num_var_decls; i++)
+ data_in->var_decls[i]
+ = lto_resolve_var_ref (fd, context, &in_var_decls[i]);
+ data_in->num_var_decls = header->num_var_decls;
+
+ for (i=0; i<header->num_type_decls; i++)
+ data_in->type_decls[i]
+ = lto_resolve_typedecl_ref (fd, context, &in_type_decls[i]);
+ data_in->num_type_decls = header->num_type_decls;
+
+ for (i=0; i<header->num_types; i++)
+ data_in->types[i] = lto_resolve_type_ref (fd, context, &in_types[i]);
+ data_in->num_types = header->num_types;
+
+ return data_in;
+}
+
+
+/*****************************************************************************/
+/* Stream debugging support code. */
+/*****************************************************************************/
#ifdef LTO_STREAM_DEBUGGING
diff --git a/gcc/lto/lto-section-in.h b/gcc/lto/lto-section-in.h
index e0b9100d25b..df6514a02e3 100644
--- a/gcc/lto/lto-section-in.h
+++ b/gcc/lto/lto-section-in.h
@@ -28,6 +28,25 @@ struct lto_input_block
unsigned int len;
};
+
+/* One of these is allocated for each object file that being compiled
+ by lto. This structure contains the tables that are needed for the
+ by the serialized functions and ipa passes to connect themselves to
+ the global types and decls as they are reconstituted. */
+struct lto_file_decl_data
+{
+ tree *field_decls; /* The field decls. */
+ tree *fn_decls; /* The function decls. */
+ tree *var_decls; /* The global or static var_decls. */
+ tree *type_decls; /* The type_decls. */
+ tree *types; /* All of the types. */
+ unsigned int num_field_decls; /* The number of field decls. */
+ unsigned int num_fn_decls; /* The number of function decls. */
+ unsigned int num_var_decls; /* The number of global or static var_decls. */
+ unsigned int num_type_decls; /* The number of type_decls. */
+ unsigned int num_types; /* All number of of the types. */
+};
+
unsigned char lto_input_1_unsigned (struct lto_input_block *);
unsigned HOST_WIDE_INT lto_input_uleb128 (struct lto_input_block *);
unsigned HOST_WIDEST_INT lto_input_widest_uint_uleb128 (struct lto_input_block *);
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index f84476e05e5..3ae77152410 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -2133,22 +2133,6 @@ lto_read_variable_formal_parameter_constant_DIE (lto_info_fd *fd,
/*at_end=*/0);
}
- /* If there is an initializer, read it now. */
- if (!declaration)
- {
- const void *init;
- lto_file *file;
- const char *name_str;
-
- name_str = IDENTIFIER_POINTER (asm_name);
- file = fd->base.file;
- init = file->vtable->map_var_init (file, name_str);
- if (init)
- {
- lto_read_var_init (fd, context, decl, init);
- file->vtable->unmap_var_init (file, name_str, init);
- }
- }
/* If this variable has already been declared, merge the
declarations. */
decl = lto_symtab_merge_var (decl);
@@ -2415,14 +2399,27 @@ lto_read_abbrev (lto_info_fd *fd)
static const void *
lto_get_body (lto_info_fd *fd,
lto_context *context ATTRIBUTE_UNUSED,
- tree decl)
+ enum lto_section_type section_type,
+ const char *name)
{
lto_file *file;
- const char *name;
file = fd->base.file;
- name = IDENTIFIER_POINTER (DECL_NAME (decl));
- return file->vtable->map_fn_body (file, name);
+ return file->vtable->map_section (file, section_type, name);
+}
+
+/* Read the constructors and initsof FD if possible. */
+
+static void
+lto_materialize_constructors_and_inits (lto_info_fd *fd,
+ lto_context *context,
+ struct lto_file_decl_data * file_data)
+{
+ lto_file *file = fd->base.file;
+ const void *body = lto_get_body (fd, context, LTO_section_static_initializer, NULL);
+
+ lto_input_constructors_and_inits (file_data, body);
+ file->vtable->unmap_section (file, NULL, body);
}
/* Read the function body for DECL out of FD if possible. */
@@ -2430,11 +2427,12 @@ lto_get_body (lto_info_fd *fd,
static void
lto_materialize_function (lto_info_fd *fd,
lto_context *context,
+ struct lto_file_decl_data * file_data,
tree decl)
{
lto_file *file = fd->base.file;
const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
- const void *body = lto_get_body (fd, context, decl);
+ const void *body = lto_get_body (fd, context, LTO_section_function_body, name);
if (body)
{
@@ -2443,8 +2441,8 @@ lto_materialize_function (lto_info_fd *fd,
DECL_EXTERNAL (decl) = 0;
allocate_struct_function (decl);
- lto_read_function_body (fd, context, decl, body);
- file->vtable->unmap_fn_body (file, name, body);
+ lto_input_function_body (file_data, decl, body);
+ file->vtable->unmap_section (file, name, body);
}
else
DECL_EXTERNAL (decl) = 1;
@@ -2457,6 +2455,20 @@ lto_materialize_function (lto_info_fd *fd,
cgraph_finalize_function (decl, /*nested=*/false);
}
+/* Read the indirection tables for the global decls and types. */
+
+static struct lto_file_decl_data *
+lto_materialize_file_data (lto_info_fd *fd,
+ lto_context *context)
+{
+ lto_file *file = fd->base.file;
+ const void *body = lto_get_body (fd, context, LTO_section_decls, NULL);
+ struct lto_file_decl_data * file_data = lto_read_decls (fd, context, body);
+
+ file->vtable->unmap_section (file, NULL, body);
+ return file_data;
+}
+
static tree
lto_read_subroutine_type_subprogram_DIE (lto_info_fd *fd,
lto_die_ptr die ATTRIBUTE_UNUSED,
@@ -2682,13 +2694,13 @@ lto_read_subroutine_type_subprogram_DIE (lto_info_fd *fd,
merging heuristics work properly. The best way to do that is
to look for the function's body. */
{
- const void *body = lto_get_body (fd, context, result);
const char *name = IDENTIFIER_POINTER (DECL_NAME (result));
+ const void *body = lto_get_body (fd, context, LTO_section_function_body, name);
if (body)
{
DECL_EXTERNAL (result) = 0;
- fd->base.file->vtable->unmap_fn_body (fd->base.file, name, body);
+ fd->base.file->vtable->unmap_section (fd->base.file, name, body);
}
else
DECL_EXTERNAL (result) = 1;
@@ -3494,6 +3506,7 @@ lto_set_cu_context (lto_context *context, lto_info_fd *fd,
bool
lto_file_read (lto_file *file)
{
+ struct lto_file_decl_data* file_data;
size_t i;
/* The descriptor for the .debug_info section. */
lto_fd *fd;
@@ -3550,13 +3563,17 @@ lto_file_read (lto_file *file)
lto_read_DIE (&file->debug_info, &context, NULL);
}
+ file_data = lto_materialize_file_data (&file->debug_info, &context);
+
+ lto_materialize_constructors_and_inits (&file->debug_info, &context, file_data);
+
/* Read in function bodies now that we have the full DWARF tree
available. */
for (j = 0;
VEC_iterate (tree, file->debug_info.unmaterialized_fndecls,
j, decl);
j++)
- lto_materialize_function (&file->debug_info, &context, decl);
+ lto_materialize_function (&file->debug_info, &context, file_data, decl);
}
return true;
diff --git a/gcc/lto/lto.h b/gcc/lto/lto.h
index 4863b33591f..0885311c447 100644
--- a/gcc/lto/lto.h
+++ b/gcc/lto/lto.h
@@ -28,6 +28,8 @@ Boston, MA 02110-1301, USA. */
#include "tree.h"
#include "vec.h"
#include <inttypes.h>
+#include "lto-header.h"
+#include "lto-section-in.h"
/* Forward Declarations */
@@ -147,20 +149,15 @@ lto_abbrev_fd;
/* The virtual function table for an lto_file. */
typedef struct lto_file_vtable_struct GTY(())
{
- /* Return the address of the function-body data for the function
- named FN, or NULL if the data is not available. */
- const void *(*map_fn_body)(struct lto_file_struct *file, const char *fn);
+ /* Return the address of the data in an lto section.
+ LTO_SECTION_TYPE specifies the type of the section. If this is a
+ function or static initializer use FN, Returns the pointer to the
+ data or NULL if the data is not available. */
+ const void *(*map_section)(struct lto_file_struct *file, enum lto_section_type, const char *fn);
/* DATA is the non-NULL address returned by a previous call to
- MAP_FN_BODY, with the same value of FN. Release any resources
+ MAP_SECTION, with the same value of FN. Release any resources
allocated by MAP_FN_BODY. */
- void (*unmap_fn_body)(struct lto_file_struct *file, const char *fn, const void *data);
- /* Return the address of the variable-initializer data for the function
- named VAR, or NULL if the data is not available. */
- const void *(*map_var_init)(struct lto_file_struct *file, const char *var);
- /* DATA is the non-NULL address returned by a previous call to
- MAP_VAR_INIT, with the same value of VAR. Release any resources
- allocated by MAP_VAR_INIT. */
- void (*unmap_var_init)(struct lto_file_struct *file, const char *var, const void *data);
+ void (*unmap_section)(struct lto_file_struct *file, const char *fn, const void *data);
}
lto_file_vtable;
@@ -243,35 +240,30 @@ extern lto_file *lto_elf_file_open (const char *filename);
/* Close an ELF input file. */
extern void lto_elf_file_close (lto_file *file);
-/* lto-read.c */
+/* lto-function-in.c */
+
+struct lto_file_decl_data* lto_read_decls (lto_info_fd *, lto_context *, const void *data);
/* FN is a FUNCTION_DECL. DATA is the LTO data written out during
- ordinary compilation, encoding the body of FN. FD and CONTEXT may
- be passed back to the lto_resolve__ref functions to retrieve
- information about glogal entities. Upon return, DECL_SAVED_TREE
- for FN contains the reconstituted body of FN and DECL_INITIAL
- contains the BLOCK tree for the function. However, it is not this
- function's responsibility to provide FN to the optimizers or
- code-generators; that will be done by the caller. */
+ ordinary compilation, encoding the body of FN. FILE_DATA are the
+ tables holding all of the global types and decls used by FN. Upon
+ return, DECL_SAVED_TREE for FN contains the reconstituted body of
+ FN and DECL_INITIAL contains the BLOCK tree for the function.
+ However, it is not this function's responsibility to provide FN to
+ the optimizers or code-generators; that will be done by the
+ caller. */
extern void
-lto_read_function_body (lto_info_fd *fd,
- lto_context *context,
+lto_input_function_body (struct lto_file_decl_data* file_data,
tree fn,
const void *data);
-/* VAR is a VAR_DECL. DATA is the LTO data written out during
- ordinary compilation, encoding the initializer for VAR. FD and
- CONTEXT are as for lto_read_function_body. Upon return,
- DECL_INITIAL for VAR contains the reconsitituted initializer for
- VAR. However, it is not this function's responsibility to provide
- VAR to the optimizers or code-generators; that will be done by the
- caller. */
+/* DATA is the LTO data written out during ordinary compilation,
+ encoding the initializers for the static and external vars.
+ FILE_DATA are the tables holding all of the global types and decls
+ used by FN. */
extern void
-lto_read_var_init (lto_info_fd *fd,
- lto_context *context,
- tree var,
- const void *data);
-
+lto_input_constructors_and_inits (struct lto_file_decl_data* file_data,
+ const void *data);
/* lto-symtab.c */
/* The NEW_VAR (a VAR_DECL) has just been read. If there is an
diff --git a/gcc/passes.c b/gcc/passes.c
index 30db326312e..47b5a30c42d 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -538,7 +538,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_rebuild_cgraph_edges);
NEXT_PASS (pass_inline_parameters);
}
- NEXT_PASS (pass_ipa_lto_out);
+ NEXT_PASS (pass_ipa_lto_gimple_out);
NEXT_PASS (pass_ipa_increase_alignment);
NEXT_PASS (pass_ipa_matrix_reorg);
NEXT_PASS (pass_ipa_cp);
@@ -547,7 +547,10 @@ init_optimization_passes (void)
NEXT_PASS (pass_ipa_pure_const);
NEXT_PASS (pass_ipa_type_escape);
NEXT_PASS (pass_ipa_pta);
- NEXT_PASS (pass_ipa_struct_reorg);
+ NEXT_PASS (pass_ipa_struct_reorg);
+ /* This must be the last ipa pass. */
+ NEXT_PASS (pass_ipa_lto_finish_out);
+
*p = NULL;
/* These passes are run after IPA passes on every function that is being
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 5d4637806ab..d4ffb6ceb31 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -335,7 +335,7 @@ extern struct tree_opt_pass pass_reset_cc_flags;
/* IPA Passes */
extern struct tree_opt_pass pass_ipa_matrix_reorg;
extern struct tree_opt_pass pass_ipa_cp;
-extern struct tree_opt_pass pass_ipa_lto_out;
+extern struct tree_opt_pass pass_ipa_lto_gimple_out;
extern struct tree_opt_pass pass_ipa_inline;
extern struct tree_opt_pass pass_ipa_early_inline;
extern struct tree_opt_pass pass_ipa_reference;
@@ -343,6 +343,7 @@ extern struct tree_opt_pass pass_ipa_pure_const;
extern struct tree_opt_pass pass_ipa_type_escape;
extern struct tree_opt_pass pass_ipa_pta;
extern struct tree_opt_pass pass_ipa_struct_reorg;
+extern struct tree_opt_pass pass_ipa_lto_finish_out;
extern struct tree_opt_pass pass_early_local_passes;
extern struct tree_opt_pass pass_ipa_increase_alignment;
extern struct tree_opt_pass pass_ipa_function_and_variable_visibility;
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 6644cd9e44f..444bb99f51d 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1954,7 +1954,6 @@ init_scc_vn (void)
size_t i;
int j;
int *rpo_numbers_temp;
- basic_block bb;
calculate_dominance_info (CDI_DOMINATORS);
sccstack = NULL;