Skip to content

Commit de4cfbc

Browse files
committed
coverage: Encode function mappings without re-sorting them
The main change here is that `VirtualFileMapping` now uses an internal hashmap to de-duplicate incoming global file IDs. That removes the need for `encode_mappings_for_function` to re-sort its mappings by filename in order to de-duplicate them. (We still de-duplicate runs of identical filenames to save work, but this is not load-bearing for correctness, so a sort is not necessary.)
1 parent 88159ca commit de4cfbc

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::llvm;
66

77
use itertools::Itertools as _;
88
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods};
9-
use rustc_data_structures::fx::FxIndexSet;
9+
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
1010
use rustc_hir::def::DefKind;
1111
use rustc_hir::def_id::DefId;
1212
use rustc_index::IndexVec;
@@ -205,11 +205,15 @@ rustc_index::newtype_index! {
205205
#[derive(Default)]
206206
struct VirtualFileMapping {
207207
local_to_global: IndexVec<LocalFileId, u32>,
208+
global_to_local: FxIndexMap<u32, LocalFileId>,
208209
}
209210

210211
impl VirtualFileMapping {
211-
fn push_global_id(&mut self, global_file_id: u32) -> LocalFileId {
212-
self.local_to_global.push(global_file_id)
212+
fn local_id_for_global(&mut self, global_file_id: u32) -> LocalFileId {
213+
*self
214+
.global_to_local
215+
.entry(global_file_id)
216+
.or_insert_with(|| self.local_to_global.push(global_file_id))
213217
}
214218

215219
fn into_vec(self) -> Vec<u32> {
@@ -226,7 +230,7 @@ fn encode_mappings_for_function(
226230
global_file_table: &GlobalFileTable,
227231
function_coverage: &FunctionCoverage<'_>,
228232
) -> Vec<u8> {
229-
let mut counter_regions = function_coverage.counter_regions().collect::<Vec<_>>();
233+
let counter_regions = function_coverage.counter_regions();
230234
if counter_regions.is_empty() {
231235
return Vec::new();
232236
}
@@ -236,25 +240,23 @@ fn encode_mappings_for_function(
236240
let mut virtual_file_mapping = VirtualFileMapping::default();
237241
let mut mapping_regions = Vec::with_capacity(counter_regions.len());
238242

239-
// Sort and group the list of (counter, region) mapping pairs by filename.
240-
// (Preserve any further ordering imposed by `FunctionCoverage`.)
243+
// Group mappings into runs with the same filename, preserving the order
244+
// yielded by `FunctionCoverage`.
241245
// Prepare file IDs for each filename, and prepare the mapping data so that
242246
// we can pass it through FFI to LLVM.
243-
counter_regions.sort_by_key(|(_counter, region)| region.file_name);
244-
for counter_regions_for_file in
245-
counter_regions.group_by(|(_, a), (_, b)| a.file_name == b.file_name)
247+
for (file_name, counter_regions_for_file) in
248+
&counter_regions.group_by(|(_counter, region)| region.file_name)
246249
{
247250
// Look up the global file ID for this filename.
248-
let file_name = counter_regions_for_file[0].1.file_name;
249251
let global_file_id = global_file_table.global_file_id_for_file_name(file_name);
250252

251253
// Associate that global file ID with a local file ID for this function.
252-
let local_file_id = virtual_file_mapping.push_global_id(global_file_id);
254+
let local_file_id = virtual_file_mapping.local_id_for_global(global_file_id);
253255
debug!(" file id: {local_file_id:?} => global {global_file_id} = '{file_name:?}'");
254256

255257
// For each counter/region pair in this function+file, convert it to a
256258
// form suitable for FFI.
257-
for &(counter, region) in counter_regions_for_file {
259+
for (counter, region) in counter_regions_for_file {
258260
let CodeRegion { file_name: _, start_line, start_col, end_line, end_col } = *region;
259261

260262
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)