From b3ae44f373dfb53e44e7e6bfd88a3cce3a3675a9 Mon Sep 17 00:00:00 2001
From: Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
Date: Thu, 4 Aug 2016 11:54:00 +1000
Subject: [PATCH 6/8] Add wide_int streaming support

---
 gcc/lto-streamer-in.c  | 14 ++++++++++++++
 gcc/lto-streamer-out.c | 12 ++++++++++++
 gcc/lto-streamer.c     |  2 ++
 gcc/lto-streamer.h     |  2 ++
 gcc/streamer-hooks.h   |  9 +++++++++
 5 files changed, 39 insertions(+)

diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 1d56d21..16ae1c1 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -1456,6 +1456,20 @@ lto_input_tree (struct lto_input_block *ib, struct data_in *data_in)
   return lto_input_tree_1 (ib, data_in, tag, 0);
 }
 
+/* Read the physical representation of a wide_int val from
+   input block IB.  */
+
+wide_int
+lto_input_wide_int (struct lto_input_block *ib)
+{
+  HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
+  int i;
+  int prec = streamer_read_uhwi (ib);
+  int len = streamer_read_uhwi (ib);
+  for (i = 0; i < len; i++)
+    a[i] = streamer_read_hwi (ib);
+  return wide_int_storage::from_array (a, len, prec);
+}
 
 /* Input toplevel asms.  */
 
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index aa6b589..a563b77 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -1553,6 +1553,18 @@ DFS::DFS_write_tree (struct output_block *ob, sccs *from_state,
   worklist_vec.safe_push (w);
 }
 
+/* Emit the physical representation of wide_int VAL to output block OB.  */
+
+void
+lto_output_wide_int (struct output_block *ob, const wide_int &val)
+{
+  int len = val.get_len ();
+
+  streamer_write_uhwi (ob, val.get_precision ());
+  streamer_write_uhwi (ob, len);
+  for (int i = 0; i < len; i++)
+    streamer_write_hwi (ob, val.elt (i));
+}
 
 /* Emit the physical representation of tree node EXPR to output block OB.
    If THIS_REF_P is true, the leaves of EXPR are emitted as references via
diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
index bfde1fe..e07a6f9 100644
--- a/gcc/lto-streamer.c
+++ b/gcc/lto-streamer.c
@@ -396,6 +396,8 @@ lto_streamer_hooks_init (void)
   streamer_hooks_init ();
   streamer_hooks.write_tree = lto_output_tree;
   streamer_hooks.read_tree = lto_input_tree;
+  streamer_hooks.write_wide_int = lto_output_wide_int;
+  streamer_hooks.read_wide_int = lto_input_wide_int;
   streamer_hooks.input_location = lto_input_location;
   streamer_hooks.output_location = lto_output_location;
 }
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index ecc1e5d..b664342 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -874,6 +874,7 @@ hashval_t lto_input_scc (struct lto_input_block *, struct data_in *,
 tree lto_input_tree_1 (struct lto_input_block *, struct data_in *,
 		       enum LTO_tags, hashval_t hash);
 tree lto_input_tree (struct lto_input_block *, struct data_in *);
+wide_int lto_input_wide_int (struct lto_input_block *);
 
 
 /* In lto-streamer-out.c  */
@@ -892,6 +893,7 @@ void lto_output_decl_state_refs (struct output_block *,
 			         struct lto_out_decl_state *);
 void lto_output_location (struct output_block *, struct bitpack_d *, location_t);
 void lto_output_init_mode_table (void);
+void lto_output_wide_int (struct output_block *, const wide_int &);
 
 
 /* In lto-cgraph.c  */
diff --git a/gcc/streamer-hooks.h b/gcc/streamer-hooks.h
index 0727048..7fc3078 100644
--- a/gcc/streamer-hooks.h
+++ b/gcc/streamer-hooks.h
@@ -51,6 +51,9 @@ struct streamer_hooks {
      tree instantiated from the stream.  */
   tree (*read_tree) (struct lto_input_block *, struct data_in *);
 
+  wide_int (*read_wide_int) (struct lto_input_block *);
+  void (*write_wide_int) (struct output_block *, const wide_int &);
+
   /* [REQ] Called by every streaming routine that needs to read a location.  */
   void (*input_location) (location_t *, struct bitpack_d *, struct data_in *);
 
@@ -73,6 +76,12 @@ struct streamer_hooks {
 #define stream_output_location(OB, BP, LOC) \
     streamer_hooks.output_location (OB, BP, LOC)
 
+#define stream_write_wide_int(OB, EXPR) \
+    streamer_hooks.write_wide_int (OB, EXPR)
+
+#define stream_read_wide_int(IB, DATA_IN) \
+    streamer_hooks.read_wide_int (IB, DATA_IN)
+
 /* Streamer hooks.  */
 extern struct streamer_hooks streamer_hooks;
 
-- 
1.9.1

