diff --git a/gcc/lto-streamer-in.cc b/gcc/lto-streamer-in.cc index 6e8bc9516a6..1876e1967ec 100644 --- a/gcc/lto-streamer-in.cc +++ b/gcc/lto-streamer-in.cc @@ -1985,8 +1985,6 @@ lto_input_mode_table (struct lto_file_decl_data *file_data) internal_error ("cannot read LTO mode table from %s", file_data->file_name); - unsigned char *table = ggc_cleared_vec_alloc (1 << 8); - file_data->mode_table = table; const struct lto_simple_header_with_strings *header = (const struct lto_simple_header_with_strings *) data; int string_offset; @@ -1998,16 +1996,22 @@ lto_input_mode_table (struct lto_file_decl_data *file_data) header->string_size, vNULL); bitpack_d bp = streamer_read_bitpack (&ib); + unsigned mode_bits = bp_unpack_value (&bp, 5); + unsigned char *table = ggc_cleared_vec_alloc (1 << mode_bits); + + file_data->mode_table = table; + file_data->mode_bits = mode_bits; + table[VOIDmode] = VOIDmode; table[BLKmode] = BLKmode; unsigned int m; - while ((m = bp_unpack_value (&bp, 8)) != VOIDmode) + while ((m = bp_unpack_value (&bp, mode_bits)) != VOIDmode) { enum mode_class mclass = bp_unpack_enum (&bp, mode_class, MAX_MODE_CLASS); poly_uint16 size = bp_unpack_poly_value (&bp, 16); poly_uint16 prec = bp_unpack_poly_value (&bp, 16); - machine_mode inner = (machine_mode) bp_unpack_value (&bp, 8); + machine_mode inner = (machine_mode) bp_unpack_value (&bp, mode_bits); poly_uint16 nunits = bp_unpack_poly_value (&bp, 16); unsigned int ibit = 0, fbit = 0; unsigned int real_fmt_len = 0; diff --git a/gcc/lto-streamer-out.cc b/gcc/lto-streamer-out.cc index 3432dd434e2..5ffa8954022 100644 --- a/gcc/lto-streamer-out.cc +++ b/gcc/lto-streamer-out.cc @@ -3196,6 +3196,11 @@ lto_write_mode_table (void) if (inner_m != m) streamer_mode_table[(int) inner_m] = 1; } + + /* Pack the mode_bits value within 5 bits (up to 31) in the beginning. */ + unsigned mode_bits = ceil_log2 (MAX_MACHINE_MODE); + bp_pack_value (&bp, mode_bits, 5); + /* First stream modes that have GET_MODE_INNER (m) == m, so that we can refer to them afterwards. */ for (int pass = 0; pass < 2; pass++) @@ -3205,11 +3210,11 @@ lto_write_mode_table (void) machine_mode m = (machine_mode) i; if ((GET_MODE_INNER (m) == m) ^ (pass == 0)) continue; - bp_pack_value (&bp, m, 8); + bp_pack_value (&bp, m, mode_bits); bp_pack_enum (&bp, mode_class, MAX_MODE_CLASS, GET_MODE_CLASS (m)); bp_pack_poly_value (&bp, GET_MODE_SIZE (m), 16); bp_pack_poly_value (&bp, GET_MODE_PRECISION (m), 16); - bp_pack_value (&bp, GET_MODE_INNER (m), 8); + bp_pack_value (&bp, GET_MODE_INNER (m), mode_bits); bp_pack_poly_value (&bp, GET_MODE_NUNITS (m), 16); switch (GET_MODE_CLASS (m)) { @@ -3229,7 +3234,7 @@ lto_write_mode_table (void) } bp_pack_string (ob, &bp, GET_MODE_NAME (m), true); } - bp_pack_value (&bp, VOIDmode, 8); + bp_pack_value (&bp, VOIDmode, mode_bits); streamer_write_bitpack (&bp); diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 2913b808bde..0556b34c837 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -604,6 +604,8 @@ struct GTY(()) lto_file_decl_data int order_base; int unit_base; + + unsigned mode_bits; }; typedef struct lto_file_decl_data *lto_file_decl_data_ptr; diff --git a/gcc/lto/lto-common.cc b/gcc/lto/lto-common.cc index cdb37c86b46..703e665b698 100644 --- a/gcc/lto/lto-common.cc +++ b/gcc/lto/lto-common.cc @@ -2278,6 +2278,7 @@ lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file, lto_input_mode_table (file_data); #else file_data->mode_table = lto_mode_identity_table; + file_data->mode_bits = ceil_log2 (MAX_MACHINE_MODE); #endif data = lto_get_summary_section_data (file_data, LTO_section_decls, &len); diff --git a/gcc/tree-streamer.cc b/gcc/tree-streamer.cc index ed65a7692e3..a28ef9c7920 100644 --- a/gcc/tree-streamer.cc +++ b/gcc/tree-streamer.cc @@ -35,7 +35,7 @@ along with GCC; see the file COPYING3. If not see During streaming in, we translate the on the disk mode using this table. For normal LTO it is set to identity, for ACCEL_COMPILER depending on the mode_table content. */ -unsigned char streamer_mode_table[1 << 8]; +unsigned char streamer_mode_table[MAX_MACHINE_MODE]; /* Check that all the TS_* structures handled by the streamer_write_* and streamer_read_* routines are exactly ALL the structures defined in diff --git a/gcc/tree-streamer.h b/gcc/tree-streamer.h index 6d565acbbc2..ff49d1ba637 100644 --- a/gcc/tree-streamer.h +++ b/gcc/tree-streamer.h @@ -75,7 +75,7 @@ void streamer_write_tree_body (struct output_block *, tree); void streamer_write_integer_cst (struct output_block *, tree); /* In tree-streamer.cc. */ -extern unsigned char streamer_mode_table[1 << 8]; +extern unsigned char streamer_mode_table[MAX_MACHINE_MODE]; void streamer_check_handled_ts_structures (void); bool streamer_tree_cache_insert (struct streamer_tree_cache_d *, tree, hashval_t, unsigned *); @@ -108,14 +108,16 @@ inline void bp_pack_machine_mode (struct bitpack_d *bp, machine_mode mode) { streamer_mode_table[mode] = 1; - bp_pack_enum (bp, machine_mode, 1 << 8, mode); + int last = 1 << ceil_log2 (MAX_MACHINE_MODE); + bp_pack_enum (bp, machine_mode, last, mode); } inline machine_mode bp_unpack_machine_mode (struct bitpack_d *bp) { lto_input_block *ib = (class lto_input_block *) bp->stream; - unsigned ix = bp_unpack_enum (bp, machine_mode, 1 << 8); + int last = 1 << ib->file_data->mode_bits; + unsigned ix = bp_unpack_enum (bp, machine_mode, last); return (machine_mode) ib->file_data->mode_table[ix]; }