From a4fa02d1b707a31c6d5e5508a9f2c7f0abdbb5ea Mon Sep 17 00:00:00 2001
From: Richard Biener <rguenther@suse.de>
Date: Wed, 12 Jun 2013 11:09:50 +0000
Subject: [PATCH] data-streamer.h (streamer_write_char_stream): CSE
 obs->current_pointer.

2013-06-12  Richard Biener  <rguenther@suse.de>

	* data-streamer.h (streamer_write_char_stream): CSE
	obs->current_pointer.
	* data-streamer-out.c (streamer_write_uhwi_stream): Inline
	streamer_write_char_stream manually and optimize the resulting loop.
	(streamer_write_hwi_stream): Likewise.

From-SVN: r199992
---
 gcc/ChangeLog           |  8 ++++
 gcc/data-streamer-out.c | 91 +++++++++++++++++++++++++++++++++++------
 gcc/data-streamer.h     |  5 ++-
 3 files changed, 89 insertions(+), 15 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 16b4ca23c3df..25d746afa6c7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2013-06-12  Richard Biener  <rguenther@suse.de>
+
+	* data-streamer.h (streamer_write_char_stream): CSE
+	obs->current_pointer.
+	* data-streamer-out.c (streamer_write_uhwi_stream): Inline
+	streamer_write_char_stream manually and optimize the resulting loop.
+	(streamer_write_hwi_stream): Likewise.
+
 2013-06-12  Jan Hubicka  <jh@suse.cz>
 
 	* lto-symtab.c (lto_symtab_merge_symbols): Populate symtab hashtable.
diff --git a/gcc/data-streamer-out.c b/gcc/data-streamer-out.c
index 4165b8747fca..247ff636e492 100644
--- a/gcc/data-streamer-out.c
+++ b/gcc/data-streamer-out.c
@@ -187,6 +187,11 @@ void
 streamer_write_uhwi_stream (struct lto_output_stream *obs,
                             unsigned HOST_WIDE_INT work)
 {
+  if (obs->left_in_block == 0)
+    lto_append_block (obs);
+  char *current_pointer = obs->current_pointer;
+  unsigned int left_in_block = obs->left_in_block;
+  unsigned int size = 0;
   do
     {
       unsigned int byte = (work & 0x7f);
@@ -195,9 +200,34 @@ streamer_write_uhwi_stream (struct lto_output_stream *obs,
 	/* More bytes to follow.  */
 	byte |= 0x80;
 
-      streamer_write_char_stream (obs, byte);
+      *(current_pointer++) = byte;
+      left_in_block--;
+      size++;
     }
-  while (work != 0);
+  while (work != 0 && left_in_block > 0);
+  if (work != 0)
+    {
+      obs->left_in_block = 0;
+      lto_append_block (obs);
+      current_pointer = obs->current_pointer;
+      left_in_block = obs->left_in_block;
+      do
+	{
+	  unsigned int byte = (work & 0x7f);
+	  work >>= 7;
+	  if (work != 0)
+	    /* More bytes to follow.  */
+	    byte |= 0x80;
+
+	  *(current_pointer++) = byte;
+	  left_in_block--;
+	  size++;
+	}
+      while (work != 0);
+    }
+  obs->current_pointer = current_pointer;
+  obs->left_in_block = left_in_block;
+  obs->total_size += size;
 }
 
 
@@ -206,21 +236,56 @@ streamer_write_uhwi_stream (struct lto_output_stream *obs,
 void
 streamer_write_hwi_stream (struct lto_output_stream *obs, HOST_WIDE_INT work)
 {
-  int more, byte;
-
+  if (obs->left_in_block == 0)
+    lto_append_block (obs);
+  char *current_pointer = obs->current_pointer;
+  unsigned int left_in_block = obs->left_in_block;
+  unsigned int size = 0;
+  bool more;
   do
     {
-      byte = (work & 0x7f);
-      /* arithmetic shift */
-      work >>= 7;
-      more = !((work == 0 && (byte & 0x40) == 0)
-	       || (work == -1 && (byte & 0x40) != 0));
+      unsigned int byte = (work & 0x7f);
+      /* If the lower 7-bits are sign-extended 0 or -1 we are finished.  */
+      work >>= 6;
+      more = !(work == 0 || work == -1);
       if (more)
-	byte |= 0x80;
-
-      streamer_write_char_stream (obs, byte);
+	{
+	  /* More bits to follow.  */
+	  work >>= 1;
+	  byte |= 0x80;
+	}
+
+      *(current_pointer++) = byte;
+      left_in_block--;
+      size++;
+    }
+  while (more && left_in_block > 0);
+  if (more)
+    {
+      obs->left_in_block = 0;
+      lto_append_block (obs);
+      current_pointer = obs->current_pointer;
+      left_in_block = obs->left_in_block;
+      do
+	{
+	  unsigned int byte = (work & 0x7f);
+	  work >>= 6;
+	  more = !(work == 0 || work == -1);
+	  if (more)
+	    {
+	      work >>= 1;
+	      byte |= 0x80;
+	    }
+
+	  *(current_pointer++) = byte;
+	  left_in_block--;
+	  size++;
+	}
+      while (more);
     }
-  while (more);
+  obs->current_pointer = current_pointer;
+  obs->left_in_block = left_in_block;
+  obs->total_size += size;
 }
 
 /* Write a GCOV counter value WORK to OBS.  */
diff --git a/gcc/data-streamer.h b/gcc/data-streamer.h
index dfca7abbd2cf..c18779ba30ab 100644
--- a/gcc/data-streamer.h
+++ b/gcc/data-streamer.h
@@ -183,8 +183,9 @@ streamer_write_char_stream (struct lto_output_stream *obs, char c)
     lto_append_block (obs);
 
   /* Write the actual character.  */
-  *obs->current_pointer = c;
-  obs->current_pointer++;
+  char *current_pointer = obs->current_pointer;
+  *(current_pointer++) = c;
+  obs->current_pointer = current_pointer;
   obs->total_size++;
   obs->left_in_block--;
 }
-- 
GitLab