@@ -6,7 +6,7 @@ use crate::llvm;
66
77use  itertools:: Itertools  as  _; 
88use  rustc_codegen_ssa:: traits:: { BaseTypeMethods ,  ConstMethods } ; 
9- use  rustc_data_structures:: fx:: FxIndexSet ; 
9+ use  rustc_data_structures:: fx:: { FxIndexMap ,   FxIndexSet } ; 
1010use  rustc_hir:: def:: DefKind ; 
1111use  rustc_hir:: def_id:: DefId ; 
1212use  rustc_index:: IndexVec ; 
@@ -205,11 +205,15 @@ rustc_index::newtype_index! {
205205#[ derive( Default ) ]  
206206struct  VirtualFileMapping  { 
207207    local_to_global :  IndexVec < LocalFileId ,  u32 > , 
208+     global_to_local :  FxIndexMap < u32 ,  LocalFileId > , 
208209} 
209210
210211impl  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:?}" ) ; 
0 commit comments