diff options
author | Richard Guenther <rguenther@suse.de> | 2010-06-14 18:54:17 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-06-14 18:54:17 +0000 |
commit | 2465dcc257488294138948de82a734c31b504ecf (patch) | |
tree | 1c5576f53e0b1246f2c6689424de8733223cce84 | |
parent | 808081b47f28975725f1a648cb92632a7a399be5 (diff) | |
download | gcc-2465dcc257488294138948de82a734c31b504ecf.zip gcc-2465dcc257488294138948de82a734c31b504ecf.tar.gz gcc-2465dcc257488294138948de82a734c31b504ecf.tar.bz2 |
lto-streamer.c (cached_bp): Remove.
2010-06-14 Richard Guenther <rguenther@suse.de>
* lto-streamer.c (cached_bp): Remove.
(bitpack_delete): Likewise.
(bitpack_create): Likewise.
(bp_get_next_word): Likewise.
(bp_pack_value, bp_unpack_value): Move ...
* lto-streamer.h (bp_pack_value, bp_unpack_value): ... here.
Re-implement.
(struct bitpack_d): Likewise.
(bitpack_create, lto_output_bitpack, lto_input_bitpack):
New inline functions.
* lto-streamer-out.c (lto_output_bitpack): Remove.
(pack_ts_base_value_fields): Adjust. Avoid conditional
bitpacking.
(pack_value_fields): Adjust.
(lto_write_tree): Likewise.
(output_gimple_stmt): Likewise.
(output_function): Likewise.
* lto-streamer-in.c (input_gimple_stmt): Adjust.
(input_function): Likewise.
(unpack_ts_base_value_fields): Adjust. Avoid conditional
bitpacking.
(lto_input_bitpack): Remove.
(lto_materialize_tree): Adjust.
* Makefile.in (ipa-prop.o): Add $(LTO_STREAMER_H) dependency.
* lto-cgraph.c (lto_output_edge): Adjust.
(lto_output_node): Likewise.
(lto_output_varpool_node): Likewise.
(lto_output_ref): Likewise.
(input_node): Likewise.
(input_varpool_node): Likewise.
(input_ref): Likewise.
(input_edge): Likewise.
(output_node_opt_summary): Likewise.
(input_node_opt_summary): Likewise.
* ipa-pure-const.c (pure_const_write_summary): Likewise.
(pure_const_read_summary): Likewise.
* ipa-prop.c (ipa_write_indirect_edge_info): Likewise.
(ipa_read_indirect_edge_info): Likewise.
(ipa_write_node_info): Likewise.
(ipa_read_node_info): Likewise.
From-SVN: r160760
-rw-r--r-- | gcc/ChangeLog | 43 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 40 | ||||
-rw-r--r-- | gcc/ipa-pure-const.c | 30 | ||||
-rw-r--r-- | gcc/lto-cgraph.c | 197 | ||||
-rw-r--r-- | gcc/lto-streamer-in.c | 87 | ||||
-rw-r--r-- | gcc/lto-streamer-out.c | 92 | ||||
-rw-r--r-- | gcc/lto-streamer.c | 141 | ||||
-rw-r--r-- | gcc/lto-streamer.h | 102 |
9 files changed, 328 insertions, 406 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 206b848..c4f9c04 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,46 @@ +2010-06-14 Richard Guenther <rguenther@suse.de> + + * lto-streamer.c (cached_bp): Remove. + (bitpack_delete): Likewise. + (bitpack_create): Likewise. + (bp_get_next_word): Likewise. + (bp_pack_value, bp_unpack_value): Move ... + * lto-streamer.h (bp_pack_value, bp_unpack_value): ... here. + Re-implement. + (struct bitpack_d): Likewise. + (bitpack_create, lto_output_bitpack, lto_input_bitpack): + New inline functions. + * lto-streamer-out.c (lto_output_bitpack): Remove. + (pack_ts_base_value_fields): Adjust. Avoid conditional + bitpacking. + (pack_value_fields): Adjust. + (lto_write_tree): Likewise. + (output_gimple_stmt): Likewise. + (output_function): Likewise. + * lto-streamer-in.c (input_gimple_stmt): Adjust. + (input_function): Likewise. + (unpack_ts_base_value_fields): Adjust. Avoid conditional + bitpacking. + (lto_input_bitpack): Remove. + (lto_materialize_tree): Adjust. + * Makefile.in (ipa-prop.o): Add $(LTO_STREAMER_H) dependency. + * lto-cgraph.c (lto_output_edge): Adjust. + (lto_output_node): Likewise. + (lto_output_varpool_node): Likewise. + (lto_output_ref): Likewise. + (input_node): Likewise. + (input_varpool_node): Likewise. + (input_ref): Likewise. + (input_edge): Likewise. + (output_node_opt_summary): Likewise. + (input_node_opt_summary): Likewise. + * ipa-pure-const.c (pure_const_write_summary): Likewise. + (pure_const_read_summary): Likewise. + * ipa-prop.c (ipa_write_indirect_edge_info): Likewise. + (ipa_read_indirect_edge_info): Likewise. + (ipa_write_node_info): Likewise. + (ipa_read_node_info): Likewise. + 2010-06-14 H.J. Lu <hongjiu.lu@intel.com> PR target/44534 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 0d4f746..98ed23d 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2995,7 +2995,7 @@ ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(DIAGNOSTIC_H) \ $(TREE_FLOW_H) $(TM_H) $(TREE_PASS_H) $(FLAGS_H) $(TREE_H) \ $(TREE_INLINE_H) $(GIMPLE_H) $(GIMPLE_FOLD_H) $(TIMEVAR_H) \ - tree-pretty-print.h gimple-pretty-print.h + tree-pretty-print.h gimple-pretty-print.h $(LTO_STREAMER_H) ipa-ref.o : ipa-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(TREE_H) $(TARGET_H) \ $(TREE_FLOW_H) $(TM_H) $(TREE_PASS_H) $(FLAGS_H) $(TREE_H) $(GGC_H) diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 6aeca33..38eb3c0 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -2403,14 +2403,13 @@ ipa_write_indirect_edge_info (struct output_block *ob, struct cgraph_edge *cs) { struct cgraph_indirect_call_info *ii = cs->indirect_info; - struct bitpack_d *bp; + struct bitpack_d bp; lto_output_sleb128_stream (ob->main_stream, ii->param_index); lto_output_sleb128_stream (ob->main_stream, ii->anc_offset); - bp = bitpack_create (); - bp_pack_value (bp, ii->polymorphic, 1); - lto_output_bitpack (ob->main_stream, bp); - bitpack_delete (bp); + bp = bitpack_create (ob->main_stream); + bp_pack_value (&bp, ii->polymorphic, 1); + lto_output_bitpack (&bp); if (ii->polymorphic) { @@ -2428,13 +2427,12 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib, struct cgraph_edge *cs) { struct cgraph_indirect_call_info *ii = cs->indirect_info; - struct bitpack_d *bp; + struct bitpack_d bp; ii->param_index = (int) lto_input_sleb128 (ib); ii->anc_offset = (HOST_WIDE_INT) lto_input_sleb128 (ib); bp = lto_input_bitpack (ib); - ii->polymorphic = bp_unpack_value (bp, 1); - bitpack_delete (bp); + ii->polymorphic = bp_unpack_value (&bp, 1); if (ii->polymorphic) { ii->otr_token = (HOST_WIDE_INT) lto_input_sleb128 (ib); @@ -2452,26 +2450,25 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node) struct ipa_node_params *info = IPA_NODE_REF (node); int j; struct cgraph_edge *e; - struct bitpack_d *bp; + struct bitpack_d bp; encoder = ob->decl_state->cgraph_node_encoder; node_ref = lto_cgraph_encoder_encode (encoder, node); lto_output_uleb128_stream (ob->main_stream, node_ref); - bp = bitpack_create (); - bp_pack_value (bp, info->called_with_var_arguments, 1); - bp_pack_value (bp, info->uses_analysis_done, 1); + bp = bitpack_create (ob->main_stream); + bp_pack_value (&bp, info->called_with_var_arguments, 1); + bp_pack_value (&bp, info->uses_analysis_done, 1); gcc_assert (info->modification_analysis_done || ipa_get_param_count (info) == 0); gcc_assert (!info->node_enqueued); gcc_assert (!info->ipcp_orig_node); for (j = 0; j < ipa_get_param_count (info); j++) { - bp_pack_value (bp, info->params[j].modified, 1); - bp_pack_value (bp, info->params[j].used, 1); + bp_pack_value (&bp, info->params[j].modified, 1); + bp_pack_value (&bp, info->params[j].used, 1); } - lto_output_bitpack (ob->main_stream, bp); - bitpack_delete (bp); + lto_output_bitpack (&bp); for (e = node->callees; e; e = e->next_callee) { struct ipa_edge_args *args = IPA_EDGE_REF (e); @@ -2494,13 +2491,13 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node, struct ipa_node_params *info = IPA_NODE_REF (node); int k; struct cgraph_edge *e; - struct bitpack_d *bp; + struct bitpack_d bp; ipa_initialize_node_params (node); bp = lto_input_bitpack (ib); - info->called_with_var_arguments = bp_unpack_value (bp, 1); - info->uses_analysis_done = bp_unpack_value (bp, 1); + info->called_with_var_arguments = bp_unpack_value (&bp, 1); + info->uses_analysis_done = bp_unpack_value (&bp, 1); if (ipa_get_param_count (info) != 0) { info->modification_analysis_done = true; @@ -2509,10 +2506,9 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node, info->node_enqueued = false; for (k = 0; k < ipa_get_param_count (info); k++) { - info->params[k].modified = bp_unpack_value (bp, 1); - info->params[k].used = bp_unpack_value (bp, 1); + info->params[k].modified = bp_unpack_value (&bp, 1); + info->params[k].used = bp_unpack_value (&bp, 1); } - bitpack_delete (bp); for (e = node->callees; e; e = e->next_callee) { struct ipa_edge_args *args = IPA_EDGE_REF (e); diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index 8678663..bc17b0c 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -943,7 +943,7 @@ pure_const_write_summary (cgraph_node_set set, node = csi_node (csi); if (node->analyzed && has_function_state (node)) { - struct bitpack_d *bp; + struct bitpack_d bp; funct_state fs; int node_ref; lto_cgraph_encoder_t encoder; @@ -956,14 +956,13 @@ pure_const_write_summary (cgraph_node_set set, /* Note that flags will need to be read in the opposite order as we are pushing the bitflags into FLAGS. */ - bp = bitpack_create (); - bp_pack_value (bp, fs->pure_const_state, 2); - bp_pack_value (bp, fs->state_previously_known, 2); - bp_pack_value (bp, fs->looping_previously_known, 1); - bp_pack_value (bp, fs->looping, 1); - bp_pack_value (bp, fs->can_throw, 1); - lto_output_bitpack (ob->main_stream, bp); - bitpack_delete (bp); + bp = bitpack_create (ob->main_stream); + bp_pack_value (&bp, fs->pure_const_state, 2); + bp_pack_value (&bp, fs->state_previously_known, 2); + bp_pack_value (&bp, fs->looping_previously_known, 1); + bp_pack_value (&bp, fs->looping, 1); + bp_pack_value (&bp, fs->can_throw, 1); + lto_output_bitpack (&bp); } } @@ -998,7 +997,7 @@ pure_const_read_summary (void) { unsigned int index; struct cgraph_node *node; - struct bitpack_d *bp; + struct bitpack_d bp; funct_state fs; lto_cgraph_encoder_t encoder; @@ -1013,12 +1012,12 @@ pure_const_read_summary (void) pushed into FLAGS). */ bp = lto_input_bitpack (ib); fs->pure_const_state - = (enum pure_const_state_e) bp_unpack_value (bp, 2); + = (enum pure_const_state_e) bp_unpack_value (&bp, 2); fs->state_previously_known - = (enum pure_const_state_e) bp_unpack_value (bp, 2); - fs->looping_previously_known = bp_unpack_value (bp, 1); - fs->looping = bp_unpack_value (bp, 1); - fs->can_throw = bp_unpack_value (bp, 1); + = (enum pure_const_state_e) bp_unpack_value (&bp, 2); + fs->looping_previously_known = bp_unpack_value (&bp, 1); + fs->looping = bp_unpack_value (&bp, 1); + fs->can_throw = bp_unpack_value (&bp, 1); if (dump_file) { int flags = flags_from_decl_or_type (node->decl); @@ -1042,7 +1041,6 @@ pure_const_read_summary (void) if (fs->can_throw) fprintf (dump_file," function is locally throwing\n"); } - bitpack_delete (bp); } lto_destroy_simple_input_block (file_data, diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index dd7b954..9722a80 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -260,7 +260,7 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge, { unsigned int uid; intptr_t ref; - struct bitpack_d *bp; + struct bitpack_d bp; if (edge->indirect_unknown_callee) lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_indirect_edge); @@ -280,32 +280,31 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge, lto_output_sleb128_stream (ob->main_stream, edge->count); - bp = bitpack_create (); + bp = bitpack_create (ob->main_stream); uid = flag_wpa ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt); - bp_pack_value (bp, uid, HOST_BITS_PER_INT); - bp_pack_value (bp, edge->inline_failed, HOST_BITS_PER_INT); - bp_pack_value (bp, edge->frequency, HOST_BITS_PER_INT); - bp_pack_value (bp, edge->loop_nest, 30); - bp_pack_value (bp, edge->indirect_inlining_edge, 1); - bp_pack_value (bp, edge->call_stmt_cannot_inline_p, 1); - bp_pack_value (bp, edge->can_throw_external, 1); + bp_pack_value (&bp, uid, HOST_BITS_PER_INT); + bp_pack_value (&bp, edge->inline_failed, HOST_BITS_PER_INT); + bp_pack_value (&bp, edge->frequency, HOST_BITS_PER_INT); + bp_pack_value (&bp, edge->loop_nest, 30); + bp_pack_value (&bp, edge->indirect_inlining_edge, 1); + bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1); + bp_pack_value (&bp, edge->can_throw_external, 1); if (edge->indirect_unknown_callee) { int flags = edge->indirect_info->ecf_flags; - bp_pack_value (bp, (flags & ECF_CONST) != 0, 1); - bp_pack_value (bp, (flags & ECF_PURE) != 0, 1); - bp_pack_value (bp, (flags & ECF_NORETURN) != 0, 1); - bp_pack_value (bp, (flags & ECF_MALLOC) != 0, 1); - bp_pack_value (bp, (flags & ECF_NOTHROW) != 0, 1); - bp_pack_value (bp, (flags & ECF_RETURNS_TWICE) != 0, 1); + bp_pack_value (&bp, (flags & ECF_CONST) != 0, 1); + bp_pack_value (&bp, (flags & ECF_PURE) != 0, 1); + bp_pack_value (&bp, (flags & ECF_NORETURN) != 0, 1); + bp_pack_value (&bp, (flags & ECF_MALLOC) != 0, 1); + bp_pack_value (&bp, (flags & ECF_NOTHROW) != 0, 1); + bp_pack_value (&bp, (flags & ECF_RETURNS_TWICE) != 0, 1); /* Flags that should not appear on indirect calls. */ gcc_assert (!(flags & (ECF_LOOPING_CONST_OR_PURE | ECF_MAY_BE_ALLOCA | ECF_SIBCALL | ECF_NOVOPS))); } - lto_output_bitpack (ob->main_stream, bp); - bitpack_delete (bp); + lto_output_bitpack (&bp); } /* Return if LIST contain references from other partitions. */ @@ -404,7 +403,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, varpool_node_set vset) { unsigned int tag; - struct bitpack_d *bp; + struct bitpack_d bp; bool boundary_p; intptr_t ref; bool in_other_partition = false; @@ -458,30 +457,6 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, lto_output_fn_decl_index (ob->decl_state, ob->main_stream, node->decl); lto_output_sleb128_stream (ob->main_stream, node->count); - bp = bitpack_create (); - bp_pack_value (bp, node->local.local, 1); - bp_pack_value (bp, node->local.externally_visible, 1); - bp_pack_value (bp, node->local.finalized, 1); - bp_pack_value (bp, node->local.inlinable, 1); - bp_pack_value (bp, node->local.versionable, 1); - bp_pack_value (bp, node->local.disregard_inline_limits, 1); - bp_pack_value (bp, node->local.redefined_extern_inline, 1); - bp_pack_value (bp, node->local.vtable_method, 1); - bp_pack_value (bp, node->needed, 1); - bp_pack_value (bp, node->address_taken, 1); - bp_pack_value (bp, node->abstract_and_needed, 1); - bp_pack_value (bp, tag == LTO_cgraph_analyzed_node - && !DECL_EXTERNAL (node->decl) - && (reachable_from_other_partition_p (node, set) - || referenced_from_other_partition_p (&node->ref_list, set, vset)), 1); - bp_pack_value (bp, node->lowered, 1); - bp_pack_value (bp, in_other_partition, 1); - bp_pack_value (bp, node->alias, 1); - bp_pack_value (bp, node->finalized_by_frontend, 1); - bp_pack_value (bp, node->frequency, 2); - lto_output_bitpack (ob->main_stream, bp); - bitpack_delete (bp); - if (tag == LTO_cgraph_analyzed_node) { lto_output_sleb128_stream (ob->main_stream, @@ -514,6 +489,29 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, ref = LCC_NOT_FOUND; lto_output_sleb128_stream (ob->main_stream, ref); + bp = bitpack_create (ob->main_stream); + bp_pack_value (&bp, node->local.local, 1); + bp_pack_value (&bp, node->local.externally_visible, 1); + bp_pack_value (&bp, node->local.finalized, 1); + bp_pack_value (&bp, node->local.inlinable, 1); + bp_pack_value (&bp, node->local.versionable, 1); + bp_pack_value (&bp, node->local.disregard_inline_limits, 1); + bp_pack_value (&bp, node->local.redefined_extern_inline, 1); + bp_pack_value (&bp, node->local.vtable_method, 1); + bp_pack_value (&bp, node->needed, 1); + bp_pack_value (&bp, node->address_taken, 1); + bp_pack_value (&bp, node->abstract_and_needed, 1); + bp_pack_value (&bp, tag == LTO_cgraph_analyzed_node + && !DECL_EXTERNAL (node->decl) + && (reachable_from_other_partition_p (node, set) + || referenced_from_other_partition_p (&node->ref_list, set, vset)), 1); + bp_pack_value (&bp, node->lowered, 1); + bp_pack_value (&bp, in_other_partition, 1); + bp_pack_value (&bp, node->alias, 1); + bp_pack_value (&bp, node->finalized_by_frontend, 1); + bp_pack_value (&bp, node->frequency, 2); + lto_output_bitpack (&bp); + if (node->same_body) { struct cgraph_node *alias; @@ -561,17 +559,17 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node cgraph_node_set set, varpool_node_set vset) { bool boundary_p = !varpool_node_in_set_p (node, vset) && node->analyzed; - struct bitpack_d *bp; + struct bitpack_d bp; struct varpool_node *alias; int count = 0; int ref; lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->decl); - bp = bitpack_create (); - bp_pack_value (bp, node->externally_visible, 1); - bp_pack_value (bp, node->force_output, 1); - bp_pack_value (bp, node->finalized, 1); - bp_pack_value (bp, node->alias, 1); + bp = bitpack_create (ob->main_stream); + bp_pack_value (&bp, node->externally_visible, 1); + bp_pack_value (&bp, node->force_output, 1); + bp_pack_value (&bp, node->finalized, 1); + bp_pack_value (&bp, node->alias, 1); gcc_assert (!node->alias || !node->extra_name); gcc_assert (node->finalized || !node->analyzed); gcc_assert (node->needed); @@ -580,22 +578,21 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node labels and share them across LTRANS partitions. */ if (DECL_IN_CONSTANT_POOL (node->decl)) { - bp_pack_value (bp, 0, 1); /* used_from_other_parition. */ - bp_pack_value (bp, 0, 1); /* in_other_partition. */ + bp_pack_value (&bp, 0, 1); /* used_from_other_parition. */ + bp_pack_value (&bp, 0, 1); /* in_other_partition. */ } else { - bp_pack_value (bp, node->analyzed + bp_pack_value (&bp, node->analyzed && referenced_from_other_partition_p (&node->ref_list, set, vset), 1); - bp_pack_value (bp, boundary_p, 1); /* in_other_partition. */ + bp_pack_value (&bp, boundary_p, 1); /* in_other_partition. */ } /* Also emit any extra name aliases. */ for (alias = node->extra_name; alias; alias = alias->next) count++; - bp_pack_value (bp, count != 0, 1); - lto_output_bitpack (ob->main_stream, bp); - bitpack_delete (bp); + bp_pack_value (&bp, count != 0, 1); + lto_output_bitpack (&bp); if (node->same_comdat_group && !boundary_p) { ref = lto_varpool_encoder_lookup (varpool_encoder, node->same_comdat_group); @@ -621,11 +618,11 @@ lto_output_ref (struct lto_simple_output_block *ob, struct ipa_ref *ref, lto_cgraph_encoder_t encoder, lto_varpool_encoder_t varpool_encoder) { - struct bitpack_d *bp = bitpack_create (); - bp_pack_value (bp, ref->refered_type, 1); - bp_pack_value (bp, ref->use, 2); - lto_output_bitpack (ob->main_stream, bp); - bitpack_delete (bp); + struct bitpack_d bp; + bp = bitpack_create (ob->main_stream); + bp_pack_value (&bp, ref->refered_type, 1); + bp_pack_value (&bp, ref->use, 2); + lto_output_bitpack (&bp); if (ref->refered_type == IPA_REF_CGRAPH) { int nref = lto_cgraph_encoder_lookup (encoder, ipa_ref_node (ref)); @@ -981,7 +978,7 @@ input_node (struct lto_file_decl_data *file_data, { tree fn_decl; struct cgraph_node *node; - struct bitpack_d *bp; + struct bitpack_d bp; int stack_size = 0; unsigned decl_index; int ref = LCC_NOT_FOUND, ref2 = LCC_NOT_FOUND; @@ -1006,7 +1003,6 @@ input_node (struct lto_file_decl_data *file_data, node = cgraph_node (fn_decl); node->count = lto_input_sleb128 (ib); - bp = lto_input_bitpack (ib); if (tag == LTO_cgraph_analyzed_node) { @@ -1020,7 +1016,6 @@ input_node (struct lto_file_decl_data *file_data, } ref2 = lto_input_sleb128 (ib); - same_body_count = lto_input_uleb128 (ib); /* Make sure that we have not read this node before. Nodes that have already been read will have their tag stored in the 'aux' @@ -1030,10 +1025,10 @@ input_node (struct lto_file_decl_data *file_data, internal_error ("bytecode stream: found multiple instances of cgraph " "node %d", node->uid); - input_overwrite_node (file_data, node, tag, bp, stack_size, self_time, + bp = lto_input_bitpack (ib); + input_overwrite_node (file_data, node, tag, &bp, stack_size, self_time, time_inlining_benefit, self_size, size_inlining_benefit); - bitpack_delete (bp); /* Store a reference for now, and fix up later to be a pointer. */ node->global.inlined_to = (cgraph_node_ptr) (intptr_t) ref; @@ -1041,6 +1036,7 @@ input_node (struct lto_file_decl_data *file_data, /* Store a reference for now, and fix up later to be a pointer. */ node->same_comdat_group = (cgraph_node_ptr) (intptr_t) ref2; + same_body_count = lto_input_uleb128 (ib); while (same_body_count-- > 0) { tree alias_decl; @@ -1081,7 +1077,7 @@ input_varpool_node (struct lto_file_decl_data *file_data, int decl_index; tree var_decl; struct varpool_node *node; - struct bitpack_d *bp; + struct bitpack_d bp; bool aliases_p; int count; int ref = LCC_NOT_FOUND; @@ -1092,17 +1088,16 @@ input_varpool_node (struct lto_file_decl_data *file_data, node->lto_file_data = file_data; bp = lto_input_bitpack (ib); - node->externally_visible = bp_unpack_value (bp, 1); - node->force_output = bp_unpack_value (bp, 1); - node->finalized = bp_unpack_value (bp, 1); - node->alias = bp_unpack_value (bp, 1); + node->externally_visible = bp_unpack_value (&bp, 1); + node->force_output = bp_unpack_value (&bp, 1); + node->finalized = bp_unpack_value (&bp, 1); + node->alias = bp_unpack_value (&bp, 1); node->analyzed = node->finalized; - node->used_from_other_partition = bp_unpack_value (bp, 1); - node->in_other_partition = bp_unpack_value (bp, 1); - aliases_p = bp_unpack_value (bp, 1); + node->used_from_other_partition = bp_unpack_value (&bp, 1); + node->in_other_partition = bp_unpack_value (&bp, 1); + aliases_p = bp_unpack_value (&bp, 1); if (node->finalized) varpool_mark_needed_node (node); - bitpack_delete (bp); ref = lto_input_sleb128 (ib); /* Store a reference for now, and fix up later to be a pointer. */ node->same_comdat_group = (struct varpool_node *) (intptr_t) ref; @@ -1131,14 +1126,13 @@ input_ref (struct lto_input_block *ib, { struct cgraph_node *node = NULL; struct varpool_node *varpool_node = NULL; - struct bitpack_d *bp; + struct bitpack_d bp; enum ipa_ref_type type; enum ipa_ref_use use; bp = lto_input_bitpack (ib); - type = (enum ipa_ref_type) bp_unpack_value (bp, 1); - use = (enum ipa_ref_use) bp_unpack_value (bp, 2); - bitpack_delete (bp); + type = (enum ipa_ref_type) bp_unpack_value (&bp, 1); + use = (enum ipa_ref_use) bp_unpack_value (&bp, 2); if (type == IPA_REF_CGRAPH) node = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib)); else @@ -1163,7 +1157,7 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes, int freq; unsigned int nest; cgraph_inline_failed_t inline_failed; - struct bitpack_d *bp; + struct bitpack_d bp; enum ld_plugin_symbol_resolution caller_resolution; int ecf_flags = 0; @@ -1183,11 +1177,11 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes, count = (gcov_type) lto_input_sleb128 (ib); bp = lto_input_bitpack (ib); - stmt_id = (unsigned int) bp_unpack_value (bp, HOST_BITS_PER_INT); - inline_failed = (cgraph_inline_failed_t) bp_unpack_value (bp, + stmt_id = (unsigned int) bp_unpack_value (&bp, HOST_BITS_PER_INT); + inline_failed = (cgraph_inline_failed_t) bp_unpack_value (&bp, HOST_BITS_PER_INT); - freq = (int) bp_unpack_value (bp, HOST_BITS_PER_INT); - nest = (unsigned) bp_unpack_value (bp, 30); + freq = (int) bp_unpack_value (&bp, HOST_BITS_PER_INT); + nest = (unsigned) bp_unpack_value (&bp, 30); /* If the caller was preempted, don't create the edge. ??? Should we ever have edges from a preempted caller? */ @@ -1201,28 +1195,27 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes, else edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest); - edge->indirect_inlining_edge = bp_unpack_value (bp, 1); + edge->indirect_inlining_edge = bp_unpack_value (&bp, 1); edge->lto_stmt_uid = stmt_id; edge->inline_failed = inline_failed; - edge->call_stmt_cannot_inline_p = bp_unpack_value (bp, 1); - edge->can_throw_external = bp_unpack_value (bp, 1); + edge->call_stmt_cannot_inline_p = bp_unpack_value (&bp, 1); + edge->can_throw_external = bp_unpack_value (&bp, 1); if (indirect) { - if (bp_unpack_value (bp, 1)) + if (bp_unpack_value (&bp, 1)) ecf_flags |= ECF_CONST; - if (bp_unpack_value (bp, 1)) + if (bp_unpack_value (&bp, 1)) ecf_flags |= ECF_PURE; - if (bp_unpack_value (bp, 1)) + if (bp_unpack_value (&bp, 1)) ecf_flags |= ECF_NORETURN; - if (bp_unpack_value (bp, 1)) + if (bp_unpack_value (&bp, 1)) ecf_flags |= ECF_MALLOC; - if (bp_unpack_value (bp, 1)) + if (bp_unpack_value (&bp, 1)) ecf_flags |= ECF_NOTHROW; - if (bp_unpack_value (bp, 1)) + if (bp_unpack_value (&bp, 1)) ecf_flags |= ECF_RETURNS_TWICE; edge->indirect_info->ecf_flags = ecf_flags; } - bitpack_delete (bp); } @@ -1470,7 +1463,7 @@ output_node_opt_summary (struct output_block *ob, unsigned int index; bitmap_iterator bi; struct ipa_replace_map *map; - struct bitpack_d *bp; + struct bitpack_d bp; int i; lto_output_uleb128_stream (ob->main_stream, @@ -1497,11 +1490,10 @@ output_node_opt_summary (struct output_block *ob, gcc_assert (parm); lto_output_uleb128_stream (ob->main_stream, parm_num); lto_output_tree (ob, map->new_tree, true); - bp = bitpack_create (); - bp_pack_value (bp, map->replace_p, 1); - bp_pack_value (bp, map->ref_p, 1); - lto_output_bitpack (ob->main_stream, bp); - bitpack_delete (bp); + bp = bitpack_create (ob->main_stream); + bp_pack_value (&bp, map->replace_p, 1); + bp_pack_value (&bp, map->ref_p, 1); + lto_output_bitpack (&bp); } } @@ -1547,7 +1539,7 @@ input_node_opt_summary (struct cgraph_node *node, int i; int count; int bit; - struct bitpack_d *bp; + struct bitpack_d bp; count = lto_input_uleb128 (ib_main); if (count) @@ -1580,9 +1572,8 @@ input_node_opt_summary (struct cgraph_node *node, map->old_tree = NULL; map->new_tree = lto_input_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); - bitpack_delete (bp); + map->replace_p = bp_unpack_value (&bp, 1); + map->ref_p = bp_unpack_value (&bp, 1); } } diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index d56cf5d..e875460 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -1001,20 +1001,19 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, enum gimple_code code; unsigned HOST_WIDE_INT num_ops; size_t i; - struct bitpack_d *bp; + struct bitpack_d bp; code = lto_tag_to_gimple_code (tag); /* Read the tuple header. */ bp = lto_input_bitpack (ib); - num_ops = bp_unpack_value (bp, sizeof (unsigned) * 8); + num_ops = bp_unpack_value (&bp, sizeof (unsigned) * 8); stmt = gimple_alloc (code, num_ops); - stmt->gsbase.no_warning = bp_unpack_value (bp, 1); + stmt->gsbase.no_warning = bp_unpack_value (&bp, 1); if (is_gimple_assign (stmt)) - stmt->gsbase.nontemporal_move = bp_unpack_value (bp, 1); - stmt->gsbase.has_volatile_ops = bp_unpack_value (bp, 1); - stmt->gsbase.subcode = bp_unpack_value (bp, 16); - bitpack_delete (bp); + stmt->gsbase.nontemporal_move = bp_unpack_value (&bp, 1); + stmt->gsbase.has_volatile_ops = bp_unpack_value (&bp, 1); + stmt->gsbase.subcode = bp_unpack_value (&bp, 16); /* Read location information. */ gimple_set_location (stmt, lto_input_location (ib, data_in)); @@ -1291,7 +1290,7 @@ input_function (tree fn_decl, struct data_in *data_in, enum LTO_tags tag; gimple *stmts; basic_block bb; - struct bitpack_d *bp; + struct bitpack_d bp; struct cgraph_node *node; tree args, narg, oarg; @@ -1304,22 +1303,21 @@ input_function (tree fn_decl, struct data_in *data_in, /* Read all the attributes for FN. */ bp = lto_input_bitpack (ib); - fn->is_thunk = bp_unpack_value (bp, 1); - fn->has_local_explicit_reg_vars = bp_unpack_value (bp, 1); - fn->after_tree_profile = bp_unpack_value (bp, 1); - fn->returns_pcc_struct = bp_unpack_value (bp, 1); - fn->returns_struct = bp_unpack_value (bp, 1); - fn->can_throw_non_call_exceptions = bp_unpack_value (bp, 1); - fn->always_inline_functions_inlined = bp_unpack_value (bp, 1); - fn->after_inlining = bp_unpack_value (bp, 1); - fn->dont_save_pending_sizes_p = bp_unpack_value (bp, 1); - fn->stdarg = bp_unpack_value (bp, 1); - fn->has_nonlocal_label = bp_unpack_value (bp, 1); - fn->calls_alloca = bp_unpack_value (bp, 1); - fn->calls_setjmp = bp_unpack_value (bp, 1); - fn->va_list_fpr_size = bp_unpack_value (bp, 8); - fn->va_list_gpr_size = bp_unpack_value (bp, 8); - bitpack_delete (bp); + fn->is_thunk = bp_unpack_value (&bp, 1); + fn->has_local_explicit_reg_vars = bp_unpack_value (&bp, 1); + fn->after_tree_profile = bp_unpack_value (&bp, 1); + fn->returns_pcc_struct = bp_unpack_value (&bp, 1); + fn->returns_struct = bp_unpack_value (&bp, 1); + fn->can_throw_non_call_exceptions = bp_unpack_value (&bp, 1); + fn->always_inline_functions_inlined = bp_unpack_value (&bp, 1); + fn->after_inlining = bp_unpack_value (&bp, 1); + fn->dont_save_pending_sizes_p = bp_unpack_value (&bp, 1); + fn->stdarg = bp_unpack_value (&bp, 1); + fn->has_nonlocal_label = bp_unpack_value (&bp, 1); + fn->calls_alloca = bp_unpack_value (&bp, 1); + fn->calls_setjmp = bp_unpack_value (&bp, 1); + fn->va_list_fpr_size = bp_unpack_value (&bp, 8); + fn->va_list_gpr_size = bp_unpack_value (&bp, 8); /* Input the current IL state of the function. */ fn->curr_properties = lto_input_uleb128 (ib); @@ -1581,12 +1579,16 @@ unpack_ts_base_value_fields (struct bitpack_d *bp, tree expr) so we skip it here. */ TREE_PUBLIC (expr) = (unsigned) bp_unpack_value (bp, 1); } + else + bp_unpack_value (bp, 4); TREE_ADDRESSABLE (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_THIS_VOLATILE (expr) = (unsigned) bp_unpack_value (bp, 1); if (DECL_P (expr)) DECL_UNSIGNED (expr) = (unsigned) bp_unpack_value (bp, 1); else if (TYPE_P (expr)) TYPE_UNSIGNED (expr) = (unsigned) bp_unpack_value (bp, 1); + else + bp_unpack_value (bp, 1); TREE_ASM_WRITTEN (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_NO_WARNING (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_USED (expr) = (unsigned) bp_unpack_value (bp, 1); @@ -1597,8 +1599,10 @@ unpack_ts_base_value_fields (struct bitpack_d *bp, tree expr) TREE_DEPRECATED (expr) = (unsigned) bp_unpack_value (bp, 1); if (TYPE_P (expr)) TYPE_SATURATING (expr) = (unsigned) bp_unpack_value (bp, 1); - if (TREE_CODE (expr) == SSA_NAME) + else if (TREE_CODE (expr) == SSA_NAME) SSA_NAME_IS_DEFAULT_DEF (expr) = (unsigned) bp_unpack_value (bp, 1); + else + bp_unpack_value (bp, 1); } @@ -1858,32 +1862,6 @@ unpack_value_fields (struct bitpack_d *bp, tree expr) } -/* Read a bitpack from input block IB. */ - -struct bitpack_d * -lto_input_bitpack (struct lto_input_block *ib) -{ - unsigned i, num_words; - struct bitpack_d *bp; - - bp = bitpack_create (); - - /* If we are about to read more than a handful of words, something - is wrong. This check is overly strict, but it acts as an early - warning. No streamed object has hundreds of bits in its fields. */ - num_words = lto_input_uleb128 (ib); - gcc_assert (num_words < 20); - - for (i = 0; i < num_words; i++) - { - bitpack_word_t w = lto_input_uleb128 (ib); - VEC_safe_push (bitpack_word_t, heap, bp->values, w); - } - - return bp; -} - - /* Materialize a new tree from input block IB using descriptors in 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. */ @@ -1892,7 +1870,7 @@ static tree lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in, enum LTO_tags tag, int *ix_p) { - struct bitpack_d *bp; + struct bitpack_d bp; enum tree_code code; tree result; #ifdef LTO_STREAMER_DEBUG @@ -1957,12 +1935,11 @@ lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in, /* 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); + 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); - bitpack_delete (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 diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index e647545..6ee2eda2 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -151,20 +151,6 @@ destroy_output_block (struct output_block *ob) } -/* Output bitpack BP to output stream S. */ - -void -lto_output_bitpack (struct lto_output_stream *s, struct bitpack_d *bp) -{ - unsigned i; - bitpack_word_t v; - - lto_output_uleb128_stream (s, VEC_length (bitpack_word_t, bp->values)); - for (i = 0; VEC_iterate (bitpack_word_t, bp->values, i, v); i++) - lto_output_uleb128_stream (s, v); -} - - /* Output STRING of LEN characters to the string table in OB. The string might or might not include a trailing '\0'. Then put the index onto the INDEX_STREAM. */ @@ -335,12 +321,16 @@ pack_ts_base_value_fields (struct bitpack_d *bp, tree expr) so we skip it here. */ bp_pack_value (bp, TREE_PUBLIC (expr), 1); } + else + bp_pack_value (bp, 0, 4); bp_pack_value (bp, TREE_ADDRESSABLE (expr), 1); bp_pack_value (bp, TREE_THIS_VOLATILE (expr), 1); if (DECL_P (expr)) bp_pack_value (bp, DECL_UNSIGNED (expr), 1); else if (TYPE_P (expr)) bp_pack_value (bp, TYPE_UNSIGNED (expr), 1); + else + bp_pack_value (bp, 0, 1); /* We write debug info two times, do not confuse the second one. */ bp_pack_value (bp, TYPE_P (expr) ? 0 : TREE_ASM_WRITTEN (expr), 1); bp_pack_value (bp, TREE_NO_WARNING (expr), 1); @@ -352,8 +342,10 @@ pack_ts_base_value_fields (struct bitpack_d *bp, tree expr) bp_pack_value (bp, TREE_DEPRECATED (expr), 1); if (TYPE_P (expr)) bp_pack_value (bp, TYPE_SATURATING (expr), 1); - if (TREE_CODE (expr) == SSA_NAME) + else if (TREE_CODE (expr) == SSA_NAME) bp_pack_value (bp, SSA_NAME_IS_DEFAULT_DEF (expr), 1); + else + bp_pack_value (bp, 0, 1); } @@ -544,14 +536,12 @@ pack_ts_block_value_fields (struct bitpack_d *bp, tree expr) /* Pack all the non-pointer fields in EXPR into a bit pack. */ -static struct bitpack_d * -pack_value_fields (tree expr) +static void +pack_value_fields (struct bitpack_d *bp, tree expr) { enum tree_code code; - struct bitpack_d *bp; code = TREE_CODE (expr); - bp = bitpack_create (); /* Note that all these functions are highly sensitive to changes in the types and sizes of each of the fields being packed. */ @@ -598,8 +588,6 @@ pack_value_fields (tree expr) /* This is only used by High GIMPLE. */ gcc_unreachable (); } - - return bp; } @@ -1294,7 +1282,7 @@ lto_output_builtin_tree (struct output_block *ob, tree expr, int ix) static void lto_write_tree (struct output_block *ob, tree expr, bool ref_p, int ix) { - struct bitpack_d *bp; + struct bitpack_d bp; /* Write the header, containing everything needed to materialize EXPR on the reading side. */ @@ -1302,9 +1290,9 @@ lto_write_tree (struct output_block *ob, tree expr, bool ref_p, int ix) /* Pack all the non-pointer fields in EXPR into a bitpack and write the resulting bitpack. */ - bp = pack_value_fields (expr); - lto_output_bitpack (ob->main_stream, bp); - bitpack_delete (bp); + 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); @@ -1661,7 +1649,7 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) unsigned i; enum gimple_code code; enum LTO_tags tag; - struct bitpack_d *bp; + struct bitpack_d bp; /* Emit identifying tag. */ code = gimple_code (stmt); @@ -1669,15 +1657,14 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) output_record_start (ob, tag); /* Emit the tuple header. */ - bp = bitpack_create (); - bp_pack_value (bp, gimple_num_ops (stmt), sizeof (unsigned) * 8); - bp_pack_value (bp, gimple_no_warning_p (stmt), 1); + bp = bitpack_create (ob->main_stream); + bp_pack_value (&bp, gimple_num_ops (stmt), sizeof (unsigned) * 8); + bp_pack_value (&bp, gimple_no_warning_p (stmt), 1); if (is_gimple_assign (stmt)) - bp_pack_value (bp, gimple_assign_nontemporal_move_p (stmt), 1); - bp_pack_value (bp, gimple_has_volatile_ops (stmt), 1); - bp_pack_value (bp, stmt->gsbase.subcode, 16); - lto_output_bitpack (ob->main_stream, bp); - bitpack_delete (bp); + bp_pack_value (&bp, gimple_assign_nontemporal_move_p (stmt), 1); + bp_pack_value (&bp, gimple_has_volatile_ops (stmt), 1); + bp_pack_value (&bp, stmt->gsbase.subcode, 16); + lto_output_bitpack (&bp); /* Emit location information for the statement. */ lto_output_location (ob, gimple_location (stmt)); @@ -1848,7 +1835,7 @@ produce_asm (struct output_block *ob, tree fn) static void output_function (struct cgraph_node *node) { - struct bitpack_d *bp; + struct bitpack_d bp; tree function; struct function *fn; basic_block bb; @@ -1873,24 +1860,23 @@ output_function (struct cgraph_node *node) output_record_start (ob, LTO_function); /* Write all the attributes for FN. */ - bp = bitpack_create (); - bp_pack_value (bp, fn->is_thunk, 1); - bp_pack_value (bp, fn->has_local_explicit_reg_vars, 1); - bp_pack_value (bp, fn->after_tree_profile, 1); - bp_pack_value (bp, fn->returns_pcc_struct, 1); - bp_pack_value (bp, fn->returns_struct, 1); - bp_pack_value (bp, fn->can_throw_non_call_exceptions, 1); - bp_pack_value (bp, fn->always_inline_functions_inlined, 1); - bp_pack_value (bp, fn->after_inlining, 1); - bp_pack_value (bp, fn->dont_save_pending_sizes_p, 1); - bp_pack_value (bp, fn->stdarg, 1); - bp_pack_value (bp, fn->has_nonlocal_label, 1); - bp_pack_value (bp, fn->calls_alloca, 1); - bp_pack_value (bp, fn->calls_setjmp, 1); - bp_pack_value (bp, fn->va_list_fpr_size, 8); - bp_pack_value (bp, fn->va_list_gpr_size, 8); - lto_output_bitpack (ob->main_stream, bp); - bitpack_delete (bp); + bp = bitpack_create (ob->main_stream); + bp_pack_value (&bp, fn->is_thunk, 1); + bp_pack_value (&bp, fn->has_local_explicit_reg_vars, 1); + bp_pack_value (&bp, fn->after_tree_profile, 1); + bp_pack_value (&bp, fn->returns_pcc_struct, 1); + bp_pack_value (&bp, fn->returns_struct, 1); + bp_pack_value (&bp, fn->can_throw_non_call_exceptions, 1); + bp_pack_value (&bp, fn->always_inline_functions_inlined, 1); + bp_pack_value (&bp, fn->after_inlining, 1); + bp_pack_value (&bp, fn->dont_save_pending_sizes_p, 1); + bp_pack_value (&bp, fn->stdarg, 1); + bp_pack_value (&bp, fn->has_nonlocal_label, 1); + bp_pack_value (&bp, fn->calls_alloca, 1); + bp_pack_value (&bp, fn->calls_setjmp, 1); + bp_pack_value (&bp, fn->va_list_fpr_size, 8); + bp_pack_value (&bp, fn->va_list_gpr_size, 8); + lto_output_bitpack (&bp); /* Output current IL state of the function. */ output_uleb128 (ob, fn->curr_properties); diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c index 216bc95..4060960 100644 --- a/gcc/lto-streamer.c +++ b/gcc/lto-streamer.c @@ -266,147 +266,6 @@ print_lto_report (void) lto_section_name[i], lto_stats.section_size[i]); } -/* We cache a single bitpack assuming that usually at most one is - life. This saves repeated re-allocations. */ -static struct bitpack_d *cached_bp; - -/* Create a new bitpack. */ - -struct bitpack_d * -bitpack_create (void) -{ - if (cached_bp) - { - struct bitpack_d *bp = cached_bp; - cached_bp = NULL; - return bp; - } - return XCNEW (struct bitpack_d); -} - - -/* Free the memory used by bitpack BP. */ - -void -bitpack_delete (struct bitpack_d *bp) -{ - if (!cached_bp) - { - bp->num_bits = 0; - bp->first_unused_bit = 0; - VEC_truncate (bitpack_word_t, bp->values, 0); - cached_bp = bp; - return; - } - VEC_free (bitpack_word_t, heap, bp->values); - free (bp); -} - - -/* Return an index to the word in bitpack BP that contains the - next NBITS. */ - -static inline unsigned -bp_get_next_word (struct bitpack_d *bp, unsigned nbits) -{ - unsigned last, ix; - - /* In principle, the next word to use is determined by the - number of bits already processed in BP. */ - ix = bp->num_bits / BITS_PER_BITPACK_WORD; - - /* All the encoded bit patterns in BP are contiguous, therefore if - the next NBITS would straddle over two different words, move the - index to the next word and update the number of encoded bits - by adding up the hole of unused bits created by this move. */ - bp->first_unused_bit %= BITS_PER_BITPACK_WORD; - last = bp->first_unused_bit + nbits - 1; - if (last >= BITS_PER_BITPACK_WORD) - { - ix++; - bp->num_bits += (BITS_PER_BITPACK_WORD - bp->first_unused_bit); - bp->first_unused_bit = 0; - } - - return ix; -} - - -/* Pack NBITS of value VAL into bitpack BP. */ - -void -bp_pack_value (struct bitpack_d *bp, bitpack_word_t val, unsigned nbits) -{ - unsigned ix; - bitpack_word_t word; - - /* We cannot encode more bits than BITS_PER_BITPACK_WORD. */ -#ifdef ENABLE_CHECKING - gcc_assert (nbits > 0 && nbits <= BITS_PER_BITPACK_WORD); -#endif - - /* Compute which word will contain the next NBITS. */ - ix = bp_get_next_word (bp, nbits); - if (ix >= VEC_length (bitpack_word_t, bp->values)) - { - /* If there is no room left in the last word of the values - array, add a new word. Additionally, we should only - need to add a single word, since every pack operation cannot - use more bits than fit in a single word. */ - VEC_safe_push (bitpack_word_t, heap, bp->values, 0); - } - - /* Grab the last word to pack VAL into. */ - word = VEC_index (bitpack_word_t, bp->values, ix); - - /* To fit VAL in WORD, we need to shift VAL to the left to - skip the bottom BP->FIRST_UNUSED_BIT bits. */ - val <<= bp->first_unused_bit; - - /* Update WORD with VAL. */ - word |= val; - - /* Update BP. */ - VEC_replace (bitpack_word_t, bp->values, ix, word); - bp->num_bits += nbits; - bp->first_unused_bit += nbits; -} - - -/* Unpack the next NBITS from bitpack BP. */ - -bitpack_word_t -bp_unpack_value (struct bitpack_d *bp, unsigned nbits) -{ - bitpack_word_t val, word, mask; - unsigned ix; - - /* We cannot decode more bits than BITS_PER_BITPACK_WORD. */ - gcc_checking_assert (nbits > 0 && nbits <= BITS_PER_BITPACK_WORD); - - /* Compute which word contains the next NBITS. */ - ix = bp_get_next_word (bp, nbits); - word = VEC_index (bitpack_word_t, bp->values, ix); - - /* Compute the mask to get NBITS from WORD. */ - mask = (nbits == BITS_PER_BITPACK_WORD) - ? (bitpack_word_t) -1 - : ((bitpack_word_t) 1 << nbits) - 1; - - /* Shift WORD to the right to skip over the bits already decoded - in word. */ - word >>= bp->first_unused_bit; - - /* Apply the mask to obtain the requested value. */ - val = word & mask; - - /* Update BP->NUM_BITS for the next unpack operation. */ - bp->num_bits += nbits; - bp->first_unused_bit += nbits; - - return val; -} - /* Check that all the TS_* structures handled by the lto_output_* and lto_input_* routines are exactly ALL the structures defined in diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 8ff5bf5..cc38b22 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -156,17 +156,14 @@ DEF_VEC_ALLOC_I(bitpack_word_t, heap); struct bitpack_d { - /* Total number of bits packed/unpacked so far. */ - size_t num_bits; + /* The position of the first unused or unconsumed bit in the word. */ + unsigned pos; - /* Values are stored contiguously, so there may be internal - fragmentation (words with unused bits). Therefore, we need to - keep track of the first available bit in the last word of the - bitpack. */ - size_t first_unused_bit; + /* The current word we are (un)packing. */ + bitpack_word_t word; - /* Vector of words holding the packed values. */ - VEC(bitpack_word_t, heap) *values; + /* The lto_output_stream or the lto_input_block we are streaming to/from. */ + void *stream; }; /* Tags representing the various IL objects written to the bytecode file @@ -820,10 +817,6 @@ extern bitmap lto_bitmap_alloc (void); extern void lto_bitmap_free (bitmap); extern char *lto_get_section_name (int, const char *); extern void print_lto_report (void); -extern struct bitpack_d *bitpack_create (void); -extern void bitpack_delete (struct bitpack_d *); -extern void bp_pack_value (struct bitpack_d *, bitpack_word_t, unsigned); -extern bitpack_word_t bp_unpack_value (struct bitpack_d *, unsigned); extern bool lto_streamer_cache_insert (struct lto_streamer_cache_d *, tree, int *, unsigned *); extern bool lto_streamer_cache_insert_at (struct lto_streamer_cache_d *, tree, @@ -851,7 +844,6 @@ extern void lto_input_function_body (struct lto_file_decl_data *, tree, const char *); extern void lto_input_constructors_and_inits (struct lto_file_decl_data *, const char *); -extern struct bitpack_d *lto_input_bitpack (struct lto_input_block *); extern void lto_init_reader (void); extern struct data_in *lto_data_in_create (struct lto_file_decl_data *, const char *, unsigned, @@ -864,7 +856,6 @@ extern void lto_register_decl_definition (tree, struct lto_file_decl_data *); extern struct output_block *create_output_block (enum lto_section_type); extern void destroy_output_block (struct output_block *); extern void lto_output_tree (struct output_block *, tree, bool); -extern void lto_output_bitpack (struct lto_output_stream *, struct bitpack_d *); extern void produce_asm (struct output_block *ob, tree fn); @@ -1077,4 +1068,85 @@ DEFINE_DECL_STREAM_FUNCS (TYPE_DECL, type_decl) DEFINE_DECL_STREAM_FUNCS (NAMESPACE_DECL, namespace_decl) DEFINE_DECL_STREAM_FUNCS (LABEL_DECL, label_decl) +/* Returns a new bit-packing context for bit-packing into S. */ +static inline struct bitpack_d +bitpack_create (struct lto_output_stream *s) +{ + struct bitpack_d bp; + bp.pos = 0; + bp.word = 0; + bp.stream = (void *)s; + return bp; +} + +/* Pack the NBITS bit sized value VAL into the bit-packing context BP. */ +static inline void +bp_pack_value (struct bitpack_d *bp, bitpack_word_t val, unsigned nbits) +{ + bitpack_word_t word = bp->word; + int pos = bp->pos; + /* If val does not fit into the current bitpack word switch to the + next one. */ + if (pos + nbits > BITS_PER_BITPACK_WORD) + { + lto_output_uleb128_stream ((struct lto_output_stream *) bp->stream, word); + word = val; + pos = nbits; + } + else + { + word |= val << pos; + pos += nbits; + } + bp->word = word; + bp->pos = pos; +} + +/* Finishes bit-packing of BP. */ +static inline void +lto_output_bitpack (struct bitpack_d *bp) +{ + lto_output_uleb128_stream ((struct lto_output_stream *) bp->stream, + bp->word); + bp->word = 0; + bp->pos = 0; +} + +/* Returns a new bit-packing context for bit-unpacking from IB. */ +static inline struct bitpack_d +lto_input_bitpack (struct lto_input_block *ib) +{ + struct bitpack_d bp; + bp.word = lto_input_uleb128 (ib); + bp.pos = 0; + bp.stream = (void *)ib; + return bp; +} + +/* Unpacks NBITS bits from the bit-packing context BP and returns them. */ +static inline bitpack_word_t +bp_unpack_value (struct bitpack_d *bp, unsigned nbits) +{ + bitpack_word_t mask, val; + int pos = bp->pos; + + mask = (nbits == BITS_PER_BITPACK_WORD + ? (bitpack_word_t) -1 + : ((bitpack_word_t) 1 << nbits) - 1); + + /* If there are not continuous nbits in the current bitpack word + switch to the next one. */ + if (pos + nbits > BITS_PER_BITPACK_WORD) + { + bp->word = val = lto_input_uleb128 ((struct lto_input_block *)bp->stream); + bp->pos = nbits; + return val & mask; + } + val = bp->word; + val >>= pos; + bp->pos = pos + nbits; + + return val & mask; +} + #endif /* GCC_LTO_STREAMER_H */ |