Commit b9393656 by Diego Novillo Committed by Diego Novillo

tree-streamer-out.c (lto_output_ts_decl_with_vis_tree_pointers): Call…

tree-streamer-out.c (lto_output_ts_decl_with_vis_tree_pointers): Call stream_write_tree instead of output_record_start.

	* tree-streamer-out.c (lto_output_ts_decl_with_vis_tree_pointers):
	Call stream_write_tree instead of output_record_start.
	(lto_output_ts_binfo_tree_pointers): Likewise.

	* streamer-hooks.h (stream_write_tree): Move from tree-streamer.h.
	Convert it to a macro.
	(stream_read_tree): Likewise.

	* lto-streamer.h (lto_stream_as_builtin_p): Move ...
	* tree-streamer.h (lto_stream_as_builtin_p): ... here.

	* lto-streamer-in.c (lto_read_tree): Call lto_streamer_cache_append
	and tree_read_bitfields.
	* lto-streamer-out.c (lto_is_streamable): Move from lto-streamer.c
	(lto_write_tree): Call it.
	* lto-streamer.c (lto_is_streamable): Move to lto-streamer-out.c
	* streamer-hooks.h (struct streamer_hooks): Remove fields
	name, is_streamable and alloc_tree. Update all users.
	* tree-streamer-in.c (tree_read_bitfields): Factor out of ...
	(lto_materialize_tree): ... here.
	Handle CALL_EXPR codes.
	Remove call to lto_streamer_cache_append.
	* tree-streamer-out.c (lto_output_tree_header): Handle
	CALL_EXPR nodes.
	* tree-streamer.h (tree_read_bitfields): Declare.

	* Makefile.in (TREE_STREAMER_H): Add STREAMER_HOOKS_H.
	(gimple-streamer-in.o): Add dependency on TREE_STREAMER_H.
	* tree-streamer.h (stream_read_tree): New.  Replace all calls
	to lto_input_tree with it.
	(stream_write_tree): New.  Replace all calls to lto_output_tree,
	lto_output_tree_ref and lto_output_tree_or_ref with it.
	* lto-streamer-in.c (lto_read_tree): Inline code from
	lto_streamer_read_tree.
	(lto_input_tree): Move from tree-streamer-in.c.
	* lto-streamer-out.c (lto_output_tree_ref): Make static.
	Remove handling of NULL values for EXPR.
	Do not handle EXPRs that are not indexable.
	(lto_write_tree): Move from tree-streamer-out.c.
	Inline lto_streamer_write_tree.
	(lto_output_tree): Move from tree-streamer-out.c.
	If REF_P is true and EXPR is indexable, call lto_output_tree_ref.
	* lto-streamer.c (lto_record_common_node): Move to tree-streamer.c.
	(lto_preload_common_nodes): Likewise.
	Remove assertions and adjustments for nodes
	main_identifier_node, ptrdiff_type_node and fileptr_type_node.
	(lto_streamer_hooks_init): Set streamer_hooks.write_tree to
	lto_output_tree and streamer_hooks.read_tree to
	lto_input_tree.
	* lto-streamer.h (lto_input_tree): Declare.
	(lto_output_tree_ref): Remove.
	* streamer-hooks.h (struct streamer_hooks): Remove fields
	preload_common_nodes, indexable_with_decls_p,
	pack_value_fields, unpack_value_fields, output_tree_header and
	has_unique_integer_csts_p.
	Update all users.
	* tree-streamer-in.c (lto_materialize_tree): Make extern.
	(lto_input_tree_pointers): Likewise.
	(lto_read_tree): Move to lto-streamer-in.c.
	(lto_input_integer_cst): Make extern.
	(lto_get_pickled_tree): Likewise.
	(lto_get_builtin_tree): Likewise.
	(lto_input_tree): Move to lto-streamer-in.c.
	* tree-streamer-out.c (pack_value_fields): Make extern.
	(lto_output_tree_or_ref): Remove.  Replace all callers with
	calls to stream_write_tree.
	(lto_output_builtin_tree): Make extern.
	(lto_streamer_write_tree): Inline into lto_write_tree.
	(lto_output_tree_pointers): Make extern.
	(lto_output_tree_header): Likewise.
	(lto_output_integer_cst): Likewise.
	(lto_write_tree): Move to lto-streamer-out.c.
	(lto_output_tree): Likewise.
	* tree-streamer.c (lto_record_common_node): Move from
	lto-streamer.c
	(preload_common_nodes): Likewise.
	(lto_streamer_cache_create): Call it.
	* tree-streamer.h: Include streamer-hooks.h.
	(stream_write_tree): New.
	(stream_read_tree): New.
	(lto_input_tree): Remove.
	(lto_materialize_tree): Declare.
	(lto_input_tree_pointers): Declare.
	(lto_get_pickled_tree): Declare.
	(lto_get_builtin_tree): Declare.
	(lto_input_integer_cst): Declare.
	(lto_output_tree_header): Declare.
	(pack_value_fields): Declare.
	(lto_output_tree_pointers): Declare.
	(lto_output_integer_cst): Declare.
	(lto_output_builtin_tree): Declare.

