diff options
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/basic-block.h | 3 | ||||
-rw-r--r-- | gcc/lto-streamer-in.c | 56 | ||||
-rw-r--r-- | gcc/lto-streamer-out.c | 41 | ||||
-rw-r--r-- | gcc/lto-streamer.h | 52 | ||||
-rw-r--r-- | gcc/tree.h | 4 |
6 files changed, 132 insertions, 40 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9a2f4d347ab..7d149a39987 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2011-05-28 Jan Hubicka <jh@suse.cz> + + * lto-streamer-out.c (pack_ts_fixed_cst_value_fields, + pack_ts_decl_common_value_fields, pack_ts_decl_with_vis_value_fields, + pack_ts_function_decl_value_fields, lto_output_builtin_tree, + output_cfg, output_gimple_stmt): Use enum and variable length i/o. + * lto-streamer-in.c (input_cfg, input_gimple_stmt, + unpack_ts_fixed_cst_value_fields, unpack_ts_decl_common_value_fields, + unpack_ts_decl_with_vis_value_fields, + unpack_ts_type_common_value_fields, unpack_ts_block_value_fields, + lto_get_builtin_tree): Use enum and variable length i/o. + * basic-block.h (profile_status_d): Add PROFILE_LAST. + * lto-streamer.h (bp_pack_int_in_range, bp_unpack_int_in_range): + New functions. + (bp_pack_enum, bp_unpack_enum): New macros. + 2011-05-28 Richard Sandiford <rdsandiford@googlemail.com> * genrecog.c: Remove redundant forward declarations. diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 946fe9d2ba1..29c1167cfe7 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -283,7 +283,8 @@ enum profile_status_d { PROFILE_ABSENT, PROFILE_GUESSED, - PROFILE_READ + PROFILE_READ, + PROFILE_LAST /* Last value, used by profile streaming. */ }; /* A structure to group all the per-function control flow graph data. diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index d2e4ed3ec20..88966f2d03d 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -798,8 +798,7 @@ input_cfg (struct lto_input_block *ib, struct function *fn, init_empty_tree_cfg_for_function (fn); init_ssa_operands (); - profile_status_for_function (fn) = - (enum profile_status_d) lto_input_uleb128 (ib); + profile_status_for_function (fn) = lto_input_enum (ib, profile_status_d, PROFILE_LAST); bb_count = lto_input_uleb128 (ib); @@ -960,13 +959,13 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, /* Read the tuple header. */ bp = lto_input_bitpack (ib); - num_ops = bp_unpack_value (&bp, sizeof (unsigned) * 8); + num_ops = bp_unpack_var_len_unsigned (&bp); stmt = gimple_alloc (code, num_ops); 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); + stmt->gsbase.subcode = bp_unpack_var_len_unsigned (&bp); /* Read location information. */ gimple_set_location (stmt, lto_input_location (ib, data_in)); @@ -1090,7 +1089,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, { if (gimple_call_internal_p (stmt)) gimple_call_set_internal_fn - (stmt, (enum internal_fn) lto_input_sleb128 (ib)); + (stmt, lto_input_enum (ib, internal_fn, IFN_LAST)); else gimple_call_set_fntype (stmt, lto_input_tree (ib, data_in)); } @@ -1638,9 +1637,9 @@ unpack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr) { struct fixed_value fv; - fv.data.low = (HOST_WIDE_INT) bp_unpack_value (bp, HOST_BITS_PER_WIDE_INT); - fv.data.high = (HOST_WIDE_INT) bp_unpack_value (bp, HOST_BITS_PER_WIDE_INT); - fv.mode = (enum machine_mode) bp_unpack_value (bp, HOST_BITS_PER_INT); + fv.mode = bp_unpack_enum (bp, machine_mode, MAX_MACHINE_MODE); + fv.data.low = bp_unpack_var_len_int (bp); + fv.data.high = bp_unpack_var_len_int (bp); TREE_FIXED_CST (expr) = fv; } @@ -1651,7 +1650,7 @@ unpack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr) static void unpack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) { - DECL_MODE (expr) = (enum machine_mode) bp_unpack_value (bp, 8); + DECL_MODE (expr) = bp_unpack_enum (bp, machine_mode, MAX_MACHINE_MODE); DECL_NONLOCAL (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_VIRTUAL_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_IGNORED_P (expr) = (unsigned) bp_unpack_value (bp, 1); @@ -1662,12 +1661,12 @@ unpack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) DECL_DEBUG_EXPR_IS_FROM (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_EXTERNAL (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_GIMPLE_REG_P (expr) = (unsigned) bp_unpack_value (bp, 1); - DECL_ALIGN (expr) = (unsigned) bp_unpack_value (bp, HOST_BITS_PER_INT); + DECL_ALIGN (expr) = (unsigned) bp_unpack_var_len_unsigned (bp); if (TREE_CODE (expr) == LABEL_DECL) { DECL_ERROR_ISSUED (expr) = (unsigned) bp_unpack_value (bp, 1); - EH_LANDING_PAD_NR (expr) = (int) bp_unpack_value (bp, HOST_BITS_PER_INT); + EH_LANDING_PAD_NR (expr) = (int) bp_unpack_var_len_unsigned (bp); /* Always assume an initial value of -1 for LABEL_DECL_UID to force gimple_set_bb to recreate label_to_block_map. */ @@ -1730,7 +1729,7 @@ unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) if (VAR_OR_FUNCTION_DECL_P (expr)) { priority_type p; - p = (priority_type) bp_unpack_value (bp, HOST_BITS_PER_SHORT); + p = (priority_type) bp_unpack_var_len_unsigned (bp); SET_DECL_INIT_PRIORITY (expr, p); } } @@ -1742,8 +1741,8 @@ unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) static void unpack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr) { - DECL_FUNCTION_CODE (expr) = (enum built_in_function) bp_unpack_value (bp, 11); - DECL_BUILT_IN_CLASS (expr) = (enum built_in_class) bp_unpack_value (bp, 2); + DECL_BUILT_IN_CLASS (expr) = bp_unpack_enum (bp, built_in_class, + BUILT_IN_LAST); DECL_STATIC_CONSTRUCTOR (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_STATIC_DESTRUCTOR (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_UNINLINABLE (expr) = (unsigned) bp_unpack_value (bp, 1); @@ -1761,10 +1760,24 @@ unpack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr) DECL_DISREGARD_INLINE_LIMITS (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_LOOPING_CONST_OR_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1); + if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN) + { + DECL_FUNCTION_CODE (expr) = (enum built_in_function) bp_unpack_value (bp, 11); + if (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_NORMAL + && DECL_FUNCTION_CODE (expr) >= END_BUILTINS) + fatal_error ("machine independent builtin code out of range"); + else if (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD) + { + tree result = targetm.builtin_decl (DECL_FUNCTION_CODE (expr), true); + if (!result || result == error_mark_node) + fatal_error ("target specific builtin not available"); + } + } if (DECL_STATIC_DESTRUCTOR (expr)) { - priority_type p = (priority_type) bp_unpack_value (bp, HOST_BITS_PER_SHORT); - SET_DECL_FINI_PRIORITY (expr, p); + priority_type p; + p = (priority_type) bp_unpack_var_len_unsigned (bp); + SET_DECL_FINI_PRIORITY (expr, p); } } @@ -1777,8 +1790,7 @@ unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr) { enum machine_mode mode; - TYPE_PRECISION (expr) = (unsigned) bp_unpack_value (bp, 10); - mode = (enum machine_mode) bp_unpack_value (bp, 8); + mode = bp_unpack_enum (bp, machine_mode, MAX_MACHINE_MODE); SET_TYPE_MODE (expr, mode); TYPE_STRING_FLAG (expr) = (unsigned) bp_unpack_value (bp, 1); TYPE_NO_FORCE_BLK (expr) = (unsigned) bp_unpack_value (bp, 1); @@ -1791,6 +1803,7 @@ unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr) = (unsigned) bp_unpack_value (bp, 2); TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1); TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1); + TYPE_PRECISION (expr) = bp_unpack_var_len_unsigned (bp); TYPE_ALIGN (expr) = bp_unpack_var_len_unsigned (bp); TYPE_ALIAS_SET (expr) = bp_unpack_var_len_int (bp); } @@ -1803,7 +1816,7 @@ static void unpack_ts_block_value_fields (struct bitpack_d *bp, tree expr) { BLOCK_ABSTRACT (expr) = (unsigned) bp_unpack_value (bp, 1); - BLOCK_NUMBER (expr) = (unsigned) bp_unpack_value (bp, 31); + /* BLOCK_NUMBER is recomputed. */ } /* Unpack all the non-pointer fields of the TS_TRANSLATION_UNIT_DECL @@ -2603,14 +2616,15 @@ lto_get_builtin_tree (struct lto_input_block *ib, struct data_in *data_in) const char *asmname; tree result; - fclass = (enum built_in_class) lto_input_uleb128 (ib); + fclass = lto_input_enum (ib, built_in_class, BUILT_IN_LAST); gcc_assert (fclass == BUILT_IN_NORMAL || fclass == BUILT_IN_MD); fcode = (enum built_in_function) lto_input_uleb128 (ib); if (fclass == BUILT_IN_NORMAL) { - gcc_assert (fcode < END_BUILTINS); + if (fcode >= END_BUILTINS) + fatal_error ("machine independent builtin code out of range"); result = built_in_decls[fcode]; gcc_assert (result); } diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index b9ac6d03245..2b80640d70e 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -372,9 +372,9 @@ static void pack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr) { struct fixed_value fv = TREE_FIXED_CST (expr); - bp_pack_value (bp, fv.data.low, HOST_BITS_PER_WIDE_INT); - bp_pack_value (bp, fv.data.high, HOST_BITS_PER_WIDE_INT); - bp_pack_value (bp, fv.mode, HOST_BITS_PER_INT); + bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, fv.mode); + bp_pack_var_len_int (bp, fv.data.low); + bp_pack_var_len_int (bp, fv.data.high); } @@ -384,7 +384,7 @@ pack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr) static void pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) { - bp_pack_value (bp, DECL_MODE (expr), 8); + bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, DECL_MODE (expr)); bp_pack_value (bp, DECL_NONLOCAL (expr), 1); bp_pack_value (bp, DECL_VIRTUAL_P (expr), 1); bp_pack_value (bp, DECL_IGNORED_P (expr), 1); @@ -395,7 +395,7 @@ pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) bp_pack_value (bp, DECL_DEBUG_EXPR_IS_FROM (expr), 1); bp_pack_value (bp, DECL_EXTERNAL (expr), 1); bp_pack_value (bp, DECL_GIMPLE_REG_P (expr), 1); - bp_pack_value (bp, DECL_ALIGN (expr), HOST_BITS_PER_INT); + bp_pack_var_len_unsigned (bp, DECL_ALIGN (expr)); if (TREE_CODE (expr) == LABEL_DECL) { @@ -403,7 +403,7 @@ pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) always assume an initial value of -1 so that the label_to_block_map is recreated by gimple_set_bb. */ bp_pack_value (bp, DECL_ERROR_ISSUED (expr), 1); - bp_pack_value (bp, EH_LANDING_PAD_NR (expr), HOST_BITS_PER_INT); + bp_pack_var_len_unsigned (bp, EH_LANDING_PAD_NR (expr)); } if (TREE_CODE (expr) == FIELD_DECL) @@ -460,7 +460,7 @@ pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) } if (VAR_OR_FUNCTION_DECL_P (expr)) - bp_pack_value (bp, DECL_INIT_PRIORITY (expr), HOST_BITS_PER_SHORT); + bp_pack_var_len_unsigned (bp, DECL_INIT_PRIORITY (expr)); } @@ -474,8 +474,8 @@ pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr) should never be handled here. */ gcc_assert (!lto_stream_as_builtin_p (expr)); - bp_pack_value (bp, DECL_FUNCTION_CODE (expr), 11); - bp_pack_value (bp, DECL_BUILT_IN_CLASS (expr), 2); + bp_pack_enum (bp, built_in_class, BUILT_IN_LAST, + DECL_BUILT_IN_CLASS (expr)); bp_pack_value (bp, DECL_STATIC_CONSTRUCTOR (expr), 1); bp_pack_value (bp, DECL_STATIC_DESTRUCTOR (expr), 1); bp_pack_value (bp, DECL_UNINLINABLE (expr), 1); @@ -492,8 +492,10 @@ pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr) bp_pack_value (bp, DECL_DISREGARD_INLINE_LIMITS (expr), 1); bp_pack_value (bp, DECL_PURE_P (expr), 1); bp_pack_value (bp, DECL_LOOPING_CONST_OR_PURE_P (expr), 1); + if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN) + bp_pack_value (bp, DECL_FUNCTION_CODE (expr), 11); if (DECL_STATIC_DESTRUCTOR (expr)) - bp_pack_value (bp, DECL_FINI_PRIORITY (expr), HOST_BITS_PER_SHORT); + bp_pack_var_len_unsigned (bp, DECL_FINI_PRIORITY (expr)); } @@ -503,8 +505,7 @@ pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr) static void pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr) { - bp_pack_value (bp, TYPE_PRECISION (expr), 10); - bp_pack_value (bp, TYPE_MODE (expr), 8); + bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, TYPE_MODE (expr)); bp_pack_value (bp, TYPE_STRING_FLAG (expr), 1); bp_pack_value (bp, TYPE_NO_FORCE_BLK (expr), 1); bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING (expr), 1); @@ -515,6 +516,7 @@ pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr) bp_pack_value (bp, TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr), 2); bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1); bp_pack_value (bp, TYPE_READONLY (expr), 1); + bp_pack_var_len_unsigned (bp, TYPE_PRECISION (expr)); bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr)); bp_pack_var_len_int (bp, TYPE_ALIAS_SET (expr) == 0 ? 0 : -1); } @@ -527,7 +529,7 @@ static void pack_ts_block_value_fields (struct bitpack_d *bp, tree expr) { bp_pack_value (bp, BLOCK_ABSTRACT (expr), 1); - bp_pack_value (bp, BLOCK_NUMBER (expr), 31); + /* BLOCK_NUMBER is recomputed. */ } /* Pack all the non-pointer fields of the TS_TRANSLATION_UNIT_DECL structure @@ -1339,7 +1341,8 @@ lto_output_builtin_tree (struct output_block *ob, tree expr) "functions on this target"); output_record_start (ob, LTO_builtin_decl); - output_uleb128 (ob, DECL_BUILT_IN_CLASS (expr)); + lto_output_enum (ob->main_stream, built_in_class, BUILT_IN_LAST, + DECL_BUILT_IN_CLASS (expr)); output_uleb128 (ob, DECL_FUNCTION_CODE (expr)); if (DECL_ASSEMBLER_NAME_SET_P (expr)) @@ -1660,7 +1663,8 @@ output_cfg (struct output_block *ob, struct function *fn) ob->main_stream = ob->cfg_stream; - output_uleb128 (ob, profile_status_for_function (fn)); + lto_output_enum (ob->main_stream, profile_status_d, PROFILE_LAST, + profile_status_for_function (fn)); /* Output the number of the highest basic block. */ output_uleb128 (ob, last_basic_block_for_function (fn)); @@ -1734,12 +1738,12 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) /* Emit the tuple header. */ bp = bitpack_create (ob->main_stream); - bp_pack_value (&bp, gimple_num_ops (stmt), sizeof (unsigned) * 8); + bp_pack_var_len_unsigned (&bp, gimple_num_ops (stmt)); 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); + bp_pack_var_len_unsigned (&bp, stmt->gsbase.subcode); lto_output_bitpack (&bp); /* Emit location information for the statement. */ @@ -1808,7 +1812,8 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) if (is_gimple_call (stmt)) { if (gimple_call_internal_p (stmt)) - output_sleb128 (ob, (int) gimple_call_internal_fn (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)); } diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 4508818a4a6..150442d8d8d 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -1262,6 +1262,47 @@ lto_input_int_in_range (struct lto_input_block *ib, return val; } + +/* Output VAL into BP and verify it is in range MIN...MAX that is supposed + to be compile time constant. + Be host independent, limit range to 31bits. */ + +static inline void +bp_pack_int_in_range (struct bitpack_d *bp, + HOST_WIDE_INT min, + HOST_WIDE_INT max, + HOST_WIDE_INT val) +{ + HOST_WIDE_INT range = max - min; + int nbits = floor_log2 (range) + 1; + + gcc_checking_assert (val >= min && val <= max && range > 0 + && range < 0x7fffffff); + + val -= min; + bp_pack_value (bp, val, nbits); +} + +/* Input VAL into BP and verify it is in range MIN...MAX that is supposed + to be compile time constant. PURPOSE is used for error reporting. */ + +static inline HOST_WIDE_INT +bp_unpack_int_in_range (struct bitpack_d *bp, + const char *purpose, + HOST_WIDE_INT min, + HOST_WIDE_INT max) +{ + HOST_WIDE_INT range = max - min; + int nbits = floor_log2 (range) + 1; + HOST_WIDE_INT val = bp_unpack_value (bp, nbits); + + gcc_checking_assert (range > 0 && range < 0x7fffffff); + + if (val < min || val > max) + lto_value_range_error (purpose, val, min, max); + return val; +} + /* Output VAL of type "enum enum_name" into OBS. Assume range 0...ENUM_LAST - 1. */ #define lto_output_enum(obs,enum_name,enum_last,val) \ @@ -1273,4 +1314,15 @@ lto_input_int_in_range (struct lto_input_block *ib, (enum enum_name)lto_input_int_in_range ((ib), #enum_name, 0, \ (int)(enum_last) - 1) +/* Output VAL of type "enum enum_name" into BP. + Assume range 0...ENUM_LAST - 1. */ +#define bp_pack_enum(bp,enum_name,enum_last,val) \ + bp_pack_int_in_range ((bp), 0, (int)(enum_last) - 1, (int)(val)) + +/* Input enum of type "enum enum_name" from BP. + Assume range 0...ENUM_LAST - 1. */ +#define bp_unpack_enum(bp,enum_name,enum_last) \ + (enum enum_name)bp_unpack_int_in_range ((bp), #enum_name, 0, \ + (int)(enum_last) - 1) + #endif /* GCC_LTO_STREAMER_H */ diff --git a/gcc/tree.h b/gcc/tree.h index f63764a56d9..02a99944933 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -277,6 +277,10 @@ enum built_in_class BUILT_IN_NORMAL }; +/* Last marker used for LTO stremaing of built_in_class. We can not add it + to the enum since we need the enumb to fit in 2 bits. */ +#define BUILT_IN_LAST (BUILT_IN_NORMAL + 1) + /* Names for the above. */ extern const char *const built_in_class_names[4]; |