[PATCH][RFC] bitpacking rewrite
Richard Guenther
rguenther@suse.de
Sat Jun 12 13:04:00 GMT 2010
The following preliminary patch rewrites bitpacking to happen
word-by-word and on the stack (well, in the preliminary form
only on the stack after inlining).
Comments?
Richard.
Index: gcc/lto-cgraph.c
===================================================================
*** gcc/lto-cgraph.c (revision 160657)
--- gcc/lto-cgraph.c (working copy)
*************** lto_output_edge (struct lto_simple_outpu
*** 260,266 ****
{
unsigned int uid;
intptr_t ref;
! struct bitpack_d *bp;
if (edge->indirect_unknown_callee)
lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_indirect_edge);
--- 260,266 ----
{
unsigned int uid;
intptr_t ref;
! struct bitpack_d *bp, bp_s;
if (edge->indirect_unknown_callee)
lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_indirect_edge);
*************** lto_output_edge (struct lto_simple_outpu
*** 280,286 ****
lto_output_sleb128_stream (ob->main_stream, edge->count);
! bp = bitpack_create ();
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);
--- 280,287 ----
lto_output_sleb128_stream (ob->main_stream, edge->count);
! bp_s = bitpack_create (ob->main_stream);
! bp = &bp_s;
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);
*************** lto_output_edge (struct lto_simple_outpu
*** 304,310 ****
| ECF_SIBCALL
| ECF_NOVOPS)));
}
! lto_output_bitpack (ob->main_stream, bp);
bitpack_delete (bp);
}
--- 305,311 ----
| ECF_SIBCALL
| ECF_NOVOPS)));
}
! lto_output_bitpack (bp);
bitpack_delete (bp);
}
*************** lto_output_node (struct lto_simple_outpu
*** 404,410 ****
varpool_node_set vset)
{
unsigned int tag;
! struct bitpack_d *bp;
bool boundary_p;
intptr_t ref;
bool in_other_partition = false;
--- 405,411 ----
varpool_node_set vset)
{
unsigned int tag;
! struct bitpack_d *bp, bp_s;
bool boundary_p;
intptr_t ref;
bool in_other_partition = false;
*************** lto_output_node (struct lto_simple_outpu
*** 458,464 ****
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);
--- 459,466 ----
lto_output_fn_decl_index (ob->decl_state, ob->main_stream, node->decl);
lto_output_sleb128_stream (ob->main_stream, node->count);
! bp_s = bitpack_create (ob->main_stream);
! bp = &bp_s;
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);
*************** lto_output_node (struct lto_simple_outpu
*** 479,485 ****
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)
--- 481,487 ----
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);
bitpack_delete (bp);
if (tag == LTO_cgraph_analyzed_node)
*************** lto_output_varpool_node (struct lto_simp
*** 561,573 ****
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 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);
--- 563,576 ----
cgraph_node_set set, varpool_node_set vset)
{
bool boundary_p = !varpool_node_in_set_p (node, vset) && node->analyzed;
! struct bitpack_d *bp, bp_s;
struct varpool_node *alias;
int count = 0;
int ref;
lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->decl);
! bp_s = bitpack_create (ob->main_stream);
! bp = &bp_s;
bp_pack_value (bp, node->externally_visible, 1);
bp_pack_value (bp, node->force_output, 1);
bp_pack_value (bp, node->finalized, 1);
*************** lto_output_varpool_node (struct lto_simp
*** 594,600 ****
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);
if (node->same_comdat_group && !boundary_p)
{
--- 597,603 ----
for (alias = node->extra_name; alias; alias = alias->next)
count++;
bp_pack_value (bp, count != 0, 1);
! lto_output_bitpack (bp);
bitpack_delete (bp);
if (node->same_comdat_group && !boundary_p)
{
*************** lto_output_ref (struct lto_simple_output
*** 621,630 ****
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);
if (ref->refered_type == IPA_REF_CGRAPH)
{
--- 624,635 ----
lto_cgraph_encoder_t encoder,
lto_varpool_encoder_t varpool_encoder)
{
! struct bitpack_d *bp, bp_s;
! bp_s = bitpack_create (ob->main_stream);
! bp = &bp_s;
bp_pack_value (bp, ref->refered_type, 1);
bp_pack_value (bp, ref->use, 2);
! lto_output_bitpack (bp);
bitpack_delete (bp);
if (ref->refered_type == IPA_REF_CGRAPH)
{
*************** input_node (struct lto_file_decl_data *f
*** 981,987 ****
{
tree fn_decl;
struct cgraph_node *node;
! struct bitpack_d *bp;
int stack_size = 0;
unsigned decl_index;
int ref = LCC_NOT_FOUND, ref2 = LCC_NOT_FOUND;
--- 986,992 ----
{
tree fn_decl;
struct cgraph_node *node;
! struct bitpack_d *bp, bp_s;
int stack_size = 0;
unsigned decl_index;
int ref = LCC_NOT_FOUND, ref2 = LCC_NOT_FOUND;
*************** input_node (struct lto_file_decl_data *f
*** 1006,1012 ****
node = cgraph_node (fn_decl);
node->count = lto_input_sleb128 (ib);
! bp = lto_input_bitpack (ib);
if (tag == LTO_cgraph_analyzed_node)
{
--- 1011,1018 ----
node = cgraph_node (fn_decl);
node->count = lto_input_sleb128 (ib);
! bp_s = lto_input_bitpack (ib);
! bp = &bp_s;
if (tag == LTO_cgraph_analyzed_node)
{
*************** input_varpool_node (struct lto_file_decl
*** 1081,1087 ****
int decl_index;
tree var_decl;
struct varpool_node *node;
! struct bitpack_d *bp;
bool aliases_p;
int count;
int ref = LCC_NOT_FOUND;
--- 1087,1093 ----
int decl_index;
tree var_decl;
struct varpool_node *node;
! struct bitpack_d *bp, bp_s;
bool aliases_p;
int count;
int ref = LCC_NOT_FOUND;
*************** input_varpool_node (struct lto_file_decl
*** 1091,1097 ****
node = varpool_node (var_decl);
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);
--- 1097,1104 ----
node = varpool_node (var_decl);
node->lto_file_data = file_data;
! bp_s = lto_input_bitpack (ib);
! bp = &bp_s;
node->externally_visible = bp_unpack_value (bp, 1);
node->force_output = bp_unpack_value (bp, 1);
node->finalized = bp_unpack_value (bp, 1);
*************** input_ref (struct lto_input_block *ib,
*** 1131,1141 ****
{
struct cgraph_node *node = NULL;
struct varpool_node *varpool_node = NULL;
! 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);
--- 1138,1149 ----
{
struct cgraph_node *node = NULL;
struct varpool_node *varpool_node = NULL;
! struct bitpack_d *bp, bp_s;
enum ipa_ref_type type;
enum ipa_ref_use use;
! bp_s = lto_input_bitpack (ib);
! bp = &bp_s;
type = (enum ipa_ref_type) bp_unpack_value (bp, 1);
use = (enum ipa_ref_use) bp_unpack_value (bp, 2);
bitpack_delete (bp);
*************** input_edge (struct lto_input_block *ib,
*** 1163,1169 ****
int freq;
unsigned int nest;
cgraph_inline_failed_t inline_failed;
! struct bitpack_d *bp;
enum ld_plugin_symbol_resolution caller_resolution;
int ecf_flags = 0;
--- 1171,1177 ----
int freq;
unsigned int nest;
cgraph_inline_failed_t inline_failed;
! struct bitpack_d *bp, bp_s;
enum ld_plugin_symbol_resolution caller_resolution;
int ecf_flags = 0;
*************** input_edge (struct lto_input_block *ib,
*** 1182,1188 ****
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,
HOST_BITS_PER_INT);
--- 1190,1197 ----
count = (gcov_type) lto_input_sleb128 (ib);
! bp_s = lto_input_bitpack (ib);
! bp = &bp_s;
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);
*************** output_node_opt_summary (struct output_b
*** 1470,1476 ****
unsigned int index;
bitmap_iterator bi;
struct ipa_replace_map *map;
! struct bitpack_d *bp;
int i;
lto_output_uleb128_stream (ob->main_stream,
--- 1479,1485 ----
unsigned int index;
bitmap_iterator bi;
struct ipa_replace_map *map;
! struct bitpack_d *bp, bp_s;
int i;
lto_output_uleb128_stream (ob->main_stream,
*************** output_node_opt_summary (struct output_b
*** 1497,1506 ****
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);
}
}
--- 1506,1516 ----
gcc_assert (parm);
lto_output_uleb128_stream (ob->main_stream, parm_num);
lto_output_tree (ob, map->new_tree, true);
! bp_s = bitpack_create (ob->main_stream);
! bp = &bp_s;
bp_pack_value (bp, map->replace_p, 1);
bp_pack_value (bp, map->ref_p, 1);
! lto_output_bitpack (bp);
bitpack_delete (bp);
}
}
*************** input_node_opt_summary (struct cgraph_no
*** 1547,1553 ****
int i;
int count;
int bit;
! struct bitpack_d *bp;
count = lto_input_uleb128 (ib_main);
if (count)
--- 1557,1563 ----
int i;
int count;
int bit;
! struct bitpack_d *bp, bp_s;
count = lto_input_uleb128 (ib_main);
if (count)
*************** input_node_opt_summary (struct cgraph_no
*** 1579,1585 ****
map->parm_num = lto_input_uleb128 (ib_main);
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);
--- 1589,1596 ----
map->parm_num = lto_input_uleb128 (ib_main);
map->old_tree = NULL;
map->new_tree = lto_input_tree (ib_main, data_in);
! bp_s = lto_input_bitpack (ib_main);
! bp = &bp_s;
map->replace_p = bp_unpack_value (bp, 1);
map->ref_p = bp_unpack_value (bp, 1);
bitpack_delete (bp);
Index: gcc/ipa-pure-const.c
===================================================================
*** gcc/ipa-pure-const.c (revision 160657)
--- gcc/ipa-pure-const.c (working copy)
*************** pure_const_write_summary (cgraph_node_se
*** 943,949 ****
node = csi_node (csi);
if (node->analyzed && has_function_state (node))
{
! struct bitpack_d *bp;
funct_state fs;
int node_ref;
lto_cgraph_encoder_t encoder;
--- 943,949 ----
node = csi_node (csi);
if (node->analyzed && has_function_state (node))
{
! struct bitpack_d *bp, bp_s;
funct_state fs;
int node_ref;
lto_cgraph_encoder_t encoder;
*************** pure_const_write_summary (cgraph_node_se
*** 956,968 ****
/* 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);
}
}
--- 956,969 ----
/* Note that flags will need to be read in the opposite
order as we are pushing the bitflags into FLAGS. */
! bp_s = bitpack_create (ob->main_stream);
! bp = &bp_s;
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);
bitpack_delete (bp);
}
}
*************** pure_const_read_summary (void)
*** 998,1004 ****
{
unsigned int index;
struct cgraph_node *node;
! struct bitpack_d *bp;
funct_state fs;
lto_cgraph_encoder_t encoder;
--- 999,1005 ----
{
unsigned int index;
struct cgraph_node *node;
! struct bitpack_d *bp, bp_s;
funct_state fs;
lto_cgraph_encoder_t encoder;
*************** pure_const_read_summary (void)
*** 1011,1017 ****
/* Note that the flags must be read in the opposite
order in which they were written (the bitflags were
pushed into FLAGS). */
! bp = lto_input_bitpack (ib);
fs->pure_const_state
= (enum pure_const_state_e) bp_unpack_value (bp, 2);
fs->state_previously_known
--- 1012,1019 ----
/* Note that the flags must be read in the opposite
order in which they were written (the bitflags were
pushed into FLAGS). */
! bp_s = lto_input_bitpack (ib);
! bp = &bp_s;
fs->pure_const_state
= (enum pure_const_state_e) bp_unpack_value (bp, 2);
fs->state_previously_known
Index: gcc/lto-streamer-out.c
===================================================================
*** gcc/lto-streamer-out.c (revision 160657)
--- gcc/lto-streamer-out.c (working copy)
*************** destroy_output_block (struct output_bloc
*** 151,170 ****
}
- /* 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. */
--- 151,156 ----
*************** pack_ts_block_value_fields (struct bitpa
*** 544,557 ****
/* Pack all the non-pointer fields in EXPR into a bit pack. */
! static struct bitpack_d *
! pack_value_fields (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. */
--- 530,541 ----
/* Pack all the non-pointer fields in EXPR into a bit pack. */
! static void
! pack_value_fields (struct bitpack_d *bp, tree expr)
{
enum tree_code code;
code = TREE_CODE (expr);
/* Note that all these functions are highly sensitive to changes in
the types and sizes of each of the fields being packed. */
*************** pack_value_fields (tree expr)
*** 598,605 ****
/* This is only used by High GIMPLE. */
gcc_unreachable ();
}
-
- return bp;
}
--- 582,587 ----
*************** lto_output_builtin_tree (struct output_b
*** 1293,1299 ****
static void
lto_write_tree (struct output_block *ob, tree expr, bool ref_p, int ix)
{
! struct bitpack_d *bp;
/* Write the header, containing everything needed to materialize
EXPR on the reading side. */
--- 1275,1281 ----
static void
lto_write_tree (struct output_block *ob, tree expr, bool ref_p, int ix)
{
! struct bitpack_d bp;
/* Write the header, containing everything needed to materialize
EXPR on the reading side. */
*************** lto_write_tree (struct output_block *ob,
*** 1301,1309 ****
/* 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);
/* Write all the pointer fields in EXPR. */
lto_output_tree_pointers (ob, expr, ref_p);
--- 1283,1292 ----
/* 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);
! bitpack_delete (&bp);
/* Write all the pointer fields in EXPR. */
lto_output_tree_pointers (ob, expr, ref_p);
*************** output_gimple_stmt (struct output_block
*** 1660,1666 ****
unsigned i;
enum gimple_code code;
enum LTO_tags tag;
! struct bitpack_d *bp;
/* Emit identifying tag. */
code = gimple_code (stmt);
--- 1643,1649 ----
unsigned i;
enum gimple_code code;
enum LTO_tags tag;
! struct bitpack_d *bp, bp_s;
/* Emit identifying tag. */
code = gimple_code (stmt);
*************** output_gimple_stmt (struct output_block
*** 1668,1681 ****
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);
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);
/* Emit location information for the statement. */
--- 1651,1665 ----
output_record_start (ob, tag);
/* Emit the tuple header. */
! bp_s = bitpack_create (ob->main_stream);
! bp = &bp_s;
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 (bp);
bitpack_delete (bp);
/* Emit location information for the statement. */
*************** produce_asm (struct output_block *ob, tr
*** 1847,1853 ****
static void
output_function (struct cgraph_node *node)
{
! struct bitpack_d *bp;
tree function;
struct function *fn;
basic_block bb;
--- 1831,1837 ----
static void
output_function (struct cgraph_node *node)
{
! struct bitpack_d *bp, bp_s;
tree function;
struct function *fn;
basic_block bb;
*************** output_function (struct cgraph_node *nod
*** 1872,1878 ****
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);
--- 1856,1863 ----
output_record_start (ob, LTO_function);
/* Write all the attributes for FN. */
! bp_s = bitpack_create (ob->main_stream);
! bp = &bp_s;
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);
*************** output_function (struct cgraph_node *nod
*** 1888,1894 ****
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);
/* Output current IL state of the function. */
--- 1873,1879 ----
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);
bitpack_delete (bp);
/* Output current IL state of the function. */
Index: gcc/lto-streamer-in.c
===================================================================
*** gcc/lto-streamer-in.c (revision 160657)
--- gcc/lto-streamer-in.c (working copy)
*************** input_gimple_stmt (struct lto_input_bloc
*** 1001,1012 ****
enum gimple_code code;
unsigned HOST_WIDE_INT num_ops;
size_t i;
! 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);
stmt = gimple_alloc (code, num_ops);
stmt->gsbase.no_warning = bp_unpack_value (bp, 1);
--- 1001,1013 ----
enum gimple_code code;
unsigned HOST_WIDE_INT num_ops;
size_t i;
! struct bitpack_d *bp, bp_s;
code = lto_tag_to_gimple_code (tag);
/* Read the tuple header. */
! bp_s = lto_input_bitpack (ib);
! bp = &bp_s;
num_ops = bp_unpack_value (bp, sizeof (unsigned) * 8);
stmt = gimple_alloc (code, num_ops);
stmt->gsbase.no_warning = bp_unpack_value (bp, 1);
*************** input_function (tree fn_decl, struct dat
*** 1291,1297 ****
enum LTO_tags tag;
gimple *stmts;
basic_block bb;
! struct bitpack_d *bp;
struct cgraph_node *node;
tree args, narg, oarg;
--- 1292,1298 ----
enum LTO_tags tag;
gimple *stmts;
basic_block bb;
! struct bitpack_d *bp, bp_s;
struct cgraph_node *node;
tree args, narg, oarg;
*************** input_function (tree fn_decl, struct dat
*** 1303,1309 ****
lto_tag_check (tag, LTO_function);
/* 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);
--- 1304,1311 ----
lto_tag_check (tag, LTO_function);
/* Read all the attributes for FN. */
! bp_s = lto_input_bitpack (ib);
! bp = &bp_s;
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);
*************** unpack_value_fields (struct bitpack_d *b
*** 1858,1889 ****
}
- /* 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. */
--- 1860,1865 ----
*************** static tree
*** 1892,1898 ****
lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
enum LTO_tags tag, int *ix_p)
{
! struct bitpack_d *bp;
enum tree_code code;
tree result;
#ifdef LTO_STREAMER_DEBUG
--- 1868,1874 ----
lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
enum LTO_tags tag, int *ix_p)
{
! struct bitpack_d *bp, bp_s;
enum tree_code code;
tree result;
#ifdef LTO_STREAMER_DEBUG
*************** lto_materialize_tree (struct lto_input_b
*** 1953,1959 ****
#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. */
--- 1929,1936 ----
#endif
/* Read the bitpack of non-pointer values from IB. */
! bp_s = lto_input_bitpack (ib);
! bp = &bp_s;
/* The first word in BP contains the code of the tree that we
are about to read. */
Index: gcc/ipa-prop.c
===================================================================
*** gcc/ipa-prop.c (revision 160657)
--- gcc/ipa-prop.c (working copy)
*************** ipa_write_indirect_edge_info (struct out
*** 2403,2416 ****
struct cgraph_edge *cs)
{
struct cgraph_indirect_call_info *ii = cs->indirect_info;
! 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);
if (ii->polymorphic)
{
--- 2403,2416 ----
struct cgraph_edge *cs)
{
struct cgraph_indirect_call_info *ii = cs->indirect_info;
! 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 (ob->main_stream);
! bp_pack_value (&bp, ii->polymorphic, 1);
! lto_output_bitpack (&bp);
! bitpack_delete (&bp);
if (ii->polymorphic)
{
*************** ipa_read_indirect_edge_info (struct lto_
*** 2428,2440 ****
struct cgraph_edge *cs)
{
struct cgraph_indirect_call_info *ii = cs->indirect_info;
! 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);
if (ii->polymorphic)
{
ii->otr_token = (HOST_WIDE_INT) lto_input_sleb128 (ib);
--- 2428,2440 ----
struct cgraph_edge *cs)
{
struct cgraph_indirect_call_info *ii = cs->indirect_info;
! 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);
if (ii->polymorphic)
{
ii->otr_token = (HOST_WIDE_INT) lto_input_sleb128 (ib);
*************** ipa_write_node_info (struct output_block
*** 2452,2477 ****
struct ipa_node_params *info = IPA_NODE_REF (node);
int j;
struct cgraph_edge *e;
! 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);
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);
}
! lto_output_bitpack (ob->main_stream, bp);
! bitpack_delete (bp);
for (e = node->callees; e; e = e->next_callee)
{
struct ipa_edge_args *args = IPA_EDGE_REF (e);
--- 2452,2477 ----
struct ipa_node_params *info = IPA_NODE_REF (node);
int j;
struct cgraph_edge *e;
! 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 (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);
}
! lto_output_bitpack (&bp);
! bitpack_delete (&bp);
for (e = node->callees; e; e = e->next_callee)
{
struct ipa_edge_args *args = IPA_EDGE_REF (e);
*************** ipa_read_node_info (struct lto_input_blo
*** 2494,2506 ****
struct ipa_node_params *info = IPA_NODE_REF (node);
int k;
struct cgraph_edge *e;
! 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);
if (ipa_get_param_count (info) != 0)
{
info->modification_analysis_done = true;
--- 2494,2506 ----
struct ipa_node_params *info = IPA_NODE_REF (node);
int k;
struct cgraph_edge *e;
! 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);
if (ipa_get_param_count (info) != 0)
{
info->modification_analysis_done = true;
*************** ipa_read_node_info (struct lto_input_blo
*** 2509,2518 ****
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);
}
! bitpack_delete (bp);
for (e = node->callees; e; e = e->next_callee)
{
struct ipa_edge_args *args = IPA_EDGE_REF (e);
--- 2509,2518 ----
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);
}
! bitpack_delete (&bp);
for (e = node->callees; e; e = e->next_callee)
{
struct ipa_edge_args *args = IPA_EDGE_REF (e);
Index: gcc/Makefile.in
===================================================================
*** gcc/Makefile.in (revision 160657)
--- gcc/Makefile.in (working copy)
*************** ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SY
*** 2995,3001 ****
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
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)
--- 2995,3001 ----
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 $(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)
Index: gcc/lto-streamer.c
===================================================================
*** gcc/lto-streamer.c (revision 160657)
--- gcc/lto-streamer.c (working copy)
*************** print_lto_report (void)
*** 266,412 ****
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_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
--- 266,271 ----
Index: gcc/lto-streamer.h
===================================================================
*** gcc/lto-streamer.h (revision 160657)
--- gcc/lto-streamer.h (working copy)
*************** DEF_VEC_ALLOC_I(bitpack_word_t, heap);
*** 156,172 ****
struct bitpack_d
{
! /* Total number of bits packed/unpacked so far. */
! size_t num_bits;
! /* 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;
! /* Vector of words holding the packed values. */
! VEC(bitpack_word_t, heap) *values;
};
/* Tags representing the various IL objects written to the bytecode file
--- 156,169 ----
struct bitpack_d
{
! /* The position of the first unused or unconsumed bit in the word. */
! unsigned pos;
! /* The current word we are (un)packing. */
! bitpack_word_t word;
! /* 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
*************** extern bitmap lto_bitmap_alloc (void);
*** 820,829 ****
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,
--- 817,822 ----
*************** extern void lto_input_function_body (str
*** 851,857 ****
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,
--- 844,849 ----
*************** extern void lto_register_decl_definition
*** 864,870 ****
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);
--- 856,861 ----
*************** DEFINE_DECL_STREAM_FUNCS (TYPE_DECL, typ
*** 1077,1080 ****
--- 1068,1150 ----
DEFINE_DECL_STREAM_FUNCS (NAMESPACE_DECL, namespace_decl)
DEFINE_DECL_STREAM_FUNCS (LABEL_DECL, label_decl)
+ 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;
+ }
+
+ 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;
+ }
+
+ static inline void
+ lto_output_bitpack (struct bitpack_d *bp)
+ {
+ lto_output_uleb128_stream ((struct lto_output_stream *) bp->stream,
+ bp->word);
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ static inline void
+ bitpack_delete (struct bitpack_d *bp ATTRIBUTE_UNUSED)
+ {
+ }
+
#endif /* GCC_LTO_STREAMER_H */
More information about the Gcc-patches
mailing list