about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2022-05-25 14:01:18 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2022-05-26 08:56:49 +1000
commit2b91c40c19e51b694ec113fd6991cf59959d4046 (patch)
treeb32895c88922e4f2e7216209de60f46aa07cc7ff
parent3e810c64d091112cf8ac51a533068632fad30a8d (diff)
downloadrust-2b91c40c19e51b694ec113fd6991cf59959d4046.tar.gz
rust-2b91c40c19e51b694ec113fd6991cf59959d4046.zip
Avoid adjusting file positions twice.
`imported_source_files` adjusts lots of file positions, and then calls
`new_imported_source_file`, which then adjust them all again. This
commit combines the two adjustments into one, for a small perf win.
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs26
-rw-r--r--compiler/rustc_span/src/source_map.rs21
2 files changed, 18 insertions, 29 deletions
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 4038af38a2c..1624e6cd6ee 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1639,10 +1639,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                         src_hash,
                         start_pos,
                         end_pos,
-                        mut lines,
-                        mut multibyte_chars,
-                        mut non_narrow_chars,
-                        mut normalized_pos,
+                        lines,
+                        multibyte_chars,
+                        non_narrow_chars,
+                        normalized_pos,
                         name_hash,
                         ..
                     } = source_file_to_import;
@@ -1679,24 +1679,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
                     let source_length = (end_pos - start_pos).to_usize();
 
-                    // Translate line-start positions and multibyte character
-                    // position into frame of reference local to file.
-                    // `SourceMap::new_imported_source_file()` will then translate those
-                    // coordinates to their new global frame of reference when the
-                    // offset of the SourceFile is known.
-                    for pos in &mut lines {
-                        *pos = *pos - start_pos;
-                    }
-                    for mbc in &mut multibyte_chars {
-                        mbc.pos = mbc.pos - start_pos;
-                    }
-                    for swc in &mut non_narrow_chars {
-                        *swc = *swc - start_pos;
-                    }
-                    for np in &mut normalized_pos {
-                        np.pos = np.pos - start_pos;
-                    }
-
                     let local_version = sess.source_map().new_imported_source_file(
                         name,
                         src_hash,
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 020ae3ad0c7..d60b4d3d021 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -345,20 +345,27 @@ impl SourceMap {
         let end_pos = Pos::from_usize(start_pos + source_len);
         let start_pos = Pos::from_usize(start_pos);
 
+        // Translate these positions into the new global frame of reference,
+        // now that the offset of the SourceFile is known.
+        //
+        // These are all unsigned values. `original_start_pos` may be larger or
+        // smaller than `start_pos`, but `pos` is always larger than both.
+        // Therefore, `(pos - original_start_pos) + start_pos` won't overflow
+        // but `start_pos - original_start_pos` might. So we use the former
+        // form rather than pre-computing the offset into a local variable. The
+        // compiler backend can optimize away the repeated computations in a
+        // way that won't trigger overflow checks.
         for pos in &mut file_local_lines {
-            *pos = *pos + start_pos;
+            *pos = (*pos - original_start_pos) + start_pos;
         }
-
         for mbc in &mut file_local_multibyte_chars {
-            mbc.pos = mbc.pos + start_pos;
+            mbc.pos = (mbc.pos - original_start_pos) + start_pos;
         }
-
         for swc in &mut file_local_non_narrow_chars {
-            *swc = *swc + start_pos;
+            *swc = (*swc - original_start_pos) + start_pos;
         }
-
         for nc in &mut file_local_normalized_pos {
-            nc.pos = nc.pos + start_pos;
+            nc.pos = (nc.pos - original_start_pos) + start_pos;
         }
 
         let source_file = Lrc::new(SourceFile {