summaryrefslogtreecommitdiff
path: root/gcc/data-streamer-in.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-20 11:33:43 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-20 11:33:43 +0000
commitab4542ebddf28e6b1a332ecd22fd6f84249cf4e9 (patch)
treecf9203d5af293ba8f6a3a702432bb6e293e1842b /gcc/data-streamer-in.c
parentd6da73039f46a29b59bb951c7fc56c4052c05d4c (diff)
downloadgcc-ab4542ebddf28e6b1a332ecd22fd6f84249cf4e9.tar.gz
2013-06-20 Richard Biener <rguenther@suse.de>
* data-streamer-in.c (streamer_read_uhwi): Optimize single byte case, inline streamer_read_uchar and defer section overrun check. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200239 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/data-streamer-in.c')
-rw-r--r--gcc/data-streamer-in.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/gcc/data-streamer-in.c b/gcc/data-streamer-in.c
index e9ceb29312a..93fe2ff4c3b 100644
--- a/gcc/data-streamer-in.c
+++ b/gcc/data-streamer-in.c
@@ -120,18 +120,33 @@ bp_unpack_string (struct data_in *data_in, struct bitpack_d *bp)
unsigned HOST_WIDE_INT
streamer_read_uhwi (struct lto_input_block *ib)
{
- unsigned HOST_WIDE_INT result = 0;
- int shift = 0;
+ unsigned HOST_WIDE_INT result;
+ int shift;
unsigned HOST_WIDE_INT byte;
+ unsigned int p = ib->p;
+ unsigned int len = ib->len;
- while (true)
+ const char *data = ib->data;
+ result = data[p++];
+ if ((result & 0x80) != 0)
{
- byte = streamer_read_uchar (ib);
- result |= (byte & 0x7f) << shift;
- shift += 7;
- if ((byte & 0x80) == 0)
- return result;
+ result &= 0x7f;
+ shift = 7;
+ do
+ {
+ byte = data[p++];
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+ }
+ while ((byte & 0x80) != 0);
}
+
+ /* We check for section overrun after the fact for performance reason. */
+ if (p > len)
+ lto_section_overrun (ib);
+
+ ib->p = p;
+ return result;
}