@@ -6,7 +6,7 @@ use crate::llvm;
6
6
7
7
use itertools:: Itertools as _;
8
8
use rustc_codegen_ssa:: traits:: { BaseTypeMethods , ConstMethods } ;
9
- use rustc_data_structures:: fx:: FxIndexSet ;
9
+ use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
10
10
use rustc_hir:: def:: DefKind ;
11
11
use rustc_hir:: def_id:: DefId ;
12
12
use rustc_index:: IndexVec ;
@@ -205,11 +205,15 @@ rustc_index::newtype_index! {
205
205
#[ derive( Default ) ]
206
206
struct VirtualFileMapping {
207
207
local_to_global : IndexVec < LocalFileId , u32 > ,
208
+ global_to_local : FxIndexMap < u32 , LocalFileId > ,
208
209
}
209
210
210
211
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) )
213
217
}
214
218
215
219
fn into_vec ( self ) -> Vec < u32 > {
@@ -226,7 +230,7 @@ fn encode_mappings_for_function(
226
230
global_file_table : & GlobalFileTable ,
227
231
function_coverage : & FunctionCoverage < ' _ > ,
228
232
) -> Vec < u8 > {
229
- let mut counter_regions = function_coverage. counter_regions ( ) . collect :: < Vec < _ > > ( ) ;
233
+ let counter_regions = function_coverage. counter_regions ( ) ;
230
234
if counter_regions. is_empty ( ) {
231
235
return Vec :: new ( ) ;
232
236
}
@@ -236,25 +240,23 @@ fn encode_mappings_for_function(
236
240
let mut virtual_file_mapping = VirtualFileMapping :: default ( ) ;
237
241
let mut mapping_regions = Vec :: with_capacity ( counter_regions. len ( ) ) ;
238
242
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`.
241
245
// Prepare file IDs for each filename, and prepare the mapping data so that
242
246
// 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 )
246
249
{
247
250
// Look up the global file ID for this filename.
248
- let file_name = counter_regions_for_file[ 0 ] . 1 . file_name ;
249
251
let global_file_id = global_file_table. global_file_id_for_file_name ( file_name) ;
250
252
251
253
// 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) ;
253
255
debug ! ( " file id: {local_file_id:?} => global {global_file_id} = '{file_name:?}'" ) ;
254
256
255
257
// For each counter/region pair in this function+file, convert it to a
256
258
// form suitable for FFI.
257
- for & ( counter, region) in counter_regions_for_file {
259
+ for ( counter, region) in counter_regions_for_file {
258
260
let CodeRegion { file_name : _, start_line, start_col, end_line, end_col } = * region;
259
261
260
262
debug ! ( "Adding counter {counter:?} to map for {region:?}" ) ;
0 commit comments