]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add support for vrange streaming.
authorAldy Hernandez <aldyh@redhat.com>
Tue, 18 Apr 2023 05:57:43 +0000 (07:57 +0200)
committerAldy Hernandez <aldyh@redhat.com>
Wed, 17 May 2023 14:08:48 +0000 (16:08 +0200)
I think it's time for the ranger folk to start owning range streaming
instead of passes (IPA, etc) doing their own thing.  I have plans for
overhauling the IPA code later this cycle to support generic ranges,
and I'd like to start cleaning up the streaming and hashing interface.

This patch adds generic streaming support for vrange.

gcc/ChangeLog:

* data-streamer-in.cc (streamer_read_real_value): New.
(streamer_read_value_range): New.
* data-streamer-out.cc (streamer_write_real_value): New.
(streamer_write_vrange): New.
* data-streamer.h (streamer_write_vrange): New.
(streamer_read_value_range): New.

gcc/data-streamer-in.cc
gcc/data-streamer-out.cc
gcc/data-streamer.h

index 8ebcac434795745b6e9efee07d35ffb2bfaf577f..07728bef41370a1dd10310b15cf369d291415fa9 100644 (file)
@@ -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.  */
 
index cd25745b8dc71b1355a740eea3c8fbf17588b825..afc9862062b7b4491d4cf422dceb0b711e04e8b6 100644 (file)
@@ -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
index 19c9d6ea6069348521b5b77e6d2114cca5df06e2..7e69eb9992b762a05f37e8603c77122ec9622cc6 100644 (file)
@@ -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