@@ -29,7 +29,10 @@ pub(crate) struct CovfunRecord<'tcx> {
29
29
mangled_function_name : & ' tcx str ,
30
30
source_hash : u64 ,
31
31
is_used : bool ,
32
- coverage_mapping_buffer : Vec < u8 > ,
32
+
33
+ virtual_file_mapping : VirtualFileMapping ,
34
+ expressions : Vec < ffi:: CounterExpression > ,
35
+ regions : ffi:: Regions ,
33
36
}
34
37
35
38
impl < ' tcx > CovfunRecord < ' tcx > {
@@ -46,61 +49,54 @@ pub(crate) fn prepare_covfun_record<'tcx>(
46
49
instance : Instance < ' tcx > ,
47
50
function_coverage : & FunctionCoverage < ' tcx > ,
48
51
) -> 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:?}" ) ;
62
66
} else {
63
- debug ! ( "unused function had no coverage mapping data: {}" , mangled_function_name ) ;
67
+ debug ! ( ?covfun , "unused function had no coverage mapping data" ) ;
64
68
return None ;
65
69
}
66
70
}
67
71
68
- Some ( CovfunRecord { mangled_function_name , source_hash , is_used , coverage_mapping_buffer } )
72
+ Some ( covfun )
69
73
}
70
74
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 > ,
78
78
global_file_table : & GlobalFileTable ,
79
- function_coverage : & FunctionCoverage < ' _ > ,
80
- ) -> Vec < u8 > {
79
+ function_coverage : & FunctionCoverage < ' tcx > ,
80
+ covfun : & mut CovfunRecord < ' tcx > ,
81
+ ) {
81
82
let counter_regions = function_coverage. counter_regions ( ) ;
82
83
if counter_regions. is_empty ( ) {
83
- return Vec :: new ( ) ;
84
+ return ;
84
85
}
85
86
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
-
94
87
// Currently a function's mappings must all be in the same file as its body span.
95
88
let file_name = span_file_name ( tcx, function_coverage. function_coverage_info . body_span ) ;
96
89
97
90
// Look up the global file ID for that filename.
98
91
let global_file_id = global_file_table. global_file_id_for_file_name ( file_name) ;
99
92
100
93
// 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) ;
102
95
debug ! ( " file id: {local_file_id:?} => {global_file_id:?} = '{file_name:?}'" ) ;
103
96
97
+ let ffi:: Regions { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } =
98
+ & mut covfun. regions ;
99
+
104
100
// For each counter/region pair in this function+file, convert it to a
105
101
// form suitable for FFI.
106
102
for ( mapping_kind, region) in counter_regions {
@@ -133,16 +129,6 @@ fn encode_mappings_for_function(
133
129
}
134
130
}
135
131
}
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
- )
146
132
}
147
133
148
134
/// Generates the contents of the covfun record for this function, which
@@ -157,9 +143,18 @@ pub(crate) fn generate_covfun_record<'tcx>(
157
143
mangled_function_name,
158
144
source_hash,
159
145
is_used,
160
- ref coverage_mapping_buffer, // Previously-encoded coverage mappings
146
+ ref virtual_file_mapping,
147
+ ref expressions,
148
+ ref regions,
161
149
} = covfun;
162
150
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
+
163
158
// Concatenate the encoded coverage mappings
164
159
let coverage_mapping_size = coverage_mapping_buffer. len ( ) ;
165
160
let coverage_mapping_val = cx. const_bytes ( & coverage_mapping_buffer) ;
0 commit comments