@@ -8,6 +8,7 @@ use rustc_codegen_ssa::traits::ConstMethods;
8
8
use rustc_data_structures:: fx:: FxIndexSet ;
9
9
use rustc_hir:: def:: DefKind ;
10
10
use rustc_hir:: def_id:: DefId ;
11
+ use rustc_index:: IndexVec ;
11
12
use rustc_middle:: bug;
12
13
use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
13
14
use rustc_middle:: mir:: coverage:: CodeRegion ;
@@ -163,34 +164,33 @@ fn encode_mappings_for_function(
163
164
return Vec :: new ( ) ;
164
165
}
165
166
166
- let mut virtual_file_mapping = Vec :: new ( ) ;
167
+ let mut virtual_file_mapping = IndexVec :: < u32 , u32 > :: new ( ) ;
167
168
let mut mapping_regions = Vec :: with_capacity ( counter_regions. len ( ) ) ;
168
- let mut current_file_name = None ;
169
- let mut current_file_id = 0 ;
170
-
171
- // Convert the list of (Counter, CodeRegion) pairs to an array of `CounterMappingRegion`, sorted
172
- // by filename and position. Capture any new files to compute the `CounterMappingRegion`s
173
- // `file_id` (indexing files referenced by the current function), and construct the
174
- // function-specific `virtual_file_mapping` from `file_id` to its index in the module's
175
- // `filenames` array.
169
+
170
+ // Sort the list of (counter, region) mapping pairs by region, so that they
171
+ // can be grouped by filename. Prepare file IDs for each filename, and
172
+ // prepare the mapping data so that we can pass it through FFI to LLVM.
176
173
counter_regions. sort_by_key ( |( _counter, region) | * region) ;
177
- for ( counter, region) in counter_regions {
178
- let CodeRegion { file_name, start_line, start_col, end_line, end_col } = * region;
179
- let same_file = current_file_name. is_some_and ( |p| p == file_name) ;
180
- if !same_file {
181
- if current_file_name. is_some ( ) {
182
- current_file_id += 1 ;
183
- }
184
- current_file_name = Some ( file_name) ;
185
- debug ! ( " file_id: {} = '{:?}'" , current_file_id, file_name) ;
186
- let global_file_id = global_file_table. global_file_id_for_file_name ( file_name) ;
187
- virtual_file_mapping. push ( global_file_id) ;
188
- }
189
- {
190
- debug ! ( "Adding counter {:?} to map for {:?}" , counter, region) ;
174
+ for counter_regions_for_file in
175
+ counter_regions. group_by ( |( _, a) , ( _, b) | a. file_name == b. file_name )
176
+ {
177
+ // Look up (or allocate) the global file ID for this filename.
178
+ let file_name = counter_regions_for_file[ 0 ] . 1 . file_name ;
179
+ let global_file_id = global_file_table. global_file_id_for_file_name ( file_name) ;
180
+
181
+ // Associate that global file ID with a local file ID for this function.
182
+ let local_file_id: u32 = virtual_file_mapping. push ( global_file_id) ;
183
+ debug ! ( " file id: local {local_file_id} => global {global_file_id} = '{file_name:?}'" ) ;
184
+
185
+ // For each counter/region pair in this function+file, convert it to a
186
+ // form suitable for FFI.
187
+ for & ( counter, region) in counter_regions_for_file {
188
+ let CodeRegion { file_name : _, start_line, start_col, end_line, end_col } = * region;
189
+
190
+ debug ! ( "Adding counter {counter:?} to map for {region:?}" ) ;
191
191
mapping_regions. push ( CounterMappingRegion :: code_region (
192
192
counter,
193
- current_file_id ,
193
+ local_file_id ,
194
194
start_line,
195
195
start_col,
196
196
end_line,
@@ -202,7 +202,7 @@ fn encode_mappings_for_function(
202
202
// Encode the function's coverage mappings into a buffer.
203
203
llvm:: build_byte_buffer ( |buffer| {
204
204
coverageinfo:: write_mapping_to_buffer (
205
- virtual_file_mapping,
205
+ virtual_file_mapping. raw ,
206
206
expressions,
207
207
mapping_regions,
208
208
buffer,
0 commit comments