summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/data-streamer-out.c91
-rw-r--r--gcc/data-streamer.h5
3 files changed, 89 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 16b4ca23c3d..25d746afa6c 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 4165b8747fc..247ff636e49 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 dfca7abbd2c..c18779ba30a 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--;
}