diff options
-rw-r--r-- | gcc/data-streamer-in.cc | 55 | ||||
-rw-r--r-- | gcc/data-streamer-out.cc | 51 | ||||
-rw-r--r-- | gcc/data-streamer.h | 3 |
3 files changed, 109 insertions, 0 deletions
diff --git a/gcc/data-streamer-in.cc b/gcc/data-streamer-in.cc index 8ebcac43479..07728bef413 100644 --- a/gcc/data-streamer-in.cc +++ b/gcc/data-streamer-in.cc @@ -28,6 +28,8 @@ along with GCC; see the file COPYING3. If not see #include "gimple.h" #include "cgraph.h" #include "data-streamer.h" +#include "value-range.h" +#include "streamer-hooks.h" /* Read a string from the string table in DATA_IN using input block IB. Write the length to RLEN. */ @@ -206,6 +208,59 @@ streamer_read_gcov_count (class lto_input_block *ib) return ret; } +/* Read REAL_VALUE_TYPE from IB. */ + +void +streamer_read_real_value (class lto_input_block *ib, REAL_VALUE_TYPE *r) +{ + struct bitpack_d bp = streamer_read_bitpack (ib); + bp_unpack_real_value (&bp, r); +} + +void +streamer_read_value_range (class lto_input_block *ib, data_in *data_in, + Value_Range &vr) +{ + // Read the common fields to all vranges. + value_range_kind kind = streamer_read_enum (ib, value_range_kind, VR_LAST); + gcc_checking_assert (kind != VR_UNDEFINED); + tree type = stream_read_tree (ib, data_in); + + // Initialize the Value_Range to the correct type. + vr.set_type (type); + + if (is_a <irange> (vr)) + { + irange &r = as_a <irange> (vr); + r.set_undefined (); + unsigned HOST_WIDE_INT num_pairs = streamer_read_uhwi (ib); + for (unsigned i = 0; i < num_pairs; ++i) + { + wide_int lb = streamer_read_wide_int (ib); + wide_int ub = streamer_read_wide_int (ib); + int_range<2> tmp (type, lb, ub); + r.union_ (tmp); + } + wide_int nz = streamer_read_wide_int (ib); + r.set_nonzero_bits (nz); + return; + } + if (is_a <frange> (vr)) + { + frange &r = as_a <frange> (vr); + REAL_VALUE_TYPE lb, ub; + streamer_read_real_value (ib, &lb); + streamer_read_real_value (ib, &ub); + struct bitpack_d bp = streamer_read_bitpack (ib); + bool pos_nan = (bool) bp_unpack_value (&bp, 1); + bool neg_nan = (bool) bp_unpack_value (&bp, 1); + nan_state nan (pos_nan, neg_nan); + r.set (type, lb, ub, nan); + return; + } + gcc_unreachable (); +} + /* Read the physical representation of a wide_int val from input block IB. */ diff --git a/gcc/data-streamer-out.cc b/gcc/data-streamer-out.cc index cd25745b8dc..afc9862062b 100644 --- a/gcc/data-streamer-out.cc +++ b/gcc/data-streamer-out.cc @@ -28,6 +28,8 @@ along with GCC; see the file COPYING3. If not see #include "gimple.h" #include "cgraph.h" #include "data-streamer.h" +#include "value-range.h" +#include "streamer-hooks.h" /* Adds a new block to output stream OBS. */ @@ -392,6 +394,55 @@ streamer_write_data_stream (struct lto_output_stream *obs, const void *data, } } +/* Write REAL_VALUE_TYPE into OB. */ + +void +streamer_write_real_value (struct output_block *ob, const REAL_VALUE_TYPE *r) +{ + bitpack_d bp = bitpack_create (ob->main_stream); + bp_pack_real_value (&bp, r); + streamer_write_bitpack (&bp); +} + +void +streamer_write_vrange (struct output_block *ob, const vrange &v) +{ + gcc_checking_assert (!v.undefined_p ()); + + // Write the common fields to all vranges. + value_range_kind kind = v.varying_p () ? VR_VARYING : VR_RANGE; + streamer_write_enum (ob->main_stream, value_range_kind, VR_LAST, kind); + stream_write_tree (ob, v.type (), true); + + if (is_a <irange> (v)) + { + const irange &r = as_a <irange> (v); + streamer_write_uhwi (ob, r.num_pairs ()); + for (unsigned i = 0; i < r.num_pairs (); ++i) + { + streamer_write_wide_int (ob, r.lower_bound (i)); + streamer_write_wide_int (ob, r.upper_bound (i)); + } + streamer_write_wide_int (ob, r.get_nonzero_bits ()); + return; + } + if (is_a <frange> (v)) + { + const frange &r = as_a <frange> (v); + REAL_VALUE_TYPE lb = r.lower_bound (); + REAL_VALUE_TYPE ub = r.upper_bound (); + streamer_write_real_value (ob, &lb); + streamer_write_real_value (ob, &ub); + bitpack_d bp = bitpack_create (ob->main_stream); + nan_state nan = r.get_nan_state (); + bp_pack_value (&bp, nan.pos_p (), 1); + bp_pack_value (&bp, nan.neg_p (), 1); + streamer_write_bitpack (&bp); + return; + } + gcc_unreachable (); +} + /* Emit the physical representation of wide_int VAL to output block OB. */ void diff --git a/gcc/data-streamer.h b/gcc/data-streamer.h index 19c9d6ea606..7e69eb9992b 100644 --- a/gcc/data-streamer.h +++ b/gcc/data-streamer.h @@ -75,6 +75,7 @@ void streamer_write_data_stream (struct lto_output_stream *, const void *, size_t); void streamer_write_wide_int (struct output_block *, const wide_int &); void streamer_write_widest_int (struct output_block *, const widest_int &); +void streamer_write_vrange (struct output_block *, const class vrange &); /* In data-streamer-in.cc */ const char *streamer_read_string (class data_in *, class lto_input_block *); @@ -91,6 +92,8 @@ poly_int64 streamer_read_poly_int64 (class lto_input_block *); gcov_type streamer_read_gcov_count (class lto_input_block *); wide_int streamer_read_wide_int (class lto_input_block *); widest_int streamer_read_widest_int (class lto_input_block *); +void streamer_read_value_range (class lto_input_block *, class data_in *, + class Value_Range &); /* Returns a new bit-packing context for bit-packing into S. */ inline struct bitpack_d |