This makes us stream TREE_OVERFLOW INTEGER_CSTs the normal way (and thus possibly allow pickle refs to them). Shared INTEGER_CSTs which are special use LTO_integer_cst now instead of the weird special-casing of the LTO tag for INTEGER_CST.
LTO bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2012-10-18 Richard Guenther <rguent...@suse.de> * 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. Index: gcc/lto-streamer.h =================================================================== *** gcc/lto-streamer.h (revision 192529) --- gcc/lto-streamer.h (working copy) *************** enum LTO_tags *** 175,180 **** --- 175,183 ---- /* 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, Index: gcc/lto-streamer-in.c =================================================================== *** gcc/lto-streamer-in.c (revision 192529) --- gcc/lto-streamer-in.c (working copy) *************** lto_input_tree (struct lto_input_block * *** 1086,1094 **** the code and class. */ result = streamer_get_builtin_tree (ib, data_in); } ! else if (tag == lto_tree_code_to_tag (INTEGER_CST)) { ! /* For integer constants we only need the type and its hi/low words. */ result = streamer_read_integer_cst (ib, data_in); } --- 1086,1094 ---- the code and class. */ result = streamer_get_builtin_tree (ib, data_in); } ! else if (tag == LTO_integer_cst) { ! /* For shared integer constants we only need the type and its hi/low words. */ result = streamer_read_integer_cst (ib, data_in); } Index: gcc/lto-streamer-out.c =================================================================== *** gcc/lto-streamer-out.c (revision 192529) --- gcc/lto-streamer-out.c (working copy) *************** lto_output_tree (struct output_block *ob *** 372,380 **** return; } ! /* 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) { streamer_write_integer_cst (ob, expr, ref_p); return; --- 372,381 ---- return; } ! /* 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 ! && !TREE_OVERFLOW (expr)) { streamer_write_integer_cst (ob, expr, ref_p); return; Index: gcc/tree-streamer-in.c =================================================================== *** gcc/tree-streamer-in.c (revision 192529) --- gcc/tree-streamer-in.c (working copy) *************** unpack_ts_base_value_fields (struct bitp *** 140,145 **** --- 140,156 ---- } + /* 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. */ *************** unpack_value_fields (struct data_in *dat *** 416,421 **** --- 427,435 ---- 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); *************** streamer_read_tree_body (struct lto_inpu *** 1012,1036 **** 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; } --- 1026,1035 ---- tree streamer_read_integer_cst (struct lto_input_block *ib, struct data_in *data_in) { ! 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); } Index: gcc/tree-streamer-out.c =================================================================== *** gcc/tree-streamer-out.c (revision 192529) --- gcc/tree-streamer-out.c (working copy) *************** pack_ts_base_value_fields (struct bitpac *** 112,117 **** --- 112,128 ---- } + /* 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. */ *************** streamer_pack_tree_bitfields (struct out *** 373,378 **** --- 384,392 ---- 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); *************** streamer_write_tree_header (struct outpu *** 935,943 **** 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)); 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)); } --- 949,957 ---- void streamer_write_integer_cst (struct output_block *ob, tree cst, bool ref_p) { ! gcc_assert (!TREE_OVERFLOW (cst)); ! streamer_write_record_start (ob, LTO_integer_cst); stream_write_tree (ob, TREE_TYPE (cst), ref_p); streamer_write_uhwi (ob, TREE_INT_CST_LOW (cst)); ! streamer_write_hwi (ob, TREE_INT_CST_HIGH (cst)); }