From-SVN: r177661
parent cf596bc7
2011-08-11 Diego Novillo <dnovillo@google.com>
* tree-streamer-out.c (lto_output_ts_decl_with_vis_tree_pointers):
Call stream_write_tree instead of output_record_start.
(lto_output_ts_binfo_tree_pointers): Likewise.
* streamer-hooks.h (stream_write_tree): Move from tree-streamer.h.
Convert it to a macro.
(stream_read_tree): Likewise.
* lto-streamer.h (lto_stream_as_builtin_p): Move ...
* tree-streamer.h (lto_stream_as_builtin_p): ... here.
* lto-streamer-in.c (lto_read_tree): Call lto_streamer_cache_append
and tree_read_bitfields.
* lto-streamer-out.c (lto_is_streamable): Move from lto-streamer.c
(lto_write_tree): Call it.
* lto-streamer.c (lto_is_streamable): Move to lto-streamer-out.c
* streamer-hooks.h (struct streamer_hooks): Remove fields
name, is_streamable and alloc_tree. Update all users.
* tree-streamer-in.c (tree_read_bitfields): Factor out of ...
(lto_materialize_tree): ... here.
Handle CALL_EXPR codes.
Remove call to lto_streamer_cache_append.
* tree-streamer-out.c (lto_output_tree_header): Handle
CALL_EXPR nodes.
* tree-streamer.h (tree_read_bitfields): Declare.
* Makefile.in (TREE_STREAMER_H): Add STREAMER_HOOKS_H.
(gimple-streamer-in.o): Add dependency on TREE_STREAMER_H.
* tree-streamer.h (stream_read_tree): New. Replace all calls
to lto_input_tree with it.
(stream_write_tree): New. Replace all calls to lto_output_tree,
lto_output_tree_ref and lto_output_tree_or_ref with it.
* lto-streamer-in.c (lto_read_tree): Inline code from
lto_streamer_read_tree.
(lto_input_tree): Move from tree-streamer-in.c.
* lto-streamer-out.c (lto_output_tree_ref): Make static.
Remove handling of NULL values for EXPR.
Do not handle EXPRs that are not indexable.
(lto_write_tree): Move from tree-streamer-out.c.
Inline lto_streamer_write_tree.
(lto_output_tree): Move from tree-streamer-out.c.
If REF_P is true and EXPR is indexable, call lto_output_tree_ref.
* lto-streamer.c (lto_record_common_node): Move to tree-streamer.c.
(lto_preload_common_nodes): Likewise.
Remove assertions and adjustments for nodes
main_identifier_node, ptrdiff_type_node and fileptr_type_node.
(lto_streamer_hooks_init): Set streamer_hooks.write_tree to
lto_output_tree and streamer_hooks.read_tree to
lto_input_tree.
* lto-streamer.h (lto_input_tree): Declare.
(lto_output_tree_ref): Remove.
* streamer-hooks.h (struct streamer_hooks): Remove fields
preload_common_nodes, indexable_with_decls_p,
pack_value_fields, unpack_value_fields and output_tree_header.
Update all users.
* tree-streamer-in.c (lto_materialize_tree): Make extern.
(lto_input_tree_pointers): Likewise.
(lto_read_tree): Move to lto-streamer-in.c.
(lto_input_integer_cst): Make extern.
(lto_get_pickled_tree): Likewise.
(lto_get_builtin_tree): Likewise.
(lto_input_tree): Move to lto-streamer-in.c.
* tree-streamer-out.c (pack_value_fields): Make extern.
(lto_output_tree_or_ref): Remove. Replace all callers with
calls to stream_write_tree.
(lto_output_builtin_tree): Make extern.
(lto_streamer_write_tree): Inline into lto_write_tree.
(lto_output_tree_pointers): Make extern.
(lto_output_tree_header): Likewise.
(lto_output_integer_cst): Likewise.
(lto_write_tree): Move to lto-streamer-out.c.
(lto_output_tree): Likewise.
* tree-streamer.c (lto_record_common_node): Move from
lto-streamer.c
(preload_common_nodes): Likewise.
(lto_streamer_cache_create): Call it.
* tree-streamer.h: Include streamer-hooks.h.
(stream_write_tree): New.
(stream_read_tree): New.
(lto_input_tree): Remove.
(lto_materialize_tree): Declare.
(lto_input_tree_pointers): Declare.
(lto_get_pickled_tree): Declare.
(lto_get_builtin_tree): Declare.
(lto_input_integer_cst): Declare.
(lto_output_tree_header): Declare.
(pack_value_fields): Declare.
(lto_output_tree_pointers): Declare.
(lto_output_integer_cst): Declare.
(lto_output_builtin_tree): Declare.
2011-08-11 Sergey Grechanik <mouseentity@ispras.ru> 2011-08-11 Sergey Grechanik <mouseentity@ispras.ru>
* sel-sched-ir.c (get_seqno_of_a_pred): Rename to * sel-sched-ir.c (get_seqno_of_a_pred): Rename to
......
...@@ -1000,7 +1000,8 @@ LTO_STREAMER_H = lto-streamer.h $(LINKER_PLUGIN_API_H) $(TARGET_H) \ ...@@ -1000,7 +1000,8 @@ LTO_STREAMER_H = lto-streamer.h $(LINKER_PLUGIN_API_H) $(TARGET_H) \
DATA_STREAMER_H = data-streamer.h $(VEC_H) $(LTO_STREAMER_H) DATA_STREAMER_H = data-streamer.h $(VEC_H) $(LTO_STREAMER_H)
GIMPLE_STREAMER_H = gimple-streamer.h $(LTO_STREAMER_H) $(BASIC_BLOCK_H) \ GIMPLE_STREAMER_H = gimple-streamer.h $(LTO_STREAMER_H) $(BASIC_BLOCK_H) \
$(FUNCTION_H) $(FUNCTION_H)
TREE_STREAMER_H = tree-streamer.h $(TREE_H) $(LTO_STREAMER_H) TREE_STREAMER_H = tree-streamer.h $(TREE_H) $(LTO_STREAMER_H) \
$(STREAMER_HOOKS_H)
STREAMER_HOOKS_H = streamer-hooks.h $(TREE_H) STREAMER_HOOKS_H = streamer-hooks.h $(TREE_H)
TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H) TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H)
IPA_PROP_H = ipa-prop.h $(TREE_H) $(VEC_H) $(CGRAPH_H) $(GIMPLE_H) alloc-pool.h IPA_PROP_H = ipa-prop.h $(TREE_H) $(VEC_H) $(CGRAPH_H) $(GIMPLE_H) alloc-pool.h
...@@ -2305,7 +2306,7 @@ gimple-streamer-in.o: gimple-streamer-in.c $(CONFIG_H) $(SYSTEM_H) \ ...@@ -2305,7 +2306,7 @@ gimple-streamer-in.o: gimple-streamer-in.c $(CONFIG_H) $(SYSTEM_H) \
$(TREE_STREAMER_H) $(DIAGNOSTIC_H) $(TREE_STREAMER_H) $(DIAGNOSTIC_H)
gimple-streamer-out.o: gimple-streamer-out.c $(CONFIG_H) $(SYSTEM_H) \ gimple-streamer-out.o: gimple-streamer-out.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(GIMPLE_STREAMER_H) $(DATA_STREAMER_H) $(TREE_FLOW_H) \ coretypes.h $(GIMPLE_STREAMER_H) $(DATA_STREAMER_H) $(TREE_FLOW_H) \
$(LTO_STREAMER_H) $(LTO_STREAMER_H) $(TREE_STREAMER_H)
tree-streamer.o: tree-streamer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ tree-streamer.o: tree-streamer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TREE_STREAMER_H) $(STREAMER_HOOKS_H) $(TREE_STREAMER_H) $(STREAMER_HOOKS_H)
tree-streamer-in.o: tree-streamer-in.c $(CONFIG_H) $(SYSTEM_H) \ tree-streamer-in.o: tree-streamer-in.c $(CONFIG_H) $(SYSTEM_H) \
......
...@@ -52,7 +52,7 @@ input_phi (struct lto_input_block *ib, basic_block bb, struct data_in *data_in, ...@@ -52,7 +52,7 @@ input_phi (struct lto_input_block *ib, basic_block bb, struct data_in *data_in,
were in the original program. */ were in the original program. */
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
tree def = lto_input_tree (ib, data_in); tree def = stream_read_tree (ib, data_in);
int src_index = lto_input_uleb128 (ib); int src_index = lto_input_uleb128 (ib);
location_t arg_loc = lto_input_location (ib, data_in); location_t arg_loc = lto_input_location (ib, data_in);
basic_block sbb = BASIC_BLOCK_FOR_FUNCTION (fn, src_index); basic_block sbb = BASIC_BLOCK_FOR_FUNCTION (fn, src_index);
...@@ -103,7 +103,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, ...@@ -103,7 +103,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
gimple_set_location (stmt, lto_input_location (ib, data_in)); gimple_set_location (stmt, lto_input_location (ib, data_in));
/* Read lexical block reference. */ /* Read lexical block reference. */
gimple_set_block (stmt, lto_input_tree (ib, data_in)); gimple_set_block (stmt, stream_read_tree (ib, data_in));
/* Read in all the operands. */ /* Read in all the operands. */
switch (code) switch (code)
...@@ -113,7 +113,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, ...@@ -113,7 +113,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
break; break;
case GIMPLE_EH_MUST_NOT_THROW: case GIMPLE_EH_MUST_NOT_THROW:
gimple_eh_must_not_throw_set_fndecl (stmt, lto_input_tree (ib, data_in)); gimple_eh_must_not_throw_set_fndecl (stmt, stream_read_tree (ib, data_in));
break; break;
case GIMPLE_EH_DISPATCH: case GIMPLE_EH_DISPATCH:
...@@ -143,7 +143,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, ...@@ -143,7 +143,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
case GIMPLE_DEBUG: case GIMPLE_DEBUG:
for (i = 0; i < num_ops; i++) for (i = 0; i < num_ops; i++)
{ {
tree op = lto_input_tree (ib, data_in); tree op = stream_read_tree (ib, data_in);
gimple_set_op (stmt, i, op); gimple_set_op (stmt, i, op);
if (!op) if (!op)
continue; continue;
...@@ -223,7 +223,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, ...@@ -223,7 +223,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
gimple_call_set_internal_fn gimple_call_set_internal_fn
(stmt, lto_input_enum (ib, internal_fn, IFN_LAST)); (stmt, lto_input_enum (ib, internal_fn, IFN_LAST));
else else
gimple_call_set_fntype (stmt, lto_input_tree (ib, data_in)); gimple_call_set_fntype (stmt, stream_read_tree (ib, data_in));
} }
break; break;
......
...@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "data-streamer.h" #include "data-streamer.h"
#include "gimple-streamer.h" #include "gimple-streamer.h"
#include "lto-streamer.h" #include "lto-streamer.h"
#include "tree-streamer.h"
/* Output PHI function PHI to the main stream in OB. */ /* Output PHI function PHI to the main stream in OB. */
...@@ -40,7 +41,7 @@ output_phi (struct output_block *ob, gimple phi) ...@@ -40,7 +41,7 @@ output_phi (struct output_block *ob, gimple phi)
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
lto_output_tree_ref (ob, gimple_phi_arg_def (phi, i)); stream_write_tree (ob, gimple_phi_arg_def (phi, i), true);
output_uleb128 (ob, gimple_phi_arg_edge (phi, i)->src->index); output_uleb128 (ob, gimple_phi_arg_edge (phi, i)->src->index);
lto_output_location (ob, gimple_phi_arg_location (phi, i)); lto_output_location (ob, gimple_phi_arg_location (phi, i));
} }
...@@ -76,7 +77,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) ...@@ -76,7 +77,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
lto_output_location (ob, gimple_location (stmt)); lto_output_location (ob, gimple_location (stmt));
/* Emit the lexical block holding STMT. */ /* Emit the lexical block holding STMT. */
lto_output_tree (ob, gimple_block (stmt), true); stream_write_tree (ob, gimple_block (stmt), true);
/* Emit the operands. */ /* Emit the operands. */
switch (gimple_code (stmt)) switch (gimple_code (stmt))
...@@ -86,7 +87,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) ...@@ -86,7 +87,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
break; break;
case GIMPLE_EH_MUST_NOT_THROW: case GIMPLE_EH_MUST_NOT_THROW:
lto_output_tree_ref (ob, gimple_eh_must_not_throw_fndecl (stmt)); stream_write_tree (ob, gimple_eh_must_not_throw_fndecl (stmt), true);
break; break;
case GIMPLE_EH_DISPATCH: case GIMPLE_EH_DISPATCH:
...@@ -133,7 +134,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) ...@@ -133,7 +134,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
TREE_THIS_VOLATILE (*basep) = volatilep; TREE_THIS_VOLATILE (*basep) = volatilep;
} }
} }
lto_output_tree_ref (ob, op); stream_write_tree (ob, op, true);
} }
if (is_gimple_call (stmt)) if (is_gimple_call (stmt))
{ {
...@@ -141,7 +142,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) ...@@ -141,7 +142,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
lto_output_enum (ob->main_stream, internal_fn, lto_output_enum (ob->main_stream, internal_fn,
IFN_LAST, gimple_call_internal_fn (stmt)); IFN_LAST, gimple_call_internal_fn (stmt));
else else
lto_output_tree_ref (ob, gimple_call_fntype (stmt)); stream_write_tree (ob, gimple_call_fntype (stmt), true);
} }
break; break;
......
...@@ -2407,7 +2407,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data, ...@@ -2407,7 +2407,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
struct condition c; struct condition c;
c.operand_num = lto_input_uleb128 (&ib); c.operand_num = lto_input_uleb128 (&ib);
c.code = (enum tree_code) lto_input_uleb128 (&ib); c.code = (enum tree_code) lto_input_uleb128 (&ib);
c.val = lto_input_tree (&ib, data_in); c.val = stream_read_tree (&ib, data_in);
VEC_safe_push (condition, gc, info->conds, &c); VEC_safe_push (condition, gc, info->conds, &c);
} }
count2 = lto_input_uleb128 (&ib); count2 = lto_input_uleb128 (&ib);
...@@ -2552,7 +2552,7 @@ inline_write_summary (cgraph_node_set set, ...@@ -2552,7 +2552,7 @@ inline_write_summary (cgraph_node_set set,
c->operand_num); c->operand_num);
lto_output_uleb128_stream (ob->main_stream, lto_output_uleb128_stream (ob->main_stream,
c->code); c->code);
lto_output_tree (ob, c->val, true); stream_write_tree (ob, c->val, true);
} }
lto_output_uleb128_stream (ob->main_stream, lto_output_uleb128_stream (ob->main_stream,
VEC_length (size_time_entry, info->entry)); VEC_length (size_time_entry, info->entry));
......
...@@ -2652,13 +2652,13 @@ ipa_write_jump_function (struct output_block *ob, ...@@ -2652,13 +2652,13 @@ ipa_write_jump_function (struct output_block *ob,
case IPA_JF_UNKNOWN: case IPA_JF_UNKNOWN:
break; break;
case IPA_JF_KNOWN_TYPE: case IPA_JF_KNOWN_TYPE:
lto_output_tree (ob, jump_func->value.base_binfo, true); stream_write_tree (ob, jump_func->value.base_binfo, true);
break; break;
case IPA_JF_CONST: case IPA_JF_CONST:
lto_output_tree (ob, jump_func->value.constant, true); stream_write_tree (ob, jump_func->value.constant, true);
break; break;
case IPA_JF_PASS_THROUGH: case IPA_JF_PASS_THROUGH:
lto_output_tree (ob, jump_func->value.pass_through.operand, true); stream_write_tree (ob, jump_func->value.pass_through.operand, true);
lto_output_uleb128_stream (ob->main_stream, lto_output_uleb128_stream (ob->main_stream,
jump_func->value.pass_through.formal_id); jump_func->value.pass_through.formal_id);
lto_output_uleb128_stream (ob->main_stream, lto_output_uleb128_stream (ob->main_stream,
...@@ -2667,13 +2667,13 @@ ipa_write_jump_function (struct output_block *ob, ...@@ -2667,13 +2667,13 @@ ipa_write_jump_function (struct output_block *ob,
case IPA_JF_ANCESTOR: case IPA_JF_ANCESTOR:
lto_output_uleb128_stream (ob->main_stream, lto_output_uleb128_stream (ob->main_stream,
jump_func->value.ancestor.offset); jump_func->value.ancestor.offset);
lto_output_tree (ob, jump_func->value.ancestor.type, true); stream_write_tree (ob, jump_func->value.ancestor.type, true);
lto_output_uleb128_stream (ob->main_stream, lto_output_uleb128_stream (ob->main_stream,
jump_func->value.ancestor.formal_id); jump_func->value.ancestor.formal_id);
break; break;
case IPA_JF_CONST_MEMBER_PTR: case IPA_JF_CONST_MEMBER_PTR:
lto_output_tree (ob, jump_func->value.member_cst.pfn, true); stream_write_tree (ob, jump_func->value.member_cst.pfn, true);
lto_output_tree (ob, jump_func->value.member_cst.delta, false); stream_write_tree (ob, jump_func->value.member_cst.delta, false);
break; break;
} }
} }
...@@ -2692,24 +2692,24 @@ ipa_read_jump_function (struct lto_input_block *ib, ...@@ -2692,24 +2692,24 @@ ipa_read_jump_function (struct lto_input_block *ib,
case IPA_JF_UNKNOWN: case IPA_JF_UNKNOWN:
break; break;
case IPA_JF_KNOWN_TYPE: case IPA_JF_KNOWN_TYPE:
jump_func->value.base_binfo = lto_input_tree (ib, data_in); jump_func->value.base_binfo = stream_read_tree (ib, data_in);
break; break;
case IPA_JF_CONST: case IPA_JF_CONST:
jump_func->value.constant = lto_input_tree (ib, data_in); jump_func->value.constant = stream_read_tree (ib, data_in);
break; break;
case IPA_JF_PASS_THROUGH: case IPA_JF_PASS_THROUGH:
jump_func->value.pass_through.operand = lto_input_tree (ib, data_in); jump_func->value.pass_through.operand = stream_read_tree (ib, data_in);
jump_func->value.pass_through.formal_id = lto_input_uleb128 (ib); jump_func->value.pass_through.formal_id = lto_input_uleb128 (ib);
jump_func->value.pass_through.operation = (enum tree_code) lto_input_uleb128 (ib); jump_func->value.pass_through.operation = (enum tree_code) lto_input_uleb128 (ib);
break; break;
case IPA_JF_ANCESTOR: case IPA_JF_ANCESTOR:
jump_func->value.ancestor.offset = lto_input_uleb128 (ib); jump_func->value.ancestor.offset = lto_input_uleb128 (ib);
jump_func->value.ancestor.type = lto_input_tree (ib, data_in); jump_func->value.ancestor.type = stream_read_tree (ib, data_in);
jump_func->value.ancestor.formal_id = lto_input_uleb128 (ib); jump_func->value.ancestor.formal_id = lto_input_uleb128 (ib);
break; break;
case IPA_JF_CONST_MEMBER_PTR: case IPA_JF_CONST_MEMBER_PTR:
jump_func->value.member_cst.pfn = lto_input_tree (ib, data_in); jump_func->value.member_cst.pfn = stream_read_tree (ib, data_in);
jump_func->value.member_cst.delta = lto_input_tree (ib, data_in); jump_func->value.member_cst.delta = stream_read_tree (ib, data_in);
break; break;
} }
} }
...@@ -2733,7 +2733,7 @@ ipa_write_indirect_edge_info (struct output_block *ob, ...@@ -2733,7 +2733,7 @@ ipa_write_indirect_edge_info (struct output_block *ob,
if (ii->polymorphic) if (ii->polymorphic)
{ {
lto_output_sleb128_stream (ob->main_stream, ii->otr_token); lto_output_sleb128_stream (ob->main_stream, ii->otr_token);
lto_output_tree (ob, ii->otr_type, true); stream_write_tree (ob, ii->otr_type, true);
} }
} }
...@@ -2755,7 +2755,7 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib, ...@@ -2755,7 +2755,7 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib,
if (ii->polymorphic) if (ii->polymorphic)
{ {
ii->otr_token = (HOST_WIDE_INT) lto_input_sleb128 (ib); ii->otr_token = (HOST_WIDE_INT) lto_input_sleb128 (ib);
ii->otr_type = lto_input_tree (ib, data_in); ii->otr_type = stream_read_tree (ib, data_in);
} }
} }
......
...@@ -1581,7 +1581,7 @@ output_node_opt_summary (struct output_block *ob, ...@@ -1581,7 +1581,7 @@ output_node_opt_summary (struct output_block *ob,
mechanism to store function local declarations into summaries. */ mechanism to store function local declarations into summaries. */
gcc_assert (parm); gcc_assert (parm);
lto_output_uleb128_stream (ob->main_stream, parm_num); lto_output_uleb128_stream (ob->main_stream, parm_num);
lto_output_tree (ob, map->new_tree, true); stream_write_tree (ob, map->new_tree, true);
bp = bitpack_create (ob->main_stream); bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, map->replace_p, 1); bp_pack_value (&bp, map->replace_p, 1);
bp_pack_value (&bp, map->ref_p, 1); bp_pack_value (&bp, map->ref_p, 1);
...@@ -1688,7 +1688,7 @@ input_node_opt_summary (struct cgraph_node *node, ...@@ -1688,7 +1688,7 @@ input_node_opt_summary (struct cgraph_node *node,
parm_num --; parm_num --;
map->parm_num = lto_input_uleb128 (ib_main); map->parm_num = lto_input_uleb128 (ib_main);
map->old_tree = NULL; map->old_tree = NULL;
map->new_tree = lto_input_tree (ib_main, data_in); map->new_tree = stream_read_tree (ib_main, data_in);
bp = lto_input_bitpack (ib_main); bp = lto_input_bitpack (ib_main);
map->replace_p = bp_unpack_value (&bp, 1); map->replace_p = bp_unpack_value (&bp, 1);
map->ref_p = bp_unpack_value (&bp, 1); map->ref_p = bp_unpack_value (&bp, 1);
......
...@@ -195,7 +195,7 @@ lto_input_location (struct lto_input_block *ib, struct data_in *data_in) ...@@ -195,7 +195,7 @@ lto_input_location (struct lto_input_block *ib, struct data_in *data_in)
TAG is the expected node that should be found in IB, if TAG belongs TAG is the expected node that should be found in IB, if TAG belongs
to one of the indexable trees, expect to read a reference index to to one of the indexable trees, expect to read a reference index to
be looked up in one of the symbol tables, otherwise read the pysical be looked up in one of the symbol tables, otherwise read the pysical
representation of the tree using lto_input_tree. FN is the representation of the tree using stream_read_tree. FN is the
function scope for the read tree. */ function scope for the read tree. */
tree tree
...@@ -280,9 +280,9 @@ lto_input_eh_catch_list (struct lto_input_block *ib, struct data_in *data_in, ...@@ -280,9 +280,9 @@ lto_input_eh_catch_list (struct lto_input_block *ib, struct data_in *data_in,
/* Read the catch node. */ /* Read the catch node. */
n = ggc_alloc_cleared_eh_catch_d (); n = ggc_alloc_cleared_eh_catch_d ();
n->type_list = lto_input_tree (ib, data_in); n->type_list = stream_read_tree (ib, data_in);
n->filter_list = lto_input_tree (ib, data_in); n->filter_list = stream_read_tree (ib, data_in);
n->label = lto_input_tree (ib, data_in); n->label = stream_read_tree (ib, data_in);
/* Register all the types in N->FILTER_LIST. */ /* Register all the types in N->FILTER_LIST. */
for (list = n->filter_list; list; list = TREE_CHAIN (list)) for (list = n->filter_list; list; list = TREE_CHAIN (list))
...@@ -351,8 +351,8 @@ input_eh_region (struct lto_input_block *ib, struct data_in *data_in, int ix) ...@@ -351,8 +351,8 @@ input_eh_region (struct lto_input_block *ib, struct data_in *data_in, int ix)
tree l; tree l;
r->type = ERT_ALLOWED_EXCEPTIONS; r->type = ERT_ALLOWED_EXCEPTIONS;
r->u.allowed.type_list = lto_input_tree (ib, data_in); r->u.allowed.type_list = stream_read_tree (ib, data_in);
r->u.allowed.label = lto_input_tree (ib, data_in); r->u.allowed.label = stream_read_tree (ib, data_in);
r->u.allowed.filter = lto_input_uleb128 (ib); r->u.allowed.filter = lto_input_uleb128 (ib);
for (l = r->u.allowed.type_list; l ; l = TREE_CHAIN (l)) for (l = r->u.allowed.type_list; l ; l = TREE_CHAIN (l))
...@@ -362,7 +362,7 @@ input_eh_region (struct lto_input_block *ib, struct data_in *data_in, int ix) ...@@ -362,7 +362,7 @@ input_eh_region (struct lto_input_block *ib, struct data_in *data_in, int ix)
case LTO_ert_must_not_throw: case LTO_ert_must_not_throw:
r->type = ERT_MUST_NOT_THROW; r->type = ERT_MUST_NOT_THROW;
r->u.must_not_throw.failure_decl = lto_input_tree (ib, data_in); r->u.must_not_throw.failure_decl = stream_read_tree (ib, data_in);
r->u.must_not_throw.failure_loc = lto_input_location (ib, data_in); r->u.must_not_throw.failure_loc = lto_input_location (ib, data_in);
break; break;
...@@ -397,7 +397,7 @@ input_eh_lp (struct lto_input_block *ib, struct data_in *data_in, int ix) ...@@ -397,7 +397,7 @@ input_eh_lp (struct lto_input_block *ib, struct data_in *data_in, int ix)
gcc_assert (lp->index == ix); gcc_assert (lp->index == ix);
lp->next_lp = (eh_landing_pad) (intptr_t) lto_input_sleb128 (ib); lp->next_lp = (eh_landing_pad) (intptr_t) lto_input_sleb128 (ib);
lp->region = (eh_region) (intptr_t) lto_input_sleb128 (ib); lp->region = (eh_region) (intptr_t) lto_input_sleb128 (ib);
lp->post_landing_pad = lto_input_tree (ib, data_in); lp->post_landing_pad = stream_read_tree (ib, data_in);
return lp; return lp;
} }
...@@ -542,7 +542,7 @@ input_eh_regions (struct lto_input_block *ib, struct data_in *data_in, ...@@ -542,7 +542,7 @@ input_eh_regions (struct lto_input_block *ib, struct data_in *data_in,
VEC_safe_grow (tree, gc, fn->eh->ttype_data, len); VEC_safe_grow (tree, gc, fn->eh->ttype_data, len);
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
tree ttype = lto_input_tree (ib, data_in); tree ttype = stream_read_tree (ib, data_in);
VEC_replace (tree, fn->eh->ttype_data, i, ttype); VEC_replace (tree, fn->eh->ttype_data, i, ttype);
} }
} }
...@@ -557,7 +557,7 @@ input_eh_regions (struct lto_input_block *ib, struct data_in *data_in, ...@@ -557,7 +557,7 @@ input_eh_regions (struct lto_input_block *ib, struct data_in *data_in,
VEC_safe_grow (tree, gc, fn->eh->ehspec_data.arm_eabi, len); VEC_safe_grow (tree, gc, fn->eh->ehspec_data.arm_eabi, len);
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
tree t = lto_input_tree (ib, data_in); tree t = stream_read_tree (ib, data_in);
VEC_replace (tree, fn->eh->ehspec_data.arm_eabi, i, t); VEC_replace (tree, fn->eh->ehspec_data.arm_eabi, i, t);
} }
} }
...@@ -700,7 +700,7 @@ input_ssa_names (struct lto_input_block *ib, struct data_in *data_in, ...@@ -700,7 +700,7 @@ input_ssa_names (struct lto_input_block *ib, struct data_in *data_in,
VEC_quick_push (tree, SSANAMES (fn), NULL_TREE); VEC_quick_push (tree, SSANAMES (fn), NULL_TREE);
is_default_def = (lto_input_1_unsigned (ib) != 0); is_default_def = (lto_input_1_unsigned (ib) != 0);
name = lto_input_tree (ib, data_in); name = stream_read_tree (ib, data_in);
ssa_name = make_ssa_name_fn (fn, name, gimple_build_nop ()); ssa_name = make_ssa_name_fn (fn, name, gimple_build_nop ());
if (is_default_def) if (is_default_def)
...@@ -800,8 +800,8 @@ input_function (tree fn_decl, struct data_in *data_in, ...@@ -800,8 +800,8 @@ input_function (tree fn_decl, struct data_in *data_in,
fn->curr_properties = lto_input_uleb128 (ib); fn->curr_properties = lto_input_uleb128 (ib);
/* Read the static chain and non-local goto save area. */ /* Read the static chain and non-local goto save area. */
fn->static_chain_decl = lto_input_tree (ib, data_in); fn->static_chain_decl = stream_read_tree (ib, data_in);
fn->nonlocal_goto_save_area = lto_input_tree (ib, data_in); fn->nonlocal_goto_save_area = stream_read_tree (ib, data_in);
/* Read all the local symbols. */ /* Read all the local symbols. */
len = lto_input_sleb128 (ib); len = lto_input_sleb128 (ib);
...@@ -811,14 +811,14 @@ input_function (tree fn_decl, struct data_in *data_in, ...@@ -811,14 +811,14 @@ input_function (tree fn_decl, struct data_in *data_in,
VEC_safe_grow (tree, gc, fn->local_decls, len); VEC_safe_grow (tree, gc, fn->local_decls, len);
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
tree t = lto_input_tree (ib, data_in); tree t = stream_read_tree (ib, data_in);
VEC_replace (tree, fn->local_decls, i, t); VEC_replace (tree, fn->local_decls, i, t);
} }
} }
/* Read all function arguments. We need to re-map them here to the /* Read all function arguments. We need to re-map them here to the
arguments of the merged function declaration. */ arguments of the merged function declaration. */
args = lto_input_tree (ib, data_in); args = stream_read_tree (ib, data_in);
for (oarg = args, narg = DECL_ARGUMENTS (fn_decl); for (oarg = args, narg = DECL_ARGUMENTS (fn_decl);
oarg && narg; oarg && narg;
oarg = TREE_CHAIN (oarg), narg = TREE_CHAIN (narg)) oarg = TREE_CHAIN (oarg), narg = TREE_CHAIN (narg))
...@@ -839,7 +839,7 @@ input_function (tree fn_decl, struct data_in *data_in, ...@@ -839,7 +839,7 @@ input_function (tree fn_decl, struct data_in *data_in,
input_eh_regions (ib, data_in, fn); input_eh_regions (ib, data_in, fn);
/* Read the tree of lexical scopes for the function. */ /* Read the tree of lexical scopes for the function. */
DECL_INITIAL (fn_decl) = lto_input_tree (ib, data_in); DECL_INITIAL (fn_decl) = stream_read_tree (ib, data_in);
gcc_assert (DECL_INITIAL (fn_decl)); gcc_assert (DECL_INITIAL (fn_decl));
DECL_SAVED_TREE (fn_decl) = NULL_TREE; DECL_SAVED_TREE (fn_decl) = NULL_TREE;
node = cgraph_get_create_node (fn_decl); node = cgraph_get_create_node (fn_decl);
...@@ -920,7 +920,7 @@ input_alias_pairs (struct lto_input_block *ib, struct data_in *data_in) ...@@ -920,7 +920,7 @@ input_alias_pairs (struct lto_input_block *ib, struct data_in *data_in)
clear_line_info (data_in); clear_line_info (data_in);
var = lto_input_tree (ib, data_in); var = stream_read_tree (ib, data_in);
while (var) while (var)
{ {
const char *orig_name, *new_name; const char *orig_name, *new_name;
...@@ -928,7 +928,7 @@ input_alias_pairs (struct lto_input_block *ib, struct data_in *data_in) ...@@ -928,7 +928,7 @@ input_alias_pairs (struct lto_input_block *ib, struct data_in *data_in)
p = VEC_safe_push (alias_pair, gc, alias_pairs, NULL); p = VEC_safe_push (alias_pair, gc, alias_pairs, NULL);
p->decl = var; p->decl = var;
p->target = lto_input_tree (ib, data_in); p->target = stream_read_tree (ib, data_in);
/* If the target is a static object, we may have registered a /* If the target is a static object, we may have registered a
new name for it to avoid clashes between statics coming from new name for it to avoid clashes between statics coming from
...@@ -938,7 +938,7 @@ input_alias_pairs (struct lto_input_block *ib, struct data_in *data_in) ...@@ -938,7 +938,7 @@ input_alias_pairs (struct lto_input_block *ib, struct data_in *data_in)
if (strcmp (orig_name, new_name) != 0) if (strcmp (orig_name, new_name) != 0)
p->target = get_identifier (new_name); p->target = get_identifier (new_name);
var = lto_input_tree (ib, data_in); var = stream_read_tree (ib, data_in);
} }
} }
...@@ -1044,18 +1044,98 @@ lto_input_constructors_and_inits (struct lto_file_decl_data *file_data, ...@@ -1044,18 +1044,98 @@ lto_input_constructors_and_inits (struct lto_file_decl_data *file_data,
} }
/* LTO streamer hook for reading GIMPLE trees. IB and DATA_IN are as in /* Read the physical representation of a tree node with tag TAG from
lto_read_tree. EXPR is the tree was materialized by lto_read_tree and input block IB using the per-file context in DATA_IN. */
needs GIMPLE specific data to be filled in. */
void static tree
lto_streamer_read_tree (struct lto_input_block *ib, struct data_in *data_in, lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
tree expr) enum LTO_tags tag)
{ {
if (DECL_P (expr) /* Instantiate a new tree node. */
&& TREE_CODE (expr) != FUNCTION_DECL tree result = lto_materialize_tree (ib, data_in, tag);
&& TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
DECL_INITIAL (expr) = lto_input_tree (ib, data_in); /* Enter RESULT in the reader cache. This will make RESULT
available so that circular references in the rest of the tree
structure can be resolved in subsequent calls to stream_read_tree. */
lto_streamer_cache_append (data_in->reader_cache, result);
/* Read all the bitfield values in RESULT. Note that for LTO, we
only write language-independent bitfields, so no more unpacking is
needed. */
tree_read_bitfields (ib, result);
/* Read all the pointer fields in RESULT. */
lto_input_tree_pointers (ib, data_in, result);
/* Read any LTO-specific data not read by the tree streamer. */
if (DECL_P (result)
&& TREE_CODE (result) != FUNCTION_DECL
&& TREE_CODE (result) != TRANSLATION_UNIT_DECL)
DECL_INITIAL (result) = stream_read_tree (ib, data_in);
/* We should never try to instantiate an MD or NORMAL builtin here. */
if (TREE_CODE (result) == FUNCTION_DECL)
gcc_assert (!lto_stream_as_builtin_p (result));
/* end_marker = */ lto_input_1_unsigned (ib);
#ifdef LTO_STREAMER_DEBUG
/* Remove the mapping to RESULT's original address set by
lto_materialize_tree. */
lto_orig_address_remove (result);
#endif
return result;
}
/* Read a tree from input block IB using the per-file context in
DATA_IN. This context is used, for example, to resolve references
to previously read nodes. */
tree
lto_input_tree (struct lto_input_block *ib, struct data_in *data_in)
{
enum LTO_tags tag;
tree result;
tag = input_record_start (ib);
gcc_assert ((unsigned) tag < (unsigned) LTO_NUM_TAGS);
if (tag == LTO_null)
result = NULL_TREE;
else if (tag >= LTO_field_decl_ref && tag <= LTO_global_decl_ref)
{
/* If TAG is a reference to an indexable tree, the next value
in IB is the index into the table where we expect to find
that tree. */
result = lto_input_tree_ref (ib, data_in, cfun, tag);
}
else if (tag == LTO_tree_pickle_reference)
{
/* If TAG is a reference to a previously read tree, look it up in
the reader cache. */
result = lto_get_pickled_tree (ib, data_in);
}
else if (tag == LTO_builtin_decl)
{
/* If we are going to read a built-in function, all we need is
the code and class. */
result = lto_get_builtin_tree (ib, data_in);
}
else if (tag == lto_tree_code_to_tag (INTEGER_CST))
{
/* For integer constants we only need the type and its hi/low
words. */
result = lto_input_integer_cst (ib, data_in);
}
else
{
/* Otherwise, materialize a new node from IB. */
result = lto_read_tree (ib, data_in, tag);
}
return result;
} }
......
...@@ -257,86 +257,6 @@ print_lto_report (void) ...@@ -257,86 +257,6 @@ print_lto_report (void)
} }
/* Record NODE in CACHE. */
static void
lto_record_common_node (struct lto_streamer_cache_d *cache, tree node)
{
/* We have to make sure to fill exactly the same number of
elements for all frontends. That can include NULL trees.
As our hash table can't deal with zero entries we'll simply stream
a random other tree. A NULL tree never will be looked up so it
doesn't matter which tree we replace it with, just to be sure
use error_mark_node. */
if (!node)
node = error_mark_node;
lto_streamer_cache_append (cache, node);
if (POINTER_TYPE_P (node)
|| TREE_CODE (node) == COMPLEX_TYPE
|| TREE_CODE (node) == ARRAY_TYPE)
lto_record_common_node (cache, TREE_TYPE (node));
else if (TREE_CODE (node) == RECORD_TYPE)
{
/* The FIELD_DECLs of structures should be shared, so that every
COMPONENT_REF uses the same tree node when referencing a field.
Pointer equality between FIELD_DECLs is used by the alias
machinery to compute overlapping memory references (See
nonoverlapping_component_refs_p). */
tree f;
for (f = TYPE_FIELDS (node); f; f = TREE_CHAIN (f))
lto_record_common_node (cache, f);
}
}
/* Preload common nodes into CACHE and make sure they are merged
properly according to the gimple type table. */
static void
lto_preload_common_nodes (struct lto_streamer_cache_d *cache)
{
unsigned i;
/* The MAIN_IDENTIFIER_NODE is normally set up by the front-end, but the
LTO back-end must agree. Currently, the only languages that set this
use the name "main". */
if (main_identifier_node)
{
const char *main_name = IDENTIFIER_POINTER (main_identifier_node);
gcc_assert (strcmp (main_name, "main") == 0);
}
else
main_identifier_node = get_identifier ("main");
gcc_assert (ptrdiff_type_node == integer_type_node);
/* FIXME lto. In the C++ front-end, fileptr_type_node is defined as a
variant copy of of ptr_type_node, rather than ptr_node itself. The
distinction should only be relevant to the front-end, so we always
use the C definition here in lto1.
These should be assured in pass_ipa_free_lang_data. */
gcc_assert (fileptr_type_node == ptr_type_node);
gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node);
for (i = 0; i < itk_none; i++)
/* Skip itk_char. char_type_node is dependent on -f[un]signed-char. */
if (i != itk_char)
lto_record_common_node (cache, integer_types[i]);
for (i = 0; i < TYPE_KIND_LAST; i++)
lto_record_common_node (cache, sizetype_tab[i]);
for (i = 0; i < TI_MAX; i++)
/* Skip boolean type and constants, they are frontend dependent. */
if (i != TI_BOOLEAN_TYPE
&& i != TI_BOOLEAN_FALSE
&& i != TI_BOOLEAN_TRUE)
lto_record_common_node (cache, global_trees[i]);
}
#ifdef LTO_STREAMER_DEBUG #ifdef LTO_STREAMER_DEBUG
static htab_t tree_htab; static htab_t tree_htab;
...@@ -464,41 +384,12 @@ lto_check_version (int major, int minor) ...@@ -464,41 +384,12 @@ lto_check_version (int major, int minor)
} }
/* Return true if EXPR is a tree node that can be written to disk. */
static inline bool
lto_is_streamable (tree expr)
{
enum tree_code code = TREE_CODE (expr);
/* Notice that we reject SSA_NAMEs as well. We only emit the SSA
name version in lto_output_tree_ref (see output_ssa_names). */
return !is_lang_specific (expr)
&& code != SSA_NAME
&& code != CALL_EXPR
&& code != LANG_TYPE
&& code != MODIFY_EXPR
&& code != INIT_EXPR
&& code != TARGET_EXPR
&& code != BIND_EXPR
&& code != WITH_CLEANUP_EXPR
&& code != STATEMENT_LIST
&& code != OMP_CLAUSE
&& code != OPTIMIZATION_NODE
&& (code == CASE_LABEL_EXPR
|| code == DECL_EXPR
|| TREE_CODE_CLASS (code) != tcc_statement);
}
/* Initialize all the streamer hooks used for streaming GIMPLE. */ /* Initialize all the streamer hooks used for streaming GIMPLE. */
void void
lto_streamer_hooks_init (void) lto_streamer_hooks_init (void)
{ {
streamer_hooks_init (); streamer_hooks_init ();
streamer_hooks.name = "gimple"; streamer_hooks.write_tree = lto_output_tree;
streamer_hooks.preload_common_nodes = lto_preload_common_nodes; streamer_hooks.read_tree = lto_input_tree;
streamer_hooks.is_streamable = lto_is_streamable;
streamer_hooks.write_tree = lto_streamer_write_tree;
streamer_hooks.read_tree = lto_streamer_read_tree;
} }
...@@ -809,6 +809,7 @@ tree lto_input_tree_ref (struct lto_input_block *, struct data_in *, ...@@ -809,6 +809,7 @@ tree lto_input_tree_ref (struct lto_input_block *, struct data_in *,
struct function *, enum LTO_tags); struct function *, enum LTO_tags);
void lto_tag_check_set (enum LTO_tags, int, ...); void lto_tag_check_set (enum LTO_tags, int, ...);
void lto_init_eh (void); void lto_init_eh (void);
tree lto_input_tree (struct lto_input_block *, struct data_in *);
/* In lto-streamer-out.c */ /* In lto-streamer-out.c */
...@@ -822,7 +823,6 @@ void lto_output_decl_state_streams (struct output_block *, ...@@ -822,7 +823,6 @@ void lto_output_decl_state_streams (struct output_block *,
void lto_output_decl_state_refs (struct output_block *, void lto_output_decl_state_refs (struct output_block *,
struct lto_output_stream *, struct lto_output_stream *,
struct lto_out_decl_state *); struct lto_out_decl_state *);
void lto_output_tree_ref (struct output_block *, tree);
void lto_output_location (struct output_block *, location_t); void lto_output_location (struct output_block *, location_t);
...@@ -1016,17 +1016,6 @@ emit_label_in_global_context_p (tree label) ...@@ -1016,17 +1016,6 @@ emit_label_in_global_context_p (tree label)
return DECL_NONLOCAL (label) || FORCED_LABEL (label); return DECL_NONLOCAL (label) || FORCED_LABEL (label);
} }
/* Return true if tree node EXPR should be streamed as a builtin. For
these nodes, we just emit the class and function code. */
static inline bool
lto_stream_as_builtin_p (tree expr)
{
return (TREE_CODE (expr) == FUNCTION_DECL
&& DECL_IS_BUILTIN (expr)
&& (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_NORMAL
|| DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD));
}
DEFINE_DECL_STREAM_FUNCS (TYPE, type) DEFINE_DECL_STREAM_FUNCS (TYPE, type)
DEFINE_DECL_STREAM_FUNCS (FIELD_DECL, field_decl) DEFINE_DECL_STREAM_FUNCS (FIELD_DECL, field_decl)
DEFINE_DECL_STREAM_FUNCS (FN_DECL, fn_decl) DEFINE_DECL_STREAM_FUNCS (FN_DECL, fn_decl)
......
...@@ -1099,6 +1099,7 @@ lto_init (void) ...@@ -1099,6 +1099,7 @@ lto_init (void)
distinction should only be relevant to the front-end, so we distinction should only be relevant to the front-end, so we
always use the C definition here in lto1. */ always use the C definition here in lto1. */
gcc_assert (fileptr_type_node == ptr_type_node); gcc_assert (fileptr_type_node == ptr_type_node);
gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node);
ptrdiff_type_node = integer_type_node; ptrdiff_type_node = integer_type_node;
......
...@@ -834,7 +834,7 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data, ...@@ -834,7 +834,7 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
{ {
tree t; tree t;
unsigned from = VEC_length (tree, data_in->reader_cache->nodes); unsigned from = VEC_length (tree, data_in->reader_cache->nodes);
t = lto_input_tree (&ib_main, data_in); t = stream_read_tree (&ib_main, data_in);
gcc_assert (t && ib_main.p <= ib_main.len); gcc_assert (t && ib_main.p <= ib_main.len);
uniquify_nodes (data_in, from); uniquify_nodes (data_in, from);
} }
......
...@@ -39,76 +39,28 @@ struct lto_streamer_cache_d; ...@@ -39,76 +39,28 @@ struct lto_streamer_cache_d;
Hooks marked [REQ] are required to be set. Those marked [OPT] may Hooks marked [REQ] are required to be set. Those marked [OPT] may
be NULL, if the streamer does not need to implement them. */ be NULL, if the streamer does not need to implement them. */
struct streamer_hooks { struct streamer_hooks {
/* [REQ] A string identifying this streamer. */ /* [REQ] Called by every tree streaming routine that needs to write
const char *name; a tree node. The arguments are: output_block where to write the
node, the tree node to write and a boolean flag that should be true
/* [REQ] Called by lto_streamer_cache_create to instantiate a cache of if the caller wants to write a reference to the tree, instead of the
well-known nodes. These are tree nodes that are always tree itself. The referencing mechanism is up to each streamer to
instantiated by the compiler on startup. Additionally, these implement. */
nodes need to be shared. This function should call
lto_streamer_cache_append on every tree node that it wishes to
preload in the streamer cache. This way, the writer will only
write out a reference to the tree and the reader will instantiate
the tree out of this pre-populated cache. */
void (*preload_common_nodes) (struct lto_streamer_cache_d *);
/* [REQ] Return true if the given tree is supported by this streamer. */
bool (*is_streamable) (tree);
/* [OPT] Called by lto_write_tree after writing all the common parts of
a tree. If defined, the callback is in charge of writing all
the fields that lto_write_tree did not write out. Arguments
are as in lto_write_tree.
The following tree fields are not handled by common code:
DECL_ABSTRACT_ORIGIN
DECL_INITIAL
DECL_SAVED_TREE
Callbacks may choose to ignore or handle them. If handled,
the reader should read them in the exact same sequence written
by the writer. */
void (*write_tree) (struct output_block *, tree, bool); void (*write_tree) (struct output_block *, tree, bool);
/* [OPT] Called by lto_read_tree after reading all the common parts of /* [REQ] Called by every tree streaming routine that needs to read
a tree. If defined, the callback is in charge of reading all a tree node. It takes two arguments: an lto_input_block pointing
the fields that lto_read_tree did not read in. Arguments to the buffer where to read from and a data_in instance with tables
are as in lto_read_tree. */ and descriptors needed by the unpickling routines. It returns the
void (*read_tree) (struct lto_input_block *, struct data_in *, tree); tree instantiated from the stream. */
tree (*read_tree) (struct lto_input_block *, struct data_in *);
/* [OPT] Called by lto_output_tree_ref to determine if the given tree node
should be emitted as a reference to the table of declarations
(the same table that holds global declarations). */
bool (*indexable_with_decls_p) (tree);
/* [OPT] Called by pack_value_fields to store any non-pointer fields
in the tree structure. The arguments are as in pack_value_fields. */
void (*pack_value_fields) (struct bitpack_d *, tree);
/* [OPT] Called by unpack_value_fields to retrieve any non-pointer fields
in the tree structure. The arguments are as in unpack_value_fields. */
void (*unpack_value_fields) (struct bitpack_d *, tree);
/* [OPT] Called by lto_materialize_tree for tree nodes that it does not
know how to allocate memory for. If defined, this hook should
return a new tree node of the given code. The data_in and
input_block arguments are passed in case the hook needs to
read more data from the stream to allocate the node.
If this hook returns NULL, then lto_materialize_tree will attempt
to allocate the tree by calling make_node directly. */
tree (*alloc_tree) (enum tree_code, struct lto_input_block *,
struct data_in *);
/* [OPT] Called by lto_output_tree_header to write any streamer-specific
information needed to allocate the tree. This hook may assume
that the basic header data (tree code, etc) has already been
written. It should only write any extra data needed to allocate
the node (e.g., in the case of CALL_EXPR, this hook would write
the number of arguments to the CALL_EXPR). */
void (*output_tree_header) (struct output_block *, tree);
}; };
#define stream_write_tree(OB, EXPR, REF_P) \
streamer_hooks.write_tree(OB, EXPR, REF_P)
#define stream_read_tree(IB, DATA_IN) \
streamer_hooks.read_tree(IB, DATA_IN)
/* Streamer hooks. */ /* Streamer hooks. */
extern struct streamer_hooks streamer_hooks; extern struct streamer_hooks streamer_hooks;
......
...@@ -245,6 +245,66 @@ lto_streamer_cache_get (struct lto_streamer_cache_d *cache, unsigned ix) ...@@ -245,6 +245,66 @@ lto_streamer_cache_get (struct lto_streamer_cache_d *cache, unsigned ix)
return VEC_index (tree, cache->nodes, ix); return VEC_index (tree, cache->nodes, ix);
} }
/* Record NODE in CACHE. */
static void
lto_record_common_node (struct lto_streamer_cache_d *cache, tree node)
{
/* We have to make sure to fill exactly the same number of
elements for all frontends. That can include NULL trees.
As our hash table can't deal with zero entries we'll simply stream
a random other tree. A NULL tree never will be looked up so it
doesn't matter which tree we replace it with, just to be sure
use error_mark_node. */
if (!node)
node = error_mark_node;
lto_streamer_cache_append (cache, node);
if (POINTER_TYPE_P (node)
|| TREE_CODE (node) == COMPLEX_TYPE
|| TREE_CODE (node) == ARRAY_TYPE)
lto_record_common_node (cache, TREE_TYPE (node));
else if (TREE_CODE (node) == RECORD_TYPE)
{
/* The FIELD_DECLs of structures should be shared, so that every
COMPONENT_REF uses the same tree node when referencing a field.
Pointer equality between FIELD_DECLs is used by the alias
machinery to compute overlapping memory references (See
nonoverlapping_component_refs_p). */
tree f;
for (f = TYPE_FIELDS (node); f; f = TREE_CHAIN (f))
lto_record_common_node (cache, f);
}
}
/* Preload common nodes into CACHE and make sure they are merged
properly according to the gimple type table. */
static void
preload_common_nodes (struct lto_streamer_cache_d *cache)
{
unsigned i;
for (i = 0; i < itk_none; i++)
/* Skip itk_char. char_type_node is dependent on -f[un]signed-char. */
if (i != itk_char)
lto_record_common_node (cache, integer_types[i]);
for (i = 0; i < TYPE_KIND_LAST; i++)
lto_record_common_node (cache, sizetype_tab[i]);
for (i = 0; i < TI_MAX; i++)
/* Skip boolean type and constants, they are frontend dependent. */
if (i != TI_BOOLEAN_TYPE
&& i != TI_BOOLEAN_FALSE
&& i != TI_BOOLEAN_TRUE)
lto_record_common_node (cache, global_trees[i]);
}
/* Create a cache of pickled nodes. */ /* Create a cache of pickled nodes. */
struct lto_streamer_cache_d * struct lto_streamer_cache_d *
...@@ -259,7 +319,7 @@ lto_streamer_cache_create (void) ...@@ -259,7 +319,7 @@ lto_streamer_cache_create (void)
/* Load all the well-known tree nodes that are always created by /* Load all the well-known tree nodes that are always created by
the compiler on startup. This prevents writing them out the compiler on startup. This prevents writing them out
unnecessarily. */ unnecessarily. */
streamer_hooks.preload_common_nodes (cache); preload_common_nodes (cache);
return cache; return cache;
} }
......
...@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_TREE_STREAMER_H #define GCC_TREE_STREAMER_H
#include "tree.h" #include "tree.h"
#include "streamer-hooks.h"
#include "lto-streamer.h" #include "lto-streamer.h"
/* Cache of pickled nodes. Used to avoid writing the same node more /* Cache of pickled nodes. Used to avoid writing the same node more
...@@ -51,14 +52,35 @@ struct lto_streamer_cache_d ...@@ -51,14 +52,35 @@ struct lto_streamer_cache_d
VEC(tree,heap) *nodes; VEC(tree,heap) *nodes;
}; };
/* Return true if tree node EXPR should be streamed as a builtin. For
these nodes, we just emit the class and function code. */
static inline bool
lto_stream_as_builtin_p (tree expr)
{
return (TREE_CODE (expr) == FUNCTION_DECL
&& DECL_IS_BUILTIN (expr)
&& (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_NORMAL
|| DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD));
}
/* In tree-streamer-in.c. */ /* In tree-streamer-in.c. */
tree input_string_cst (struct data_in *, struct lto_input_block *); tree input_string_cst (struct data_in *, struct lto_input_block *);
tree lto_input_tree (struct lto_input_block *, struct data_in *); void lto_streamer_read_tree (struct lto_input_block *, struct data_in *, tree);
void lto_streamer_read_tree (struct lto_input_block *, tree lto_materialize_tree (struct lto_input_block *, struct data_in *,
struct data_in *, tree); enum LTO_tags);
void lto_input_tree_pointers (struct lto_input_block *, struct data_in *, tree);
tree lto_get_pickled_tree (struct lto_input_block *, struct data_in *);
tree lto_get_builtin_tree (struct lto_input_block *, struct data_in *);
tree lto_input_integer_cst (struct lto_input_block *, struct data_in *);
struct bitpack_d tree_read_bitfields (struct lto_input_block *, tree);
/* In tree-streamer-out.c. */ /* In tree-streamer-out.c. */
void lto_streamer_write_tree (struct output_block *, tree, bool); void lto_output_chain (struct output_block *, tree, bool);
void lto_output_tree_header (struct output_block *, tree);
void pack_value_fields (struct bitpack_d *, tree);
void lto_output_tree_pointers (struct output_block *, tree, bool);
void lto_output_integer_cst (struct output_block *, tree, bool);
void lto_output_builtin_tree (struct output_block *, tree);
/* In tree-streamer.c. */ /* In tree-streamer.c. */
void check_handled_ts_structures (void); void check_handled_ts_structures (void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment