about summary refs log tree commit diff
path: root/compiler/rustc_serialize/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-01-15 07:27:30 +0000
committerbors <bors@rust-lang.org>2022-01-15 07:27:30 +0000
commit38c22af0153cf8f920c01ef04493e8878401fd18 (patch)
tree0eddc6a30acb7bf64159aab68f7a8be0712000b2 /compiler/rustc_serialize/src
parent69d25fc58257637cedbfe0a046d90da1494bcb05 (diff)
parentfacba24926e218f996a953b0d91494a04374b217 (diff)
downloadrust-38c22af0153cf8f920c01ef04493e8878401fd18.tar.gz
rust-38c22af0153cf8f920c01ef04493e8878401fd18.zip
Auto merge of #92604 - nnethercote:optimize-impl_read_unsigned_leb128, r=michaelwoerister
Optimize `impl_read_unsigned_leb128`

I see instruction count improvements of up to 3.5% locally with these changes, mostly on the smaller benchmarks.

r? `@michaelwoerister`
Diffstat (limited to 'compiler/rustc_serialize/src')
-rw-r--r--compiler/rustc_serialize/src/leb128.rs31
-rw-r--r--compiler/rustc_serialize/src/opaque.rs6
2 files changed, 20 insertions, 17 deletions
diff --git a/compiler/rustc_serialize/src/leb128.rs b/compiler/rustc_serialize/src/leb128.rs
index ea2df80e641..08b3c054200 100644
--- a/compiler/rustc_serialize/src/leb128.rs
+++ b/compiler/rustc_serialize/src/leb128.rs
@@ -53,16 +53,24 @@ impl_write_unsigned_leb128!(write_usize_leb128, usize);
 macro_rules! impl_read_unsigned_leb128 {
     ($fn_name:ident, $int_ty:ty) => {
         #[inline]
-        pub fn $fn_name(slice: &[u8]) -> ($int_ty, usize) {
-            let mut result = 0;
-            let mut shift = 0;
-            let mut position = 0;
+        pub fn $fn_name(slice: &[u8], position: &mut usize) -> $int_ty {
+            // The first iteration of this loop is unpeeled. This is a
+            // performance win because this code is hot and integer values less
+            // than 128 are very common, typically occurring 50-80% or more of
+            // the time, even for u64 and u128.
+            let byte = slice[*position];
+            *position += 1;
+            if (byte & 0x80) == 0 {
+                return byte as $int_ty;
+            }
+            let mut result = (byte & 0x7F) as $int_ty;
+            let mut shift = 7;
             loop {
-                let byte = slice[position];
-                position += 1;
+                let byte = slice[*position];
+                *position += 1;
                 if (byte & 0x80) == 0 {
                     result |= (byte as $int_ty) << shift;
-                    return (result, position);
+                    return result;
                 } else {
                     result |= ((byte & 0x7F) as $int_ty) << shift;
                 }
@@ -122,15 +130,14 @@ impl_write_signed_leb128!(write_isize_leb128, isize);
 macro_rules! impl_read_signed_leb128 {
     ($fn_name:ident, $int_ty:ty) => {
         #[inline]
-        pub fn $fn_name(slice: &[u8]) -> ($int_ty, usize) {
+        pub fn $fn_name(slice: &[u8], position: &mut usize) -> $int_ty {
             let mut result = 0;
             let mut shift = 0;
-            let mut position = 0;
             let mut byte;
 
             loop {
-                byte = slice[position];
-                position += 1;
+                byte = slice[*position];
+                *position += 1;
                 result |= <$int_ty>::from(byte & 0x7F) << shift;
                 shift += 7;
 
@@ -144,7 +151,7 @@ macro_rules! impl_read_signed_leb128 {
                 result |= (!0 << shift);
             }
 
-            (result, position)
+            result
         }
     };
 }
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index f2ef1481681..078237801be 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -560,11 +560,7 @@ impl<'a> Decoder<'a> {
 }
 
 macro_rules! read_leb128 {
-    ($dec:expr, $fun:ident) => {{
-        let (value, bytes_read) = leb128::$fun(&$dec.data[$dec.position..]);
-        $dec.position += bytes_read;
-        Ok(value)
-    }};
+    ($dec:expr, $fun:ident) => {{ Ok(leb128::$fun($dec.data, &mut $dec.position)) }};
 }
 
 impl<'a> serialize::Decoder for Decoder<'a> {