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
This commit is contained in:
parent
cf596bc73f
commit
b939365672
|
@ -1,3 +1,96 @@
|
|||
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>
|
||||
|
||||
* 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) \
|
|||
DATA_STREAMER_H = data-streamer.h $(VEC_H) $(LTO_STREAMER_H)
|
||||
GIMPLE_STREAMER_H = gimple-streamer.h $(LTO_STREAMER_H) $(BASIC_BLOCK_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)
|
||||
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
|
||||
|
@ -2305,7 +2306,7 @@ gimple-streamer-in.o: gimple-streamer-in.c $(CONFIG_H) $(SYSTEM_H) \
|
|||
$(TREE_STREAMER_H) $(DIAGNOSTIC_H)
|
||||
gimple-streamer-out.o: gimple-streamer-out.c $(CONFIG_H) $(SYSTEM_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_H) $(STREAMER_HOOKS_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,
|
|||
were in the original program. */
|
||||
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);
|
||||
location_t arg_loc = lto_input_location (ib, data_in);
|
||||
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,
|
|||
gimple_set_location (stmt, lto_input_location (ib, data_in));
|
||||
|
||||
/* 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. */
|
||||
switch (code)
|
||||
|
@ -113,7 +113,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
|
|||
break;
|
||||
|
||||
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;
|
||||
|
||||
case GIMPLE_EH_DISPATCH:
|
||||
|
@ -143,7 +143,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
|
|||
case GIMPLE_DEBUG:
|
||||
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);
|
||||
if (!op)
|
||||
continue;
|
||||
|
@ -223,7 +223,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
|
|||
gimple_call_set_internal_fn
|
||||
(stmt, lto_input_enum (ib, internal_fn, IFN_LAST));
|
||||
else
|
||||
gimple_call_set_fntype (stmt, lto_input_tree (ib, data_in));
|
||||
gimple_call_set_fntype (stmt, stream_read_tree (ib, data_in));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "data-streamer.h"
|
||||
#include "gimple-streamer.h"
|
||||
#include "lto-streamer.h"
|
||||
#include "tree-streamer.h"
|
||||
|
||||
/* Output PHI function PHI to the main stream in OB. */
|
||||
|
||||
|
@ -40,7 +41,7 @@ output_phi (struct output_block *ob, gimple phi)
|
|||
|
||||
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);
|
||||
lto_output_location (ob, gimple_phi_arg_location (phi, i));
|
||||
}
|
||||
|
@ -76,7 +77,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
|
|||
lto_output_location (ob, gimple_location (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. */
|
||||
switch (gimple_code (stmt))
|
||||
|
@ -86,7 +87,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
|
|||
break;
|
||||
|
||||
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;
|
||||
|
||||
case GIMPLE_EH_DISPATCH:
|
||||
|
@ -133,7 +134,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
|
|||
TREE_THIS_VOLATILE (*basep) = volatilep;
|
||||
}
|
||||
}
|
||||
lto_output_tree_ref (ob, op);
|
||||
stream_write_tree (ob, op, true);
|
||||
}
|
||||
if (is_gimple_call (stmt))
|
||||
{
|
||||
|
@ -141,7 +142,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
|
|||
lto_output_enum (ob->main_stream, internal_fn,
|
||||
IFN_LAST, gimple_call_internal_fn (stmt));
|
||||
else
|
||||
lto_output_tree_ref (ob, gimple_call_fntype (stmt));
|
||||
stream_write_tree (ob, gimple_call_fntype (stmt), true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -2407,7 +2407,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
|
|||
struct condition c;
|
||||
c.operand_num = 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);
|
||||
}
|
||||
count2 = lto_input_uleb128 (&ib);
|
||||
|
@ -2552,7 +2552,7 @@ inline_write_summary (cgraph_node_set set,
|
|||
c->operand_num);
|
||||
lto_output_uleb128_stream (ob->main_stream,
|
||||
c->code);
|
||||
lto_output_tree (ob, c->val, true);
|
||||
stream_write_tree (ob, c->val, true);
|
||||
}
|
||||
lto_output_uleb128_stream (ob->main_stream,
|
||||
VEC_length (size_time_entry, info->entry));
|
||||
|
|
|
@ -2652,13 +2652,13 @@ ipa_write_jump_function (struct output_block *ob,
|
|||
case IPA_JF_UNKNOWN:
|
||||
break;
|
||||
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;
|
||||
case IPA_JF_CONST:
|
||||
lto_output_tree (ob, jump_func->value.constant, true);
|
||||
stream_write_tree (ob, jump_func->value.constant, true);
|
||||
break;
|
||||
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,
|
||||
jump_func->value.pass_through.formal_id);
|
||||
lto_output_uleb128_stream (ob->main_stream,
|
||||
|
@ -2667,13 +2667,13 @@ ipa_write_jump_function (struct output_block *ob,
|
|||
case IPA_JF_ANCESTOR:
|
||||
lto_output_uleb128_stream (ob->main_stream,
|
||||
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,
|
||||
jump_func->value.ancestor.formal_id);
|
||||
break;
|
||||
case IPA_JF_CONST_MEMBER_PTR:
|
||||
lto_output_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.pfn, true);
|
||||
stream_write_tree (ob, jump_func->value.member_cst.delta, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2692,24 +2692,24 @@ ipa_read_jump_function (struct lto_input_block *ib,
|
|||
case IPA_JF_UNKNOWN:
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
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.operation = (enum tree_code) lto_input_uleb128 (ib);
|
||||
break;
|
||||
case IPA_JF_ANCESTOR:
|
||||
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);
|
||||
break;
|
||||
case IPA_JF_CONST_MEMBER_PTR:
|
||||
jump_func->value.member_cst.pfn = lto_input_tree (ib, data_in);
|
||||
jump_func->value.member_cst.delta = lto_input_tree (ib, data_in);
|
||||
jump_func->value.member_cst.pfn = stream_read_tree (ib, data_in);
|
||||
jump_func->value.member_cst.delta = stream_read_tree (ib, data_in);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2733,7 +2733,7 @@ ipa_write_indirect_edge_info (struct output_block *ob,
|
|||
if (ii->polymorphic)
|
||||
{
|
||||
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,
|
|||
if (ii->polymorphic)
|
||||
{
|
||||
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,
|
|||
mechanism to store function local declarations into summaries. */
|
||||
gcc_assert (parm);
|
||||
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_pack_value (&bp, map->replace_p, 1);
|
||||
bp_pack_value (&bp, map->ref_p, 1);
|
||||
|
@ -1688,7 +1688,7 @@ input_node_opt_summary (struct cgraph_node *node,
|
|||
parm_num --;
|
||||
map->parm_num = lto_input_uleb128 (ib_main);
|
||||
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);
|
||||
map->replace_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)
|
|||
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
|
||||
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. */
|
||||
|
||||
tree
|
||||
|
@ -280,9 +280,9 @@ lto_input_eh_catch_list (struct lto_input_block *ib, struct data_in *data_in,
|
|||
|
||||
/* Read the catch node. */
|
||||
n = ggc_alloc_cleared_eh_catch_d ();
|
||||
n->type_list = lto_input_tree (ib, data_in);
|
||||
n->filter_list = lto_input_tree (ib, data_in);
|
||||
n->label = lto_input_tree (ib, data_in);
|
||||
n->type_list = stream_read_tree (ib, data_in);
|
||||
n->filter_list = stream_read_tree (ib, data_in);
|
||||
n->label = stream_read_tree (ib, data_in);
|
||||
|
||||
/* Register all the types in N->FILTER_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)
|
|||
tree l;
|
||||
|
||||
r->type = ERT_ALLOWED_EXCEPTIONS;
|
||||
r->u.allowed.type_list = lto_input_tree (ib, data_in);
|
||||
r->u.allowed.label = lto_input_tree (ib, data_in);
|
||||
r->u.allowed.type_list = stream_read_tree (ib, data_in);
|
||||
r->u.allowed.label = stream_read_tree (ib, data_in);
|
||||
r->u.allowed.filter = lto_input_uleb128 (ib);
|
||||
|
||||
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)
|
|||
|
||||
case LTO_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);
|
||||
break;
|
||||
|
||||
|
@ -397,7 +397,7 @@ input_eh_lp (struct lto_input_block *ib, struct data_in *data_in, int ix)
|
|||
gcc_assert (lp->index == ix);
|
||||
lp->next_lp = (eh_landing_pad) (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;
|
||||
}
|
||||
|
@ -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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
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 ());
|
||||
|
||||
if (is_default_def)
|
||||
|
@ -800,8 +800,8 @@ input_function (tree fn_decl, struct data_in *data_in,
|
|||
fn->curr_properties = lto_input_uleb128 (ib);
|
||||
|
||||
/* Read the static chain and non-local goto save area. */
|
||||
fn->static_chain_decl = lto_input_tree (ib, data_in);
|
||||
fn->nonlocal_goto_save_area = lto_input_tree (ib, data_in);
|
||||
fn->static_chain_decl = stream_read_tree (ib, data_in);
|
||||
fn->nonlocal_goto_save_area = stream_read_tree (ib, data_in);
|
||||
|
||||
/* Read all the local symbols. */
|
||||
len = lto_input_sleb128 (ib);
|
||||
|
@ -811,14 +811,14 @@ input_function (tree fn_decl, struct data_in *data_in,
|
|||
VEC_safe_grow (tree, gc, fn->local_decls, len);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read all function arguments. We need to re-map them here to the
|
||||
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);
|
||||
oarg && narg;
|
||||
oarg = TREE_CHAIN (oarg), narg = TREE_CHAIN (narg))
|
||||
|
@ -839,7 +839,7 @@ input_function (tree fn_decl, struct data_in *data_in,
|
|||
input_eh_regions (ib, data_in, fn);
|
||||
|
||||
/* 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));
|
||||
DECL_SAVED_TREE (fn_decl) = NULL_TREE;
|
||||
node = cgraph_get_create_node (fn_decl);
|
||||
|
@ -920,7 +920,7 @@ input_alias_pairs (struct lto_input_block *ib, struct data_in *data_in)
|
|||
|
||||
clear_line_info (data_in);
|
||||
|
||||
var = lto_input_tree (ib, data_in);
|
||||
var = stream_read_tree (ib, data_in);
|
||||
while (var)
|
||||
{
|
||||
const char *orig_name, *new_name;
|
||||
|
@ -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->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
|
||||
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)
|
|||
if (strcmp (orig_name, new_name) != 0)
|
||||
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,
|
|||
}
|
||||
|
||||
|
||||
/* LTO streamer hook for reading GIMPLE trees. IB and DATA_IN are as in
|
||||
lto_read_tree. EXPR is the tree was materialized by lto_read_tree and
|
||||
needs GIMPLE specific data to be filled in. */
|
||||
/* Read the physical representation of a tree node with tag TAG from
|
||||
input block IB using the per-file context in DATA_IN. */
|
||||
|
||||
void
|
||||
lto_streamer_read_tree (struct lto_input_block *ib, struct data_in *data_in,
|
||||
tree expr)
|
||||
static tree
|
||||
lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
|
||||
enum LTO_tags tag)
|
||||
{
|
||||
if (DECL_P (expr)
|
||||
&& TREE_CODE (expr) != FUNCTION_DECL
|
||||
&& TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
|
||||
DECL_INITIAL (expr) = lto_input_tree (ib, data_in);
|
||||
/* Instantiate a new tree node. */
|
||||
tree result = lto_materialize_tree (ib, data_in, tag);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -188,25 +188,11 @@ lto_output_location (struct output_block *ob, location_t loc)
|
|||
output block OB. Otherwise, output the physical representation of
|
||||
EXPR to OB. */
|
||||
|
||||
void
|
||||
static void
|
||||
lto_output_tree_ref (struct output_block *ob, tree expr)
|
||||
{
|
||||
enum tree_code code;
|
||||
|
||||
if (expr == NULL_TREE)
|
||||
{
|
||||
output_record_start (ob, LTO_null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tree_is_indexable (expr))
|
||||
{
|
||||
/* Even though we are emitting the physical representation of
|
||||
EXPR, its leaves must be emitted as references. */
|
||||
lto_output_tree (ob, expr, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TYPE_P (expr))
|
||||
{
|
||||
output_type_ref (ob, expr);
|
||||
|
@ -233,8 +219,7 @@ lto_output_tree_ref (struct output_block *ob, tree expr)
|
|||
|
||||
case VAR_DECL:
|
||||
case DEBUG_EXPR_DECL:
|
||||
gcc_assert (decl_function_context (expr) == NULL
|
||||
|| TREE_STATIC (expr));
|
||||
gcc_assert (decl_function_context (expr) == NULL || TREE_STATIC (expr));
|
||||
output_record_start (ob, LTO_global_decl_ref);
|
||||
lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
|
||||
break;
|
||||
|
@ -276,22 +261,153 @@ lto_output_tree_ref (struct output_block *ob, tree expr)
|
|||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
/* See if the streamer allows this node to be indexable
|
||||
like other global declarations. */
|
||||
if (streamer_hooks.indexable_with_decls_p
|
||||
&& streamer_hooks.indexable_with_decls_p (expr))
|
||||
{
|
||||
output_record_start (ob, LTO_global_decl_ref);
|
||||
lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No other node is indexable, so it should have been
|
||||
handled by lto_output_tree. */
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
/* No other node is indexable, so it should have been handled by
|
||||
lto_output_tree. */
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
/* Write a physical representation of tree node EXPR to output block
|
||||
OB. If REF_P is true, the leaves of EXPR are emitted as references
|
||||
via lto_output_tree_ref. IX is the index into the streamer cache
|
||||
where EXPR is stored. */
|
||||
|
||||
static void
|
||||
lto_write_tree (struct output_block *ob, tree expr, bool ref_p)
|
||||
{
|
||||
struct bitpack_d bp;
|
||||
|
||||
if (!lto_is_streamable (expr))
|
||||
internal_error ("tree code %qs is not supported in LTO streams",
|
||||
tree_code_name[TREE_CODE (expr)]);
|
||||
|
||||
/* Write the header, containing everything needed to materialize
|
||||
EXPR on the reading side. */
|
||||
lto_output_tree_header (ob, expr);
|
||||
|
||||
/* Pack all the non-pointer fields in EXPR into a bitpack and write
|
||||
the resulting bitpack. */
|
||||
bp = bitpack_create (ob->main_stream);
|
||||
pack_value_fields (&bp, expr);
|
||||
lto_output_bitpack (&bp);
|
||||
|
||||
/* Write all the pointer fields in EXPR. */
|
||||
lto_output_tree_pointers (ob, expr, ref_p);
|
||||
|
||||
/* Write any LTO-specific data to OB. */
|
||||
if (DECL_P (expr)
|
||||
&& TREE_CODE (expr) != FUNCTION_DECL
|
||||
&& TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
|
||||
{
|
||||
/* Handle DECL_INITIAL for symbols. */
|
||||
tree initial = DECL_INITIAL (expr);
|
||||
if (TREE_CODE (expr) == VAR_DECL
|
||||
&& (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
|
||||
&& initial)
|
||||
{
|
||||
lto_varpool_encoder_t varpool_encoder;
|
||||
struct varpool_node *vnode;
|
||||
|
||||
varpool_encoder = ob->decl_state->varpool_node_encoder;
|
||||
vnode = varpool_get_node (expr);
|
||||
if (!vnode)
|
||||
initial = error_mark_node;
|
||||
else if (!lto_varpool_encoder_encode_initializer_p (varpool_encoder,
|
||||
vnode))
|
||||
initial = NULL;
|
||||
}
|
||||
|
||||
stream_write_tree (ob, initial, ref_p);
|
||||
}
|
||||
|
||||
/* Mark the end of EXPR. */
|
||||
output_zero (ob);
|
||||
}
|
||||
|
||||
|
||||
/* Emit the physical representation of tree node EXPR to output block
|
||||
OB. If REF_P is true, the leaves of EXPR are emitted as references
|
||||
via lto_output_tree_ref. */
|
||||
|
||||
void
|
||||
lto_output_tree (struct output_block *ob, tree expr, bool ref_p)
|
||||
{
|
||||
unsigned ix;
|
||||
bool existed_p;
|
||||
|
||||
if (expr == NULL_TREE)
|
||||
{
|
||||
output_record_start (ob, LTO_null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ref_p && tree_is_indexable (expr))
|
||||
{
|
||||
lto_output_tree_ref (ob, expr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* INTEGER_CST nodes are special because they need their original type
|
||||
to be materialized by the reader (to implement TYPE_CACHED_VALUES). */
|
||||
if (TREE_CODE (expr) == INTEGER_CST)
|
||||
{
|
||||
lto_output_integer_cst (ob, expr, ref_p);
|
||||
return;
|
||||
}
|
||||
|
||||
existed_p = lto_streamer_cache_insert (ob->writer_cache, expr, &ix);
|
||||
if (existed_p)
|
||||
{
|
||||
/* If a node has already been streamed out, make sure that
|
||||
we don't write it more than once. Otherwise, the reader
|
||||
will instantiate two different nodes for the same object. */
|
||||
output_record_start (ob, LTO_tree_pickle_reference);
|
||||
output_uleb128 (ob, ix);
|
||||
lto_output_enum (ob->main_stream, LTO_tags, LTO_NUM_TAGS,
|
||||
lto_tree_code_to_tag (TREE_CODE (expr)));
|
||||
}
|
||||
else if (lto_stream_as_builtin_p (expr))
|
||||
{
|
||||
/* MD and NORMAL builtins do not need to be written out
|
||||
completely as they are always instantiated by the
|
||||
compiler on startup. The only builtins that need to
|
||||
be written out are BUILT_IN_FRONTEND. For all other
|
||||
builtins, we simply write the class and code. */
|
||||
lto_output_builtin_tree (ob, expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is the first time we see EXPR, write its fields
|
||||
to OB. */
|
||||
lto_write_tree (ob, expr, ref_p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,9 +422,9 @@ output_eh_try_list (struct output_block *ob, eh_catch first)
|
|||
for (n = first; n; n = n->next_catch)
|
||||
{
|
||||
output_record_start (ob, LTO_eh_catch);
|
||||
lto_output_tree_ref (ob, n->type_list);
|
||||
lto_output_tree_ref (ob, n->filter_list);
|
||||
lto_output_tree_ref (ob, n->label);
|
||||
stream_write_tree (ob, n->type_list, true);
|
||||
stream_write_tree (ob, n->filter_list, true);
|
||||
stream_write_tree (ob, n->label, true);
|
||||
}
|
||||
|
||||
output_record_start (ob, LTO_null);
|
||||
|
@ -365,13 +481,13 @@ output_eh_region (struct output_block *ob, eh_region r)
|
|||
}
|
||||
else if (r->type == ERT_ALLOWED_EXCEPTIONS)
|
||||
{
|
||||
lto_output_tree_ref (ob, r->u.allowed.type_list);
|
||||
lto_output_tree_ref (ob, r->u.allowed.label);
|
||||
stream_write_tree (ob, r->u.allowed.type_list, true);
|
||||
stream_write_tree (ob, r->u.allowed.label, true);
|
||||
output_uleb128 (ob, r->u.allowed.filter);
|
||||
}
|
||||
else if (r->type == ERT_MUST_NOT_THROW)
|
||||
{
|
||||
lto_output_tree_ref (ob, r->u.must_not_throw.failure_decl);
|
||||
stream_write_tree (ob, r->u.must_not_throw.failure_decl, true);
|
||||
lto_output_location (ob, r->u.must_not_throw.failure_loc);
|
||||
}
|
||||
|
||||
|
@ -405,7 +521,7 @@ output_eh_lp (struct output_block *ob, eh_landing_pad lp)
|
|||
else
|
||||
output_zero (ob);
|
||||
|
||||
lto_output_tree_ref (ob, lp->post_landing_pad);
|
||||
stream_write_tree (ob, lp->post_landing_pad, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -439,7 +555,7 @@ output_eh_regions (struct output_block *ob, struct function *fn)
|
|||
/* Emit all the runtime type data. */
|
||||
output_sleb128 (ob, VEC_length (tree, fn->eh->ttype_data));
|
||||
FOR_EACH_VEC_ELT (tree, fn->eh->ttype_data, i, ttype)
|
||||
lto_output_tree_ref (ob, ttype);
|
||||
stream_write_tree (ob, ttype, true);
|
||||
|
||||
/* Emit the table of action chains. */
|
||||
if (targetm.arm_eabi_unwinder)
|
||||
|
@ -447,7 +563,7 @@ output_eh_regions (struct output_block *ob, struct function *fn)
|
|||
tree t;
|
||||
output_sleb128 (ob, VEC_length (tree, fn->eh->ehspec_data.arm_eabi));
|
||||
FOR_EACH_VEC_ELT (tree, fn->eh->ehspec_data.arm_eabi, i, t)
|
||||
lto_output_tree_ref (ob, t);
|
||||
stream_write_tree (ob, t, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -485,7 +601,7 @@ output_ssa_names (struct output_block *ob, struct function *fn)
|
|||
|
||||
output_uleb128 (ob, i);
|
||||
lto_output_1_stream (ob->main_stream, SSA_NAME_IS_DEFAULT_DEF (ptr));
|
||||
lto_output_tree_ref (ob, SSA_NAME_VAR (ptr));
|
||||
stream_write_tree (ob, SSA_NAME_VAR (ptr), true);
|
||||
}
|
||||
|
||||
output_zero (ob);
|
||||
|
@ -651,16 +767,16 @@ output_function (struct cgraph_node *node)
|
|||
output_uleb128 (ob, fn->curr_properties);
|
||||
|
||||
/* Output the static chain and non-local goto save area. */
|
||||
lto_output_tree_ref (ob, fn->static_chain_decl);
|
||||
lto_output_tree_ref (ob, fn->nonlocal_goto_save_area);
|
||||
stream_write_tree (ob, fn->static_chain_decl, true);
|
||||
stream_write_tree (ob, fn->nonlocal_goto_save_area, true);
|
||||
|
||||
/* Output all the local variables in the function. */
|
||||
output_sleb128 (ob, VEC_length (tree, fn->local_decls));
|
||||
FOR_EACH_VEC_ELT (tree, fn->local_decls, i, t)
|
||||
lto_output_tree_ref (ob, t);
|
||||
stream_write_tree (ob, t, true);
|
||||
|
||||
/* Output the head of the arguments list. */
|
||||
lto_output_tree_ref (ob, DECL_ARGUMENTS (function));
|
||||
stream_write_tree (ob, DECL_ARGUMENTS (function), true);
|
||||
|
||||
/* Output all the SSA names used in the function. */
|
||||
output_ssa_names (ob, fn);
|
||||
|
@ -670,7 +786,7 @@ output_function (struct cgraph_node *node)
|
|||
|
||||
/* Output DECL_INITIAL for the function, which contains the tree of
|
||||
lexical scopes. */
|
||||
lto_output_tree (ob, DECL_INITIAL (function), true);
|
||||
stream_write_tree (ob, DECL_INITIAL (function), true);
|
||||
|
||||
/* We will renumber the statements. The code that does this uses
|
||||
the same ordering that we use for serializing them so we can use
|
||||
|
@ -803,8 +919,8 @@ output_unreferenced_globals (cgraph_node_set set, varpool_node_set vset)
|
|||
FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p)
|
||||
if (output_alias_pair_p (p, defined, set, vset))
|
||||
{
|
||||
lto_output_tree_ref (ob, p->decl);
|
||||
lto_output_tree_ref (ob, p->target);
|
||||
stream_write_tree (ob, p->decl, true);
|
||||
stream_write_tree (ob, p->target, true);
|
||||
}
|
||||
symbol_alias_set_destroy (defined);
|
||||
|
||||
|
@ -974,7 +1090,7 @@ write_global_stream (struct output_block *ob,
|
|||
{
|
||||
t = lto_tree_ref_encoder_get_tree (encoder, index);
|
||||
if (!lto_streamer_cache_lookup (ob->writer_cache, t, NULL))
|
||||
lto_output_tree (ob, t, false);
|
||||
stream_write_tree (ob, t, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
static htab_t tree_htab;
|
||||
|
||||
|
@ -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. */
|
||||
|
||||
void
|
||||
lto_streamer_hooks_init (void)
|
||||
{
|
||||
streamer_hooks_init ();
|
||||
streamer_hooks.name = "gimple";
|
||||
streamer_hooks.preload_common_nodes = lto_preload_common_nodes;
|
||||
streamer_hooks.is_streamable = lto_is_streamable;
|
||||
streamer_hooks.write_tree = lto_streamer_write_tree;
|
||||
streamer_hooks.read_tree = lto_streamer_read_tree;
|
||||
streamer_hooks.write_tree = lto_output_tree;
|
||||
streamer_hooks.read_tree = lto_input_tree;
|
||||
}
|
||||
|
|
|
@ -809,6 +809,7 @@ tree lto_input_tree_ref (struct lto_input_block *, struct data_in *,
|
|||
struct function *, enum LTO_tags);
|
||||
void lto_tag_check_set (enum LTO_tags, int, ...);
|
||||
void lto_init_eh (void);
|
||||
tree lto_input_tree (struct lto_input_block *, struct data_in *);
|
||||
|
||||
|
||||
/* In lto-streamer-out.c */
|
||||
|
@ -822,7 +823,6 @@ void lto_output_decl_state_streams (struct output_block *,
|
|||
void lto_output_decl_state_refs (struct output_block *,
|
||||
struct lto_output_stream *,
|
||||
struct lto_out_decl_state *);
|
||||
void lto_output_tree_ref (struct output_block *, tree);
|
||||
void lto_output_location (struct output_block *, location_t);
|
||||
|
||||
|
||||
|
@ -1016,17 +1016,6 @@ emit_label_in_global_context_p (tree 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 (FIELD_DECL, field_decl)
|
||||
DEFINE_DECL_STREAM_FUNCS (FN_DECL, fn_decl)
|
||||
|
|
|
@ -1099,6 +1099,7 @@ lto_init (void)
|
|||
distinction should only be relevant to the front-end, so we
|
||||
always use the C definition here in lto1. */
|
||||
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;
|
||||
|
||||
|
|
|
@ -834,7 +834,7 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
|
|||
{
|
||||
tree t;
|
||||
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);
|
||||
uniquify_nodes (data_in, from);
|
||||
}
|
||||
|
|
|
@ -39,76 +39,28 @@ struct lto_streamer_cache_d;
|
|||
Hooks marked [REQ] are required to be set. Those marked [OPT] may
|
||||
be NULL, if the streamer does not need to implement them. */
|
||||
struct streamer_hooks {
|
||||
/* [REQ] A string identifying this streamer. */
|
||||
const char *name;
|
||||
|
||||
/* [REQ] Called by lto_streamer_cache_create to instantiate a cache of
|
||||
well-known nodes. These are tree nodes that are always
|
||||
instantiated by the compiler on startup. Additionally, these
|
||||
nodes need to be shared. This function should call
|
||||
lto_streamer_cache_append on every tree node that it wishes to
|
||||
preload in the streamer cache. This way, the writer will only
|
||||
write out a reference to the tree and the reader will instantiate
|
||||
the tree out of this pre-populated cache. */
|
||||
void (*preload_common_nodes) (struct lto_streamer_cache_d *);
|
||||
|
||||
/* [REQ] Return true if the given tree is supported by this streamer. */
|
||||
bool (*is_streamable) (tree);
|
||||
|
||||
/* [OPT] Called by lto_write_tree after writing all the common parts of
|
||||
a tree. If defined, the callback is in charge of writing all
|
||||
the fields that lto_write_tree did not write out. Arguments
|
||||
are as in lto_write_tree.
|
||||
|
||||
The following tree fields are not handled by common code:
|
||||
|
||||
DECL_ABSTRACT_ORIGIN
|
||||
DECL_INITIAL
|
||||
DECL_SAVED_TREE
|
||||
|
||||
Callbacks may choose to ignore or handle them. If handled,
|
||||
the reader should read them in the exact same sequence written
|
||||
by the writer. */
|
||||
/* [REQ] Called by every tree streaming routine that needs to write
|
||||
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
|
||||
if the caller wants to write a reference to the tree, instead of the
|
||||
tree itself. The referencing mechanism is up to each streamer to
|
||||
implement. */
|
||||
void (*write_tree) (struct output_block *, tree, bool);
|
||||
|
||||
/* [OPT] Called by lto_read_tree after reading all the common parts of
|
||||
a tree. If defined, the callback is in charge of reading all
|
||||
the fields that lto_read_tree did not read in. Arguments
|
||||
are as in lto_read_tree. */
|
||||
void (*read_tree) (struct lto_input_block *, struct data_in *, tree);
|
||||
|
||||
/* [OPT] Called by lto_output_tree_ref to determine if the given tree node
|
||||
should be emitted as a reference to the table of declarations
|
||||
(the same table that holds global declarations). */
|
||||
bool (*indexable_with_decls_p) (tree);
|
||||
|
||||
/* [OPT] Called by pack_value_fields to store any non-pointer fields
|
||||
in the tree structure. The arguments are as in pack_value_fields. */
|
||||
void (*pack_value_fields) (struct bitpack_d *, tree);
|
||||
|
||||
/* [OPT] Called by unpack_value_fields to retrieve any non-pointer fields
|
||||
in the tree structure. The arguments are as in unpack_value_fields. */
|
||||
void (*unpack_value_fields) (struct bitpack_d *, tree);
|
||||
|
||||
/* [OPT] Called by lto_materialize_tree for tree nodes that it does not
|
||||
know how to allocate memory for. If defined, this hook should
|
||||
return a new tree node of the given code. The data_in and
|
||||
input_block arguments are passed in case the hook needs to
|
||||
read more data from the stream to allocate the node.
|
||||
If this hook returns NULL, then lto_materialize_tree will attempt
|
||||
to allocate the tree by calling make_node directly. */
|
||||
tree (*alloc_tree) (enum tree_code, struct lto_input_block *,
|
||||
struct data_in *);
|
||||
|
||||
/* [OPT] Called by lto_output_tree_header to write any streamer-specific
|
||||
information needed to allocate the tree. This hook may assume
|
||||
that the basic header data (tree code, etc) has already been
|
||||
written. It should only write any extra data needed to allocate
|
||||
the node (e.g., in the case of CALL_EXPR, this hook would write
|
||||
the number of arguments to the CALL_EXPR). */
|
||||
void (*output_tree_header) (struct output_block *, tree);
|
||||
/* [REQ] Called by every tree streaming routine that needs to read
|
||||
a tree node. It takes two arguments: an lto_input_block pointing
|
||||
to the buffer where to read from and a data_in instance with tables
|
||||
and descriptors needed by the unpickling routines. It returns the
|
||||
tree instantiated from the stream. */
|
||||
tree (*read_tree) (struct lto_input_block *, struct data_in *);
|
||||
};
|
||||
|
||||
#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. */
|
||||
extern struct streamer_hooks streamer_hooks;
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ lto_input_chain (struct lto_input_block *ib, struct data_in *data_in)
|
|||
count = lto_input_sleb128 (ib);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
curr = lto_input_tree (ib, data_in);
|
||||
curr = stream_read_tree (ib, data_in);
|
||||
if (prev)
|
||||
TREE_CHAIN (prev) = curr;
|
||||
else
|
||||
|
@ -401,9 +401,32 @@ unpack_value_fields (struct bitpack_d *bp, tree expr)
|
|||
|
||||
if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
|
||||
unpack_ts_translation_unit_decl_value_fields (bp, expr);
|
||||
}
|
||||
|
||||
if (streamer_hooks.unpack_value_fields)
|
||||
streamer_hooks.unpack_value_fields (bp, expr);
|
||||
|
||||
/* Read all the language-independent bitfield values for EXPR from IB.
|
||||
Return the partially unpacked bitpack so the caller can unpack any other
|
||||
bitfield values that the writer may have written. */
|
||||
|
||||
struct bitpack_d
|
||||
tree_read_bitfields (struct lto_input_block *ib, tree expr)
|
||||
{
|
||||
enum tree_code code;
|
||||
struct bitpack_d bp;
|
||||
|
||||
/* Read the bitpack of non-pointer values from IB. */
|
||||
bp = lto_input_bitpack (ib);
|
||||
|
||||
/* The first word in BP contains the code of the tree that we
|
||||
are about to read. */
|
||||
code = (enum tree_code) bp_unpack_value (&bp, 16);
|
||||
lto_tag_check (lto_tree_code_to_tag (code),
|
||||
lto_tree_code_to_tag (TREE_CODE (expr)));
|
||||
|
||||
/* Unpack all the value fields from BP. */
|
||||
unpack_value_fields (&bp, expr);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
|
||||
|
@ -411,11 +434,10 @@ unpack_value_fields (struct bitpack_d *bp, tree expr)
|
|||
DATA_IN. The code for the new tree should match TAG. Store in
|
||||
*IX_P the index into the reader cache where the new tree is stored. */
|
||||
|
||||
static tree
|
||||
tree
|
||||
lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
|
||||
enum LTO_tags tag)
|
||||
{
|
||||
struct bitpack_d bp;
|
||||
enum tree_code code;
|
||||
tree result;
|
||||
#ifdef LTO_STREAMER_DEBUG
|
||||
|
@ -453,17 +475,16 @@ lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
|
|||
unsigned HOST_WIDE_INT len = lto_input_uleb128 (ib);
|
||||
result = make_tree_binfo (len);
|
||||
}
|
||||
else if (code == CALL_EXPR)
|
||||
{
|
||||
unsigned HOST_WIDE_INT nargs = lto_input_uleb128 (ib);
|
||||
return build_vl_exp (CALL_EXPR, nargs + 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For all other nodes, see if the streamer knows how to allocate
|
||||
it. */
|
||||
if (streamer_hooks.alloc_tree)
|
||||
result = streamer_hooks.alloc_tree (code, ib, data_in);
|
||||
|
||||
/* If the hook did not handle it, materialize the tree with a raw
|
||||
/* For all other nodes, materialize the tree with a raw
|
||||
make_node call. */
|
||||
if (result == NULL_TREE)
|
||||
result = make_node (code);
|
||||
result = make_node (code);
|
||||
}
|
||||
|
||||
#ifdef LTO_STREAMER_DEBUG
|
||||
|
@ -475,22 +496,6 @@ lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
|
|||
lto_orig_address_map (result, (intptr_t) orig_address_in_writer);
|
||||
#endif
|
||||
|
||||
/* Read the bitpack of non-pointer values from IB. */
|
||||
bp = lto_input_bitpack (ib);
|
||||
|
||||
/* The first word in BP contains the code of the tree that we
|
||||
are about to read. */
|
||||
code = (enum tree_code) bp_unpack_value (&bp, 16);
|
||||
lto_tag_check (lto_tree_code_to_tag (code), tag);
|
||||
|
||||
/* Unpack all the value fields from BP. */
|
||||
unpack_value_fields (&bp, result);
|
||||
|
||||
/* 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 lto_input_tree. */
|
||||
lto_streamer_cache_append (data_in->reader_cache, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -505,7 +510,7 @@ lto_input_ts_common_tree_pointers (struct lto_input_block *ib,
|
|||
struct data_in *data_in, tree expr)
|
||||
{
|
||||
if (TREE_CODE (expr) != IDENTIFIER_NODE)
|
||||
TREE_TYPE (expr) = lto_input_tree (ib, data_in);
|
||||
TREE_TYPE (expr) = stream_read_tree (ib, data_in);
|
||||
}
|
||||
|
||||
|
||||
|
@ -529,8 +534,8 @@ static void
|
|||
lto_input_ts_complex_tree_pointers (struct lto_input_block *ib,
|
||||
struct data_in *data_in, tree expr)
|
||||
{
|
||||
TREE_REALPART (expr) = lto_input_tree (ib, data_in);
|
||||
TREE_IMAGPART (expr) = lto_input_tree (ib, data_in);
|
||||
TREE_REALPART (expr) = stream_read_tree (ib, data_in);
|
||||
TREE_IMAGPART (expr) = stream_read_tree (ib, data_in);
|
||||
}
|
||||
|
||||
|
||||
|
@ -542,8 +547,8 @@ static void
|
|||
lto_input_ts_decl_minimal_tree_pointers (struct lto_input_block *ib,
|
||||
struct data_in *data_in, tree expr)
|
||||
{
|
||||
DECL_NAME (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_CONTEXT (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_NAME (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_CONTEXT (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_SOURCE_LOCATION (expr) = lto_input_location (ib, data_in);
|
||||
}
|
||||
|
||||
|
@ -556,9 +561,9 @@ static void
|
|||
lto_input_ts_decl_common_tree_pointers (struct lto_input_block *ib,
|
||||
struct data_in *data_in, tree expr)
|
||||
{
|
||||
DECL_SIZE (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_SIZE_UNIT (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_ATTRIBUTES (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_SIZE (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_SIZE_UNIT (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_ATTRIBUTES (expr) = stream_read_tree (ib, data_in);
|
||||
|
||||
/* Do not stream DECL_ABSTRACT_ORIGIN. We cannot handle debug information
|
||||
for early inlining so drop it on the floor instead of ICEing in
|
||||
|
@ -570,11 +575,11 @@ lto_input_ts_decl_common_tree_pointers (struct lto_input_block *ib,
|
|||
if ((TREE_CODE (expr) == VAR_DECL
|
||||
|| TREE_CODE (expr) == PARM_DECL)
|
||||
&& DECL_HAS_VALUE_EXPR_P (expr))
|
||||
SET_DECL_VALUE_EXPR (expr, lto_input_tree (ib, data_in));
|
||||
SET_DECL_VALUE_EXPR (expr, stream_read_tree (ib, data_in));
|
||||
|
||||
if (TREE_CODE (expr) == VAR_DECL)
|
||||
{
|
||||
tree dexpr = lto_input_tree (ib, data_in);
|
||||
tree dexpr = stream_read_tree (ib, data_in);
|
||||
if (dexpr)
|
||||
SET_DECL_DEBUG_EXPR (expr, dexpr);
|
||||
}
|
||||
|
@ -591,10 +596,10 @@ lto_input_ts_decl_non_common_tree_pointers (struct lto_input_block *ib,
|
|||
{
|
||||
if (TREE_CODE (expr) == FUNCTION_DECL)
|
||||
{
|
||||
DECL_ARGUMENTS (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_RESULT (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_ARGUMENTS (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_RESULT (expr) = stream_read_tree (ib, data_in);
|
||||
}
|
||||
DECL_VINDEX (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_VINDEX (expr) = stream_read_tree (ib, data_in);
|
||||
}
|
||||
|
||||
|
||||
|
@ -608,15 +613,15 @@ lto_input_ts_decl_with_vis_tree_pointers (struct lto_input_block *ib,
|
|||
{
|
||||
tree id;
|
||||
|
||||
id = lto_input_tree (ib, data_in);
|
||||
id = stream_read_tree (ib, data_in);
|
||||
if (id)
|
||||
{
|
||||
gcc_assert (TREE_CODE (id) == IDENTIFIER_NODE);
|
||||
SET_DECL_ASSEMBLER_NAME (expr, id);
|
||||
}
|
||||
|
||||
DECL_SECTION_NAME (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_COMDAT_GROUP (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_SECTION_NAME (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_COMDAT_GROUP (expr) = stream_read_tree (ib, data_in);
|
||||
}
|
||||
|
||||
|
||||
|
@ -628,11 +633,11 @@ static void
|
|||
lto_input_ts_field_decl_tree_pointers (struct lto_input_block *ib,
|
||||
struct data_in *data_in, tree expr)
|
||||
{
|
||||
DECL_FIELD_OFFSET (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_BIT_FIELD_TYPE (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_QUALIFIER (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_FIELD_BIT_OFFSET (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_FCONTEXT (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_FIELD_OFFSET (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_BIT_FIELD_TYPE (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_QUALIFIER (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_FIELD_BIT_OFFSET (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_FCONTEXT (expr) = stream_read_tree (ib, data_in);
|
||||
TREE_CHAIN (expr) = lto_input_chain (ib, data_in);
|
||||
}
|
||||
|
||||
|
@ -647,9 +652,9 @@ lto_input_ts_function_decl_tree_pointers (struct lto_input_block *ib,
|
|||
{
|
||||
/* DECL_STRUCT_FUNCTION is handled by lto_input_function. FIXME lto,
|
||||
maybe it should be handled here? */
|
||||
DECL_FUNCTION_PERSONALITY (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_FUNCTION_SPECIFIC_TARGET (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = lto_input_tree (ib, data_in);
|
||||
DECL_FUNCTION_PERSONALITY (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_FUNCTION_SPECIFIC_TARGET (expr) = stream_read_tree (ib, data_in);
|
||||
DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = stream_read_tree (ib, data_in);
|
||||
|
||||
/* If the file contains a function with an EH personality set,
|
||||
then it was compiled with -fexceptions. In that case, initialize
|
||||
|
@ -667,19 +672,19 @@ static void
|
|||
lto_input_ts_type_common_tree_pointers (struct lto_input_block *ib,
|
||||
struct data_in *data_in, tree expr)
|
||||
{
|
||||
TYPE_SIZE (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_SIZE_UNIT (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_ATTRIBUTES (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_NAME (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_SIZE (expr) = stream_read_tree (ib, data_in);
|
||||
TYPE_SIZE_UNIT (expr) = stream_read_tree (ib, data_in);
|
||||
TYPE_ATTRIBUTES (expr) = stream_read_tree (ib, data_in);
|
||||
TYPE_NAME (expr) = stream_read_tree (ib, data_in);
|
||||
/* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO. They will be
|
||||
reconstructed during fixup. */
|
||||
/* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists
|
||||
during fixup. */
|
||||
TYPE_MAIN_VARIANT (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_CONTEXT (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_MAIN_VARIANT (expr) = stream_read_tree (ib, data_in);
|
||||
TYPE_CONTEXT (expr) = stream_read_tree (ib, data_in);
|
||||
/* TYPE_CANONICAL gets re-computed during type merging. */
|
||||
TYPE_CANONICAL (expr) = NULL_TREE;
|
||||
TYPE_STUB_DECL (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_STUB_DECL (expr) = stream_read_tree (ib, data_in);
|
||||
}
|
||||
|
||||
/* Read all pointer fields in the TS_TYPE_NON_COMMON structure of EXPR
|
||||
|
@ -692,20 +697,20 @@ lto_input_ts_type_non_common_tree_pointers (struct lto_input_block *ib,
|
|||
tree expr)
|
||||
{
|
||||
if (TREE_CODE (expr) == ENUMERAL_TYPE)
|
||||
TYPE_VALUES (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_VALUES (expr) = stream_read_tree (ib, data_in);
|
||||
else if (TREE_CODE (expr) == ARRAY_TYPE)
|
||||
TYPE_DOMAIN (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_DOMAIN (expr) = stream_read_tree (ib, data_in);
|
||||
else if (RECORD_OR_UNION_TYPE_P (expr))
|
||||
TYPE_FIELDS (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_FIELDS (expr) = stream_read_tree (ib, data_in);
|
||||
else if (TREE_CODE (expr) == FUNCTION_TYPE
|
||||
|| TREE_CODE (expr) == METHOD_TYPE)
|
||||
TYPE_ARG_TYPES (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_ARG_TYPES (expr) = stream_read_tree (ib, data_in);
|
||||
|
||||
if (!POINTER_TYPE_P (expr))
|
||||
TYPE_MINVAL (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_MAXVAL (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_MINVAL (expr) = stream_read_tree (ib, data_in);
|
||||
TYPE_MAXVAL (expr) = stream_read_tree (ib, data_in);
|
||||
if (RECORD_OR_UNION_TYPE_P (expr))
|
||||
TYPE_BINFO (expr) = lto_input_tree (ib, data_in);
|
||||
TYPE_BINFO (expr) = stream_read_tree (ib, data_in);
|
||||
}
|
||||
|
||||
|
||||
|
@ -717,8 +722,8 @@ static void
|
|||
lto_input_ts_list_tree_pointers (struct lto_input_block *ib,
|
||||
struct data_in *data_in, tree expr)
|
||||
{
|
||||
TREE_PURPOSE (expr) = lto_input_tree (ib, data_in);
|
||||
TREE_VALUE (expr) = lto_input_tree (ib, data_in);
|
||||
TREE_PURPOSE (expr) = stream_read_tree (ib, data_in);
|
||||
TREE_VALUE (expr) = stream_read_tree (ib, data_in);
|
||||
TREE_CHAIN (expr) = lto_input_chain (ib, data_in);
|
||||
}
|
||||
|
||||
|
@ -736,7 +741,7 @@ lto_input_ts_vec_tree_pointers (struct lto_input_block *ib,
|
|||
/* Note that TREE_VEC_LENGTH was read by lto_materialize_tree to
|
||||
instantiate EXPR. */
|
||||
for (i = 0; i < TREE_VEC_LENGTH (expr); i++)
|
||||
TREE_VEC_ELT (expr, i) = lto_input_tree (ib, data_in);
|
||||
TREE_VEC_ELT (expr, i) = stream_read_tree (ib, data_in);
|
||||
}
|
||||
|
||||
|
||||
|
@ -756,11 +761,11 @@ lto_input_ts_exp_tree_pointers (struct lto_input_block *ib,
|
|||
gcc_assert (length == TREE_OPERAND_LENGTH (expr));
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
TREE_OPERAND (expr, i) = lto_input_tree (ib, data_in);
|
||||
TREE_OPERAND (expr, i) = stream_read_tree (ib, data_in);
|
||||
|
||||
loc = lto_input_location (ib, data_in);
|
||||
SET_EXPR_LOCATION (expr, loc);
|
||||
TREE_BLOCK (expr) = lto_input_tree (ib, data_in);
|
||||
TREE_BLOCK (expr) = stream_read_tree (ib, data_in);
|
||||
}
|
||||
|
||||
|
||||
|
@ -781,13 +786,13 @@ lto_input_ts_block_tree_pointers (struct lto_input_block *ib,
|
|||
for early inlining so drop it on the floor instead of ICEing in
|
||||
dwarf2out.c. */
|
||||
|
||||
BLOCK_SUPERCONTEXT (expr) = lto_input_tree (ib, data_in);
|
||||
BLOCK_SUPERCONTEXT (expr) = stream_read_tree (ib, data_in);
|
||||
|
||||
/* Do not stream BLOCK_ABSTRACT_ORIGIN. We cannot handle debug information
|
||||
for early inlining so drop it on the floor instead of ICEing in
|
||||
dwarf2out.c. */
|
||||
BLOCK_FRAGMENT_ORIGIN (expr) = lto_input_tree (ib, data_in);
|
||||
BLOCK_FRAGMENT_CHAIN (expr) = lto_input_tree (ib, data_in);
|
||||
BLOCK_FRAGMENT_ORIGIN (expr) = stream_read_tree (ib, data_in);
|
||||
BLOCK_FRAGMENT_CHAIN (expr) = stream_read_tree (ib, data_in);
|
||||
|
||||
/* We re-compute BLOCK_SUBBLOCKS of our parent here instead
|
||||
of streaming it. For non-BLOCK BLOCK_SUPERCONTEXTs we still
|
||||
|
@ -828,16 +833,16 @@ lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib,
|
|||
list on the writer side. */
|
||||
do
|
||||
{
|
||||
t = lto_input_tree (ib, data_in);
|
||||
t = stream_read_tree (ib, data_in);
|
||||
if (t)
|
||||
VEC_quick_push (tree, BINFO_BASE_BINFOS (expr), t);
|
||||
}
|
||||
while (t);
|
||||
|
||||
BINFO_OFFSET (expr) = lto_input_tree (ib, data_in);
|
||||
BINFO_VTABLE (expr) = lto_input_tree (ib, data_in);
|
||||
BINFO_VIRTUALS (expr) = lto_input_tree (ib, data_in);
|
||||
BINFO_VPTR_FIELD (expr) = lto_input_tree (ib, data_in);
|
||||
BINFO_OFFSET (expr) = stream_read_tree (ib, data_in);
|
||||
BINFO_VTABLE (expr) = stream_read_tree (ib, data_in);
|
||||
BINFO_VIRTUALS (expr) = stream_read_tree (ib, data_in);
|
||||
BINFO_VPTR_FIELD (expr) = stream_read_tree (ib, data_in);
|
||||
|
||||
len = lto_input_uleb128 (ib);
|
||||
if (len > 0)
|
||||
|
@ -845,14 +850,14 @@ lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib,
|
|||
VEC_reserve_exact (tree, gc, BINFO_BASE_ACCESSES (expr), len);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tree a = lto_input_tree (ib, data_in);
|
||||
tree a = stream_read_tree (ib, data_in);
|
||||
VEC_quick_push (tree, BINFO_BASE_ACCESSES (expr), a);
|
||||
}
|
||||
}
|
||||
|
||||
BINFO_INHERITANCE_CHAIN (expr) = lto_input_tree (ib, data_in);
|
||||
BINFO_SUBVTT_INDEX (expr) = lto_input_tree (ib, data_in);
|
||||
BINFO_VPTR_INDEX (expr) = lto_input_tree (ib, data_in);
|
||||
BINFO_INHERITANCE_CHAIN (expr) = stream_read_tree (ib, data_in);
|
||||
BINFO_SUBVTT_INDEX (expr) = stream_read_tree (ib, data_in);
|
||||
BINFO_VPTR_INDEX (expr) = stream_read_tree (ib, data_in);
|
||||
}
|
||||
|
||||
|
||||
|
@ -871,8 +876,8 @@ lto_input_ts_constructor_tree_pointers (struct lto_input_block *ib,
|
|||
{
|
||||
tree index, value;
|
||||
|
||||
index = lto_input_tree (ib, data_in);
|
||||
value = lto_input_tree (ib, data_in);
|
||||
index = stream_read_tree (ib, data_in);
|
||||
value = stream_read_tree (ib, data_in);
|
||||
CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (expr), index, value);
|
||||
}
|
||||
}
|
||||
|
@ -906,11 +911,10 @@ lto_input_ts_translation_unit_decl_tree_pointers (struct lto_input_block *ib,
|
|||
VEC_safe_push (tree, gc, all_translation_units, expr);
|
||||
}
|
||||
|
||||
/* Helper for lto_input_tree. Read all pointer fields in EXPR from
|
||||
input block IB. DATA_IN contains tables and descriptors for the
|
||||
file being read. */
|
||||
/* Read all pointer fields in EXPR from input block IB. DATA_IN
|
||||
contains tables and descriptors for the file being read. */
|
||||
|
||||
static void
|
||||
void
|
||||
lto_input_tree_pointers (struct lto_input_block *ib, struct data_in *data_in,
|
||||
tree expr)
|
||||
{
|
||||
|
@ -977,52 +981,17 @@ lto_input_tree_pointers (struct lto_input_block *ib, struct data_in *data_in,
|
|||
}
|
||||
|
||||
|
||||
/* Read the physical representation of a tree node with tag TAG from
|
||||
input block IB using the per-file context in DATA_IN. */
|
||||
|
||||
static tree
|
||||
lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
|
||||
enum LTO_tags tag)
|
||||
{
|
||||
tree result;
|
||||
|
||||
result = lto_materialize_tree (ib, data_in, tag);
|
||||
|
||||
/* Read all the pointer fields in RESULT. */
|
||||
lto_input_tree_pointers (ib, data_in, result);
|
||||
|
||||
/* Call back into the streaming module to read anything else it
|
||||
may need. */
|
||||
if (streamer_hooks.read_tree)
|
||||
streamer_hooks.read_tree (ib, data_in, result);
|
||||
|
||||
/* We should never try to instantiate an MD or NORMAL builtin here. */
|
||||
if (TREE_CODE (result) == FUNCTION_DECL)
|
||||
gcc_assert (!lto_stream_as_builtin_p (result));
|
||||
|
||||
/* 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 and INTEGER_CST node from input block IB using the per-file
|
||||
context in DATA_IN. */
|
||||
|
||||
static tree
|
||||
tree
|
||||
lto_input_integer_cst (struct lto_input_block *ib, struct data_in *data_in)
|
||||
{
|
||||
tree result, type;
|
||||
HOST_WIDE_INT low, high;
|
||||
bool overflow_p;
|
||||
|
||||
type = lto_input_tree (ib, data_in);
|
||||
type = stream_read_tree (ib, data_in);
|
||||
overflow_p = (lto_input_1_unsigned (ib) != 0);
|
||||
low = lto_input_uleb128 (ib);
|
||||
high = lto_input_uleb128 (ib);
|
||||
|
@ -1043,7 +1012,7 @@ lto_input_integer_cst (struct lto_input_block *ib, struct data_in *data_in)
|
|||
/* Read an index IX from input block IB and return the tree node at
|
||||
DATA_IN->FILE_DATA->GLOBALS_INDEX[IX]. */
|
||||
|
||||
static tree
|
||||
tree
|
||||
lto_get_pickled_tree (struct lto_input_block *ib, struct data_in *data_in)
|
||||
{
|
||||
unsigned HOST_WIDE_INT ix;
|
||||
|
@ -1062,9 +1031,9 @@ lto_get_pickled_tree (struct lto_input_block *ib, struct data_in *data_in)
|
|||
|
||||
|
||||
/* Read a code and class from input block IB and return the
|
||||
corresponding builtin. DATA_IN is as in lto_input_tree. */
|
||||
corresponding builtin. DATA_IN is as in stream_read_tree. */
|
||||
|
||||
static tree
|
||||
tree
|
||||
lto_get_builtin_tree (struct lto_input_block *ib, struct data_in *data_in)
|
||||
{
|
||||
enum built_in_class fclass;
|
||||
|
@ -1101,53 +1070,3 @@ lto_get_builtin_tree (struct lto_input_block *ib, struct data_in *data_in)
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -305,7 +305,7 @@ pack_ts_translation_unit_decl_value_fields (struct bitpack_d *bp ATTRIBUTE_UNUSE
|
|||
|
||||
/* Pack all the non-pointer fields in EXPR into a bit pack. */
|
||||
|
||||
static void
|
||||
void
|
||||
pack_value_fields (struct bitpack_d *bp, tree expr)
|
||||
{
|
||||
enum tree_code code;
|
||||
|
@ -342,29 +342,13 @@ pack_value_fields (struct bitpack_d *bp, tree expr)
|
|||
|
||||
if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
|
||||
pack_ts_translation_unit_decl_value_fields (bp, expr);
|
||||
|
||||
if (streamer_hooks.pack_value_fields)
|
||||
streamer_hooks.pack_value_fields (bp, expr);
|
||||
}
|
||||
|
||||
|
||||
/* If REF_P is true, emit a reference to EXPR in output block OB,
|
||||
otherwise emit the physical representation of EXPR in OB. */
|
||||
|
||||
static inline void
|
||||
lto_output_tree_or_ref (struct output_block *ob, tree expr, bool ref_p)
|
||||
{
|
||||
if (ref_p)
|
||||
lto_output_tree_ref (ob, expr);
|
||||
else
|
||||
lto_output_tree (ob, expr, false);
|
||||
}
|
||||
|
||||
|
||||
/* Write the code and class of builtin EXPR to output block OB. IX is
|
||||
the index into the streamer cache where EXPR is stored.*/
|
||||
|
||||
static void
|
||||
void
|
||||
lto_output_builtin_tree (struct output_block *ob, tree expr)
|
||||
{
|
||||
gcc_assert (lto_stream_as_builtin_p (expr));
|
||||
|
@ -396,44 +380,11 @@ lto_output_builtin_tree (struct output_block *ob, tree expr)
|
|||
}
|
||||
|
||||
|
||||
/* GIMPLE hook for writing GIMPLE-specific parts of trees. OB, EXPR
|
||||
and REF_P are as in lto_write_tree. */
|
||||
|
||||
void
|
||||
lto_streamer_write_tree (struct output_block *ob, tree expr, bool ref_p)
|
||||
{
|
||||
if (DECL_P (expr)
|
||||
&& TREE_CODE (expr) != FUNCTION_DECL
|
||||
&& TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
|
||||
{
|
||||
/* Handle DECL_INITIAL for symbols. */
|
||||
tree initial = DECL_INITIAL (expr);
|
||||
if (TREE_CODE (expr) == VAR_DECL
|
||||
&& (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
|
||||
&& initial)
|
||||
{
|
||||
lto_varpool_encoder_t varpool_encoder;
|
||||
struct varpool_node *vnode;
|
||||
|
||||
varpool_encoder = ob->decl_state->varpool_node_encoder;
|
||||
vnode = varpool_get_node (expr);
|
||||
if (!vnode)
|
||||
initial = error_mark_node;
|
||||
else if (!lto_varpool_encoder_encode_initializer_p (varpool_encoder,
|
||||
vnode))
|
||||
initial = NULL;
|
||||
}
|
||||
|
||||
lto_output_tree_or_ref (ob, initial, ref_p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Emit the chain of tree nodes starting at T. OB is the output block
|
||||
to write to. REF_P is true if chain elements should be emitted
|
||||
as references. */
|
||||
|
||||
static void
|
||||
void
|
||||
lto_output_chain (struct output_block *ob, tree t, bool ref_p)
|
||||
{
|
||||
int i, count;
|
||||
|
@ -449,7 +400,7 @@ lto_output_chain (struct output_block *ob, tree t, bool ref_p)
|
|||
saved_chain = TREE_CHAIN (t);
|
||||
TREE_CHAIN (t) = NULL_TREE;
|
||||
|
||||
lto_output_tree_or_ref (ob, t, ref_p);
|
||||
stream_write_tree (ob, t, ref_p);
|
||||
|
||||
TREE_CHAIN (t) = saved_chain;
|
||||
t = TREE_CHAIN (t);
|
||||
|
@ -466,7 +417,7 @@ lto_output_ts_common_tree_pointers (struct output_block *ob, tree expr,
|
|||
bool ref_p)
|
||||
{
|
||||
if (TREE_CODE (expr) != IDENTIFIER_NODE)
|
||||
lto_output_tree_or_ref (ob, TREE_TYPE (expr), ref_p);
|
||||
stream_write_tree (ob, TREE_TYPE (expr), ref_p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -490,8 +441,8 @@ static void
|
|||
lto_output_ts_complex_tree_pointers (struct output_block *ob, tree expr,
|
||||
bool ref_p)
|
||||
{
|
||||
lto_output_tree_or_ref (ob, TREE_REALPART (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, TREE_IMAGPART (expr), ref_p);
|
||||
stream_write_tree (ob, TREE_REALPART (expr), ref_p);
|
||||
stream_write_tree (ob, TREE_IMAGPART (expr), ref_p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -503,8 +454,8 @@ static void
|
|||
lto_output_ts_decl_minimal_tree_pointers (struct output_block *ob, tree expr,
|
||||
bool ref_p)
|
||||
{
|
||||
lto_output_tree_or_ref (ob, DECL_NAME (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, DECL_CONTEXT (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_NAME (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
|
||||
lto_output_location (ob, DECL_SOURCE_LOCATION (expr));
|
||||
}
|
||||
|
||||
|
@ -517,13 +468,13 @@ static void
|
|||
lto_output_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
|
||||
bool ref_p)
|
||||
{
|
||||
lto_output_tree_or_ref (ob, DECL_SIZE (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, DECL_SIZE_UNIT (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_SIZE (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_SIZE_UNIT (expr), ref_p);
|
||||
|
||||
/* Note, DECL_INITIAL is not handled here. Since DECL_INITIAL needs
|
||||
special handling in LTO, it must be handled by streamer hooks. */
|
||||
|
||||
lto_output_tree_or_ref (ob, DECL_ATTRIBUTES (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_ATTRIBUTES (expr), ref_p);
|
||||
|
||||
/* Do not stream DECL_ABSTRACT_ORIGIN. We cannot handle debug information
|
||||
for early inlining so drop it on the floor instead of ICEing in
|
||||
|
@ -535,10 +486,10 @@ lto_output_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
|
|||
if ((TREE_CODE (expr) == VAR_DECL
|
||||
|| TREE_CODE (expr) == PARM_DECL)
|
||||
&& DECL_HAS_VALUE_EXPR_P (expr))
|
||||
lto_output_tree_or_ref (ob, DECL_VALUE_EXPR (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_VALUE_EXPR (expr), ref_p);
|
||||
|
||||
if (TREE_CODE (expr) == VAR_DECL)
|
||||
lto_output_tree_or_ref (ob, DECL_DEBUG_EXPR (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_DEBUG_EXPR (expr), ref_p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -552,10 +503,10 @@ lto_output_ts_decl_non_common_tree_pointers (struct output_block *ob,
|
|||
{
|
||||
if (TREE_CODE (expr) == FUNCTION_DECL)
|
||||
{
|
||||
lto_output_tree_or_ref (ob, DECL_ARGUMENTS (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, DECL_RESULT (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_ARGUMENTS (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_RESULT (expr), ref_p);
|
||||
}
|
||||
lto_output_tree_or_ref (ob, DECL_VINDEX (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_VINDEX (expr), ref_p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -569,12 +520,12 @@ lto_output_ts_decl_with_vis_tree_pointers (struct output_block *ob, tree expr,
|
|||
{
|
||||
/* Make sure we don't inadvertently set the assembler name. */
|
||||
if (DECL_ASSEMBLER_NAME_SET_P (expr))
|
||||
lto_output_tree_or_ref (ob, DECL_ASSEMBLER_NAME (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_ASSEMBLER_NAME (expr), ref_p);
|
||||
else
|
||||
output_record_start (ob, LTO_null);
|
||||
stream_write_tree (ob, NULL_TREE, false);
|
||||
|
||||
lto_output_tree_or_ref (ob, DECL_SECTION_NAME (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, DECL_COMDAT_GROUP (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_SECTION_NAME (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_COMDAT_GROUP (expr), ref_p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -586,11 +537,11 @@ static void
|
|||
lto_output_ts_field_decl_tree_pointers (struct output_block *ob, tree expr,
|
||||
bool ref_p)
|
||||
{
|
||||
lto_output_tree_or_ref (ob, DECL_FIELD_OFFSET (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, DECL_BIT_FIELD_TYPE (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, DECL_QUALIFIER (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, DECL_FIELD_BIT_OFFSET (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, DECL_FCONTEXT (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_FIELD_OFFSET (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_BIT_FIELD_TYPE (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_QUALIFIER (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_FIELD_BIT_OFFSET (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_FCONTEXT (expr), ref_p);
|
||||
lto_output_chain (ob, TREE_CHAIN (expr), ref_p);
|
||||
}
|
||||
|
||||
|
@ -605,10 +556,9 @@ lto_output_ts_function_decl_tree_pointers (struct output_block *ob, tree expr,
|
|||
{
|
||||
/* DECL_STRUCT_FUNCTION is handled by lto_output_function. FIXME lto,
|
||||
maybe it should be handled here? */
|
||||
lto_output_tree_or_ref (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr),
|
||||
ref_p);
|
||||
stream_write_tree (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
|
||||
stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr), ref_p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -620,19 +570,19 @@ static void
|
|||
lto_output_ts_type_common_tree_pointers (struct output_block *ob, tree expr,
|
||||
bool ref_p)
|
||||
{
|
||||
lto_output_tree_or_ref (ob, TYPE_SIZE (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, TYPE_SIZE_UNIT (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, TYPE_ATTRIBUTES (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, TYPE_NAME (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_SIZE (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_SIZE_UNIT (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_ATTRIBUTES (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_NAME (expr), ref_p);
|
||||
/* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO. They will be
|
||||
reconstructed during fixup. */
|
||||
/* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists
|
||||
during fixup. */
|
||||
lto_output_tree_or_ref (ob, TYPE_MAIN_VARIANT (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, TYPE_CONTEXT (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_MAIN_VARIANT (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_CONTEXT (expr), ref_p);
|
||||
/* TYPE_CANONICAL is re-computed during type merging, so no need
|
||||
to stream it here. */
|
||||
lto_output_tree_or_ref (ob, TYPE_STUB_DECL (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_STUB_DECL (expr), ref_p);
|
||||
}
|
||||
|
||||
/* Write all pointer fields in the TS_TYPE_NON_COMMON structure of EXPR
|
||||
|
@ -644,20 +594,20 @@ lto_output_ts_type_non_common_tree_pointers (struct output_block *ob,
|
|||
tree expr, bool ref_p)
|
||||
{
|
||||
if (TREE_CODE (expr) == ENUMERAL_TYPE)
|
||||
lto_output_tree_or_ref (ob, TYPE_VALUES (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_VALUES (expr), ref_p);
|
||||
else if (TREE_CODE (expr) == ARRAY_TYPE)
|
||||
lto_output_tree_or_ref (ob, TYPE_DOMAIN (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_DOMAIN (expr), ref_p);
|
||||
else if (RECORD_OR_UNION_TYPE_P (expr))
|
||||
lto_output_tree_or_ref (ob, TYPE_FIELDS (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_FIELDS (expr), ref_p);
|
||||
else if (TREE_CODE (expr) == FUNCTION_TYPE
|
||||
|| TREE_CODE (expr) == METHOD_TYPE)
|
||||
lto_output_tree_or_ref (ob, TYPE_ARG_TYPES (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_ARG_TYPES (expr), ref_p);
|
||||
|
||||
if (!POINTER_TYPE_P (expr))
|
||||
lto_output_tree_or_ref (ob, TYPE_MINVAL (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, TYPE_MAXVAL (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_MINVAL (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_MAXVAL (expr), ref_p);
|
||||
if (RECORD_OR_UNION_TYPE_P (expr))
|
||||
lto_output_tree_or_ref (ob, TYPE_BINFO (expr), ref_p);
|
||||
stream_write_tree (ob, TYPE_BINFO (expr), ref_p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -669,8 +619,8 @@ static void
|
|||
lto_output_ts_list_tree_pointers (struct output_block *ob, tree expr,
|
||||
bool ref_p)
|
||||
{
|
||||
lto_output_tree_or_ref (ob, TREE_PURPOSE (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, TREE_VALUE (expr), ref_p);
|
||||
stream_write_tree (ob, TREE_PURPOSE (expr), ref_p);
|
||||
stream_write_tree (ob, TREE_VALUE (expr), ref_p);
|
||||
lto_output_chain (ob, TREE_CHAIN (expr), ref_p);
|
||||
}
|
||||
|
||||
|
@ -687,7 +637,7 @@ lto_output_ts_vec_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
|
|||
/* Note that the number of slots for EXPR has already been emitted
|
||||
in EXPR's header (see lto_output_tree_header). */
|
||||
for (i = 0; i < TREE_VEC_LENGTH (expr); i++)
|
||||
lto_output_tree_or_ref (ob, TREE_VEC_ELT (expr, i), ref_p);
|
||||
stream_write_tree (ob, TREE_VEC_ELT (expr, i), ref_p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -702,9 +652,9 @@ lto_output_ts_exp_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
|
|||
|
||||
output_sleb128 (ob, TREE_OPERAND_LENGTH (expr));
|
||||
for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
|
||||
lto_output_tree_or_ref (ob, TREE_OPERAND (expr, i), ref_p);
|
||||
stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
|
||||
lto_output_location (ob, EXPR_LOCATION (expr));
|
||||
lto_output_tree_or_ref (ob, TREE_BLOCK (expr), ref_p);
|
||||
stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -725,12 +675,12 @@ lto_output_ts_block_tree_pointers (struct output_block *ob, tree expr,
|
|||
for early inlining so drop it on the floor instead of ICEing in
|
||||
dwarf2out.c. */
|
||||
|
||||
lto_output_tree_or_ref (ob, BLOCK_SUPERCONTEXT (expr), ref_p);
|
||||
stream_write_tree (ob, BLOCK_SUPERCONTEXT (expr), ref_p);
|
||||
/* Do not stream BLOCK_ABSTRACT_ORIGIN. We cannot handle debug information
|
||||
for early inlining so drop it on the floor instead of ICEing in
|
||||
dwarf2out.c. */
|
||||
lto_output_tree_or_ref (ob, BLOCK_FRAGMENT_ORIGIN (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, BLOCK_FRAGMENT_CHAIN (expr), ref_p);
|
||||
stream_write_tree (ob, BLOCK_FRAGMENT_ORIGIN (expr), ref_p);
|
||||
stream_write_tree (ob, BLOCK_FRAGMENT_CHAIN (expr), ref_p);
|
||||
/* Do not output BLOCK_SUBBLOCKS. Instead on streaming-in this
|
||||
list is re-constructed from BLOCK_SUPERCONTEXT. */
|
||||
}
|
||||
|
@ -751,25 +701,25 @@ lto_output_ts_binfo_tree_pointers (struct output_block *ob, tree expr,
|
|||
EXPR's header (see lto_output_tree_header) because this length
|
||||
is needed to build the empty BINFO node on the reader side. */
|
||||
FOR_EACH_VEC_ELT (tree, BINFO_BASE_BINFOS (expr), i, t)
|
||||
lto_output_tree_or_ref (ob, t, ref_p);
|
||||
output_record_start (ob, LTO_null);
|
||||
stream_write_tree (ob, t, ref_p);
|
||||
stream_write_tree (ob, NULL_TREE, false);
|
||||
|
||||
lto_output_tree_or_ref (ob, BINFO_OFFSET (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, BINFO_VTABLE (expr), ref_p);
|
||||
stream_write_tree (ob, BINFO_OFFSET (expr), ref_p);
|
||||
stream_write_tree (ob, BINFO_VTABLE (expr), ref_p);
|
||||
/* BINFO_VIRTUALS is used to drive type based devirtualizatoin. It often links
|
||||
together large portions of programs making it harder to partition. Becuase
|
||||
devirtualization is interesting before inlining, only, there is no real
|
||||
need to ship it into ltrans partition. */
|
||||
lto_output_tree_or_ref (ob, flag_wpa ? NULL : BINFO_VIRTUALS (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, BINFO_VPTR_FIELD (expr), ref_p);
|
||||
stream_write_tree (ob, flag_wpa ? NULL : BINFO_VIRTUALS (expr), ref_p);
|
||||
stream_write_tree (ob, BINFO_VPTR_FIELD (expr), ref_p);
|
||||
|
||||
output_uleb128 (ob, VEC_length (tree, BINFO_BASE_ACCESSES (expr)));
|
||||
FOR_EACH_VEC_ELT (tree, BINFO_BASE_ACCESSES (expr), i, t)
|
||||
lto_output_tree_or_ref (ob, t, ref_p);
|
||||
stream_write_tree (ob, t, ref_p);
|
||||
|
||||
lto_output_tree_or_ref (ob, BINFO_INHERITANCE_CHAIN (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, BINFO_SUBVTT_INDEX (expr), ref_p);
|
||||
lto_output_tree_or_ref (ob, BINFO_VPTR_INDEX (expr), ref_p);
|
||||
stream_write_tree (ob, BINFO_INHERITANCE_CHAIN (expr), ref_p);
|
||||
stream_write_tree (ob, BINFO_SUBVTT_INDEX (expr), ref_p);
|
||||
stream_write_tree (ob, BINFO_VPTR_INDEX (expr), ref_p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -787,8 +737,8 @@ lto_output_ts_constructor_tree_pointers (struct output_block *ob, tree expr,
|
|||
output_uleb128 (ob, CONSTRUCTOR_NELTS (expr));
|
||||
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (expr), i, index, value)
|
||||
{
|
||||
lto_output_tree_or_ref (ob, index, ref_p);
|
||||
lto_output_tree_or_ref (ob, value, ref_p);
|
||||
stream_write_tree (ob, index, ref_p);
|
||||
stream_write_tree (ob, value, ref_p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -823,11 +773,10 @@ lto_output_ts_translation_unit_decl_tree_pointers (struct output_block *ob,
|
|||
TRANSLATION_UNIT_LANGUAGE (expr), true);
|
||||
}
|
||||
|
||||
/* Helper for lto_output_tree. Write all pointer fields in EXPR to output
|
||||
block OB. If REF_P is true, the leaves of EXPR are emitted as
|
||||
references. */
|
||||
/* Write all pointer fields in EXPR to output block OB. If REF_P is true,
|
||||
the leaves of EXPR are emitted as references. */
|
||||
|
||||
static void
|
||||
void
|
||||
lto_output_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
|
||||
{
|
||||
enum tree_code code;
|
||||
|
@ -896,9 +845,9 @@ lto_output_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
|
|||
/* Emit header information for tree EXPR to output block OB. The header
|
||||
contains everything needed to instantiate an empty skeleton for
|
||||
EXPR on the reading side. IX is the index into the streamer cache
|
||||
where EXPR is stored. REF_P is as in lto_output_tree. */
|
||||
where EXPR is stored. */
|
||||
|
||||
static void
|
||||
void
|
||||
lto_output_tree_header (struct output_block *ob, tree expr)
|
||||
{
|
||||
enum LTO_tags tag;
|
||||
|
@ -906,9 +855,6 @@ lto_output_tree_header (struct output_block *ob, tree expr)
|
|||
|
||||
/* We should not see any tree nodes not handled by the streamer. */
|
||||
code = TREE_CODE (expr);
|
||||
if (!streamer_hooks.is_streamable (expr))
|
||||
internal_error ("tree code %qs is not supported in %s streams",
|
||||
tree_code_name[code], streamer_hooks.name);
|
||||
|
||||
/* The header of a tree node consists of its tag, the size of
|
||||
the node, and any other information needed to instantiate
|
||||
|
@ -937,109 +883,20 @@ lto_output_tree_header (struct output_block *ob, tree expr)
|
|||
output_sleb128 (ob, TREE_VEC_LENGTH (expr));
|
||||
else if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
|
||||
output_uleb128 (ob, BINFO_N_BASE_BINFOS (expr));
|
||||
|
||||
/* Allow the streamer to write any streamer-specific information
|
||||
needed to instantiate the node when reading. */
|
||||
if (streamer_hooks.output_tree_header)
|
||||
streamer_hooks.output_tree_header (ob, expr);
|
||||
else if (TREE_CODE (expr) == CALL_EXPR)
|
||||
output_uleb128 (ob, call_expr_nargs (expr));
|
||||
}
|
||||
|
||||
|
||||
/* Emit the integer constant CST to output block OB. If REF_P is true,
|
||||
CST's type will be emitted as a reference. */
|
||||
|
||||
static void
|
||||
void
|
||||
lto_output_integer_cst (struct output_block *ob, tree cst, bool ref_p)
|
||||
{
|
||||
output_record_start (ob, lto_tree_code_to_tag (INTEGER_CST));
|
||||
lto_output_tree_or_ref (ob, TREE_TYPE (cst), ref_p);
|
||||
stream_write_tree (ob, TREE_TYPE (cst), ref_p);
|
||||
lto_output_1_stream (ob->main_stream, TREE_OVERFLOW_P (cst));
|
||||
output_uleb128 (ob, TREE_INT_CST_LOW (cst));
|
||||
output_uleb128 (ob, TREE_INT_CST_HIGH (cst));
|
||||
}
|
||||
|
||||
|
||||
/* Write a physical representation of tree node EXPR to output block
|
||||
OB. If REF_P is true, the leaves of EXPR are emitted as references
|
||||
via lto_output_tree_ref. IX is the index into the streamer cache
|
||||
where EXPR is stored. */
|
||||
|
||||
static void
|
||||
lto_write_tree (struct output_block *ob, tree expr, bool ref_p)
|
||||
{
|
||||
struct bitpack_d bp;
|
||||
|
||||
/* Write the header, containing everything needed to materialize
|
||||
EXPR on the reading side. */
|
||||
lto_output_tree_header (ob, expr);
|
||||
|
||||
/* Pack all the non-pointer fields in EXPR into a bitpack and write
|
||||
the resulting bitpack. */
|
||||
bp = bitpack_create (ob->main_stream);
|
||||
pack_value_fields (&bp, expr);
|
||||
lto_output_bitpack (&bp);
|
||||
|
||||
/* Write all the pointer fields in EXPR. */
|
||||
lto_output_tree_pointers (ob, expr, ref_p);
|
||||
|
||||
/* Call back into the streaming module to see if it needs to write
|
||||
anything that was not written by the common streamer. */
|
||||
if (streamer_hooks.write_tree)
|
||||
streamer_hooks.write_tree (ob, expr, ref_p);
|
||||
|
||||
/* Mark the end of EXPR. */
|
||||
output_zero (ob);
|
||||
}
|
||||
|
||||
|
||||
/* Emit the physical representation of tree node EXPR to output block
|
||||
OB. If REF_P is true, the leaves of EXPR are emitted as references
|
||||
via lto_output_tree_ref. */
|
||||
|
||||
void
|
||||
lto_output_tree (struct output_block *ob, tree expr, bool ref_p)
|
||||
{
|
||||
unsigned ix;
|
||||
bool existed_p;
|
||||
|
||||
if (expr == NULL_TREE)
|
||||
{
|
||||
output_record_start (ob, LTO_null);
|
||||
return;
|
||||
}
|
||||
|
||||
/* INTEGER_CST nodes are special because they need their original type
|
||||
to be materialized by the reader (to implement TYPE_CACHED_VALUES). */
|
||||
if (TREE_CODE (expr) == INTEGER_CST)
|
||||
{
|
||||
lto_output_integer_cst (ob, expr, ref_p);
|
||||
return;
|
||||
}
|
||||
|
||||
existed_p = lto_streamer_cache_insert (ob->writer_cache, expr, &ix);
|
||||
if (existed_p)
|
||||
{
|
||||
/* If a node has already been streamed out, make sure that
|
||||
we don't write it more than once. Otherwise, the reader
|
||||
will instantiate two different nodes for the same object. */
|
||||
output_record_start (ob, LTO_tree_pickle_reference);
|
||||
output_uleb128 (ob, ix);
|
||||
lto_output_enum (ob->main_stream, LTO_tags, LTO_NUM_TAGS,
|
||||
lto_tree_code_to_tag (TREE_CODE (expr)));
|
||||
}
|
||||
else if (lto_stream_as_builtin_p (expr))
|
||||
{
|
||||
/* MD and NORMAL builtins do not need to be written out
|
||||
completely as they are always instantiated by the
|
||||
compiler on startup. The only builtins that need to
|
||||
be written out are BUILT_IN_FRONTEND. For all other
|
||||
builtins, we simply write the class and code. */
|
||||
lto_output_builtin_tree (ob, expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is the first time we see EXPR, write its fields
|
||||
to OB. */
|
||||
lto_write_tree (ob, expr, ref_p);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -245,6 +245,66 @@ lto_streamer_cache_get (struct lto_streamer_cache_d *cache, unsigned 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. */
|
||||
|
||||
struct lto_streamer_cache_d *
|
||||
|
@ -259,7 +319,7 @@ lto_streamer_cache_create (void)
|
|||
/* Load all the well-known tree nodes that are always created by
|
||||
the compiler on startup. This prevents writing them out
|
||||
unnecessarily. */
|
||||
streamer_hooks.preload_common_nodes (cache);
|
||||
preload_common_nodes (cache);
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#define GCC_TREE_STREAMER_H
|
||||
|
||||
#include "tree.h"
|
||||
#include "streamer-hooks.h"
|
||||
#include "lto-streamer.h"
|
||||
|
||||
/* Cache of pickled nodes. Used to avoid writing the same node more
|
||||
|
@ -51,14 +52,35 @@ struct lto_streamer_cache_d
|
|||
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. */
|
||||
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 *, struct data_in *, tree);
|
||||
tree lto_materialize_tree (struct lto_input_block *, struct data_in *,
|
||||
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. */
|
||||
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. */
|
||||
void check_handled_ts_structures (void);
|
||||
|
|
Loading…
Reference in New Issue