diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f94b861c38a..607205a2754 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2012-10-18 Richard Guenther + + * lto-streamer.h (enum LTO_tags): Add LTO_integer_cst. + * lto-streamer-in.c (lto_input_tree): Use it. + * lto-streamer-out.c (lto_output_tree): Likewise, for + !TREE_OVERFLOW integer constants only. + * tree-streamer-in.c (unpack_ts_int_cst_value_fields): New function. + (unpack_value_fields): Call it. + (streamer_read_integer_cst): Simplify. + * tree-streamer-out.c (pack_ts_int_cst_value_fields): New function. + (streamer_pack_tree_bitfields): Call it. + (streamer_write_integer_cst): Adjust. + 2012-10-17 Matthew Gretton-Dann Ramana Radhakrishnan diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index a5d13eec5ff..15905f859a4 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -1086,9 +1086,9 @@ lto_input_tree (struct lto_input_block *ib, struct data_in *data_in) the code and class. */ result = streamer_get_builtin_tree (ib, data_in); } - else if (tag == lto_tree_code_to_tag (INTEGER_CST)) + else if (tag == LTO_integer_cst) { - /* For integer constants we only need the type and its hi/low + /* For shared integer constants we only need the type and its hi/low words. */ result = streamer_read_integer_cst (ib, data_in); } diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 55a20dd134b..806045b52bf 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -372,9 +372,10 @@ lto_output_tree (struct output_block *ob, tree expr, return; } - /* INTEGER_CST nodes are special because they need their original type + /* Shared INTEGER_CST nodes are special because they need their original type to be materialized by the reader (to implement TYPE_CACHED_VALUES). */ - if (TREE_CODE (expr) == INTEGER_CST) + if (TREE_CODE (expr) == INTEGER_CST + && !TREE_OVERFLOW (expr)) { streamer_write_integer_cst (ob, expr, ref_p); return; diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index c7b7ef94871..c9d13aea4da 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -175,6 +175,9 @@ enum LTO_tags /* An MD or NORMAL builtin. Only the code and class are streamed out. */ LTO_builtin_decl, + /* Shared INTEGER_CST node. */ + LTO_integer_cst, + /* Function body. */ LTO_function, diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c index 9e1e9750cb0..f573659edd1 100644 --- a/gcc/tree-streamer-in.c +++ b/gcc/tree-streamer-in.c @@ -140,6 +140,17 @@ unpack_ts_base_value_fields (struct bitpack_d *bp, tree expr) } +/* Unpack all the non-pointer fields of the TS_INT_CST structure of + expression EXPR from bitpack BP. */ + +static void +unpack_ts_int_cst_value_fields (struct bitpack_d *bp, tree expr) +{ + TREE_INT_CST_LOW (expr) = (unsigned) bp_unpack_var_len_unsigned (bp); + TREE_INT_CST_HIGH (expr) = (unsigned) bp_unpack_var_len_int (bp); +} + + /* Unpack all the non-pointer fields of the TS_REAL_CST structure of expression EXPR from bitpack BP. */ @@ -416,6 +427,9 @@ unpack_value_fields (struct data_in *data_in, struct bitpack_d *bp, tree expr) the types and sizes of each of the fields being packed. */ unpack_ts_base_value_fields (bp, expr); + if (CODE_CONTAINS_STRUCT (code, TS_INT_CST)) + unpack_ts_int_cst_value_fields (bp, expr); + if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST)) unpack_ts_real_cst_value_fields (bp, expr); @@ -1012,25 +1026,10 @@ streamer_read_tree_body (struct lto_input_block *ib, struct data_in *data_in, tree streamer_read_integer_cst (struct lto_input_block *ib, struct data_in *data_in) { - tree result, type; - HOST_WIDE_INT low, high; - bool overflow_p; - - type = stream_read_tree (ib, data_in); - overflow_p = (streamer_read_uchar (ib) != 0); - low = streamer_read_uhwi (ib); - high = streamer_read_uhwi (ib); - result = build_int_cst_wide (type, low, high); - - /* If the original constant had overflown, build a replica of RESULT to - avoid modifying the shared constant returned by build_int_cst_wide. */ - if (overflow_p) - { - result = copy_node (result); - TREE_OVERFLOW (result) = 1; - } - - return result; + tree type = stream_read_tree (ib, data_in); + unsigned HOST_WIDE_INT low = streamer_read_uhwi (ib); + HOST_WIDE_INT high = streamer_read_hwi (ib); + return build_int_cst_wide (type, low, high); } diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c index ee5e31172b9..1f0eb55ec44 100644 --- a/gcc/tree-streamer-out.c +++ b/gcc/tree-streamer-out.c @@ -112,6 +112,17 @@ pack_ts_base_value_fields (struct bitpack_d *bp, tree expr) } +/* Pack all the non-pointer fields of the TS_INTEGER_CST structure of + expression EXPR into bitpack BP. */ + +static void +pack_ts_int_cst_value_fields (struct bitpack_d *bp, tree expr) +{ + bp_pack_var_len_unsigned (bp, TREE_INT_CST_LOW (expr)); + bp_pack_var_len_int (bp, TREE_INT_CST_HIGH (expr)); +} + + /* Pack all the non-pointer fields of the TS_REAL_CST structure of expression EXPR into bitpack BP. */ @@ -373,6 +384,9 @@ streamer_pack_tree_bitfields (struct output_block *ob, the types and sizes of each of the fields being packed. */ pack_ts_base_value_fields (bp, expr); + if (CODE_CONTAINS_STRUCT (code, TS_INT_CST)) + pack_ts_int_cst_value_fields (bp, expr); + if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST)) pack_ts_real_cst_value_fields (bp, expr); @@ -935,9 +949,9 @@ streamer_write_tree_header (struct output_block *ob, tree expr) void streamer_write_integer_cst (struct output_block *ob, tree cst, bool ref_p) { - streamer_write_record_start (ob, lto_tree_code_to_tag (INTEGER_CST)); + gcc_assert (!TREE_OVERFLOW (cst)); + streamer_write_record_start (ob, LTO_integer_cst); stream_write_tree (ob, TREE_TYPE (cst), ref_p); - streamer_write_char_stream (ob->main_stream, TREE_OVERFLOW_P (cst)); streamer_write_uhwi (ob, TREE_INT_CST_LOW (cst)); - streamer_write_uhwi (ob, TREE_INT_CST_HIGH (cst)); + streamer_write_hwi (ob, TREE_INT_CST_HIGH (cst)); }