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 + + * 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 * 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; + { + /* More bits to follow. */ + work >>= 1; + byte |= 0x80; + } - streamer_write_char_stream (obs, byte); + *(current_pointer++) = byte; + left_in_block--; + size++; } - while (more); + 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); + } + 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--; }