@@ -29,7 +29,10 @@ pub(crate) struct CovfunRecord<'tcx> {
2929 mangled_function_name : & ' tcx str ,
3030 source_hash : u64 ,
3131 is_used : bool ,
32- coverage_mapping_buffer : Vec < u8 > ,
32+
33+ virtual_file_mapping : VirtualFileMapping ,
34+ expressions : Vec < ffi:: CounterExpression > ,
35+ regions : ffi:: Regions ,
3336}
3437
3538impl < ' tcx > CovfunRecord < ' tcx > {
@@ -46,61 +49,54 @@ pub(crate) fn prepare_covfun_record<'tcx>(
4649 instance : Instance < ' tcx > ,
4750 function_coverage : & FunctionCoverage < ' tcx > ,
4851) -> Option < CovfunRecord < ' tcx > > {
49- let mangled_function_name = tcx. symbol_name ( instance) . name ;
50- let source_hash = function_coverage. source_hash ( ) ;
51- let is_used = function_coverage. is_used ( ) ;
52-
53- let coverage_mapping_buffer =
54- encode_mappings_for_function ( tcx, global_file_table, function_coverage) ;
55-
56- if coverage_mapping_buffer. is_empty ( ) {
57- if function_coverage. is_used ( ) {
58- bug ! (
59- "A used function should have had coverage mapping data but did not: {}" ,
60- mangled_function_name
61- ) ;
52+ let mut covfun = CovfunRecord {
53+ mangled_function_name : tcx. symbol_name ( instance) . name ,
54+ source_hash : function_coverage. source_hash ( ) ,
55+ is_used : function_coverage. is_used ( ) ,
56+ virtual_file_mapping : VirtualFileMapping :: default ( ) ,
57+ expressions : function_coverage. counter_expressions ( ) . collect :: < Vec < _ > > ( ) ,
58+ regions : ffi:: Regions :: default ( ) ,
59+ } ;
60+
61+ fill_region_tables ( tcx, global_file_table, function_coverage, & mut covfun) ;
62+
63+ if covfun. regions . has_no_regions ( ) {
64+ if covfun. is_used {
65+ bug ! ( "a used function should have had coverage mapping data but did not: {covfun:?}" ) ;
6266 } else {
63- debug ! ( "unused function had no coverage mapping data: {}" , mangled_function_name ) ;
67+ debug ! ( ?covfun , "unused function had no coverage mapping data" ) ;
6468 return None ;
6569 }
6670 }
6771
68- Some ( CovfunRecord { mangled_function_name , source_hash , is_used , coverage_mapping_buffer } )
72+ Some ( covfun )
6973}
7074
71- /// Using the expressions and counter regions collected for a single function,
72- /// generate the variable-sized payload of its corresponding `__llvm_covfun`
73- /// entry. The payload is returned as a vector of bytes.
74- ///
75- /// Newly-encountered filenames will be added to the global file table.
76- fn encode_mappings_for_function (
77- tcx : TyCtxt < ' _ > ,
75+ /// Populates the mapping region tables in the current function's covfun record.
76+ fn fill_region_tables < ' tcx > (
77+ tcx : TyCtxt < ' tcx > ,
7878 global_file_table : & GlobalFileTable ,
79- function_coverage : & FunctionCoverage < ' _ > ,
80- ) -> Vec < u8 > {
79+ function_coverage : & FunctionCoverage < ' tcx > ,
80+ covfun : & mut CovfunRecord < ' tcx > ,
81+ ) {
8182 let counter_regions = function_coverage. counter_regions ( ) ;
8283 if counter_regions. is_empty ( ) {
83- return Vec :: new ( ) ;
84+ return ;
8485 }
8586
86- let expressions = function_coverage. counter_expressions ( ) . collect :: < Vec < _ > > ( ) ;
87-
88- let mut virtual_file_mapping = VirtualFileMapping :: default ( ) ;
89- let mut code_regions = vec ! [ ] ;
90- let mut branch_regions = vec ! [ ] ;
91- let mut mcdc_branch_regions = vec ! [ ] ;
92- let mut mcdc_decision_regions = vec ! [ ] ;
93-
9487 // Currently a function's mappings must all be in the same file as its body span.
9588 let file_name = span_file_name ( tcx, function_coverage. function_coverage_info . body_span ) ;
9689
9790 // Look up the global file ID for that filename.
9891 let global_file_id = global_file_table. global_file_id_for_file_name ( file_name) ;
9992
10093 // Associate that global file ID with a local file ID for this function.
101- let local_file_id = virtual_file_mapping. local_id_for_global ( global_file_id) ;
94+ let local_file_id = covfun . virtual_file_mapping . local_id_for_global ( global_file_id) ;
10295 debug ! ( " file id: {local_file_id:?} => {global_file_id:?} = '{file_name:?}'" ) ;
10396
97+ let ffi:: Regions { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } =
98+ & mut covfun. regions ;
99+
104100 // For each counter/region pair in this function+file, convert it to a
105101 // form suitable for FFI.
106102 for ( mapping_kind, region) in counter_regions {
@@ -133,16 +129,6 @@ fn encode_mappings_for_function(
133129 }
134130 }
135131 }
136-
137- // Encode the function's coverage mappings into a buffer.
138- llvm_cov:: write_function_mappings_to_buffer (
139- & virtual_file_mapping. into_vec ( ) ,
140- & expressions,
141- & code_regions,
142- & branch_regions,
143- & mcdc_branch_regions,
144- & mcdc_decision_regions,
145- )
146132}
147133
148134/// Generates the contents of the covfun record for this function, which
@@ -157,9 +143,18 @@ pub(crate) fn generate_covfun_record<'tcx>(
157143 mangled_function_name,
158144 source_hash,
159145 is_used,
160- ref coverage_mapping_buffer, // Previously-encoded coverage mappings
146+ ref virtual_file_mapping,
147+ ref expressions,
148+ ref regions,
161149 } = covfun;
162150
151+ // Encode the function's coverage mappings into a buffer.
152+ let coverage_mapping_buffer = llvm_cov:: write_function_mappings_to_buffer (
153+ & virtual_file_mapping. to_vec ( ) ,
154+ expressions,
155+ regions,
156+ ) ;
157+
163158 // Concatenate the encoded coverage mappings
164159 let coverage_mapping_size = coverage_mapping_buffer. len ( ) ;
165160 let coverage_mapping_val = cx. const_bytes ( & coverage_mapping_buffer) ;
0 commit comments