Skip to content

Commit 68b8610

Browse files
committed
coverage: Encode function mappings without re-sorting them
1 parent c5d04d5 commit 68b8610

File tree

2 files changed

+14
-12
lines changed

2 files changed

+14
-12
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,15 @@ rustc_index::newtype_index! {
219219
#[derive(Default)]
220220
struct VirtualFileMapping {
221221
local_to_global: IndexVec<LocalFileId, u32>,
222+
global_to_local: FxIndexMap<u32, LocalFileId>,
222223
}
223224

224225
impl VirtualFileMapping {
225-
fn push_global_id(&mut self, global_file_id: u32) -> LocalFileId {
226-
self.local_to_global.push(global_file_id)
226+
fn local_id_for_global(&mut self, global_file_id: u32) -> LocalFileId {
227+
*self
228+
.global_to_local
229+
.entry(global_file_id)
230+
.or_insert_with(|| self.local_to_global.push(global_file_id))
227231
}
228232

229233
fn into_vec(self) -> Vec<u32> {
@@ -240,7 +244,7 @@ fn encode_mappings_for_function(
240244
global_file_table: &GlobalFileTable,
241245
function_coverage: &FunctionCoverage<'_>,
242246
) -> Vec<u8> {
243-
let mut counter_regions = function_coverage.counter_regions().collect::<Vec<_>>();
247+
let counter_regions = function_coverage.counter_regions();
244248
if counter_regions.is_empty() {
245249
return Vec::new();
246250
}
@@ -250,25 +254,23 @@ fn encode_mappings_for_function(
250254
let mut virtual_file_mapping = VirtualFileMapping::default();
251255
let mut mapping_regions = Vec::with_capacity(counter_regions.len());
252256

253-
// Sort and group the list of (counter, region) mapping pairs by filename.
254-
// (Preserve any further ordering imposed by `FunctionCoverage`.)
257+
// Group mappings into runs with the same filename, preserving the order
258+
// yielded by `FunctionCoverage`.
255259
// Prepare file IDs for each filename, and prepare the mapping data so that
256260
// we can pass it through FFI to LLVM.
257-
counter_regions.sort_by_key(|(_counter, region)| region.file_name);
258-
for counter_regions_for_file in
259-
counter_regions.group_by(|(_, a), (_, b)| a.file_name == b.file_name)
261+
for (file_name, counter_regions_for_file) in
262+
&counter_regions.group_by(|(_counter, region)| region.file_name)
260263
{
261264
// Look up the global file ID for this filename.
262-
let file_name = counter_regions_for_file[0].1.file_name;
263265
let global_file_id = global_file_table.global_file_id_for_file_name(file_name);
264266

265267
// Associate that global file ID with a local file ID for this function.
266-
let local_file_id = virtual_file_mapping.push_global_id(global_file_id);
268+
let local_file_id = virtual_file_mapping.local_id_for_global(global_file_id);
267269
debug!(" file id: {local_file_id:?} => global {global_file_id} = '{file_name:?}'");
268270

269271
// For each counter/region pair in this function+file, convert it to a
270272
// form suitable for FFI.
271-
for &(counter, region) in counter_regions_for_file {
273+
for (counter, region) in counter_regions_for_file {
272274
let CodeRegion { file_name: _, start_line, start_col, end_line, end_col } = *region;
273275

274276
debug!("Adding counter {counter:?} to map for {region:?}");

compiler/rustc_codegen_llvm/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
99
#![cfg_attr(not(bootstrap), doc(rust_logo))]
1010
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
11+
#![feature(exact_size_is_empty)]
1112
#![feature(extern_types)]
1213
#![feature(hash_raw_entry)]
1314
#![feature(iter_intersperse)]
1415
#![feature(let_chains)]
1516
#![feature(min_specialization)]
1617
#![feature(never_type)]
17-
#![feature(slice_group_by)]
1818
#![feature(impl_trait_in_assoc_type)]
1919
#![recursion_limit = "256"]
2020
#![allow(rustc::potential_query_instability)]

0 commit comments

Comments
 (0)