@@ -7,13 +7,9 @@ mod spans;
7
7
#[ cfg( test) ]
8
8
mod tests;
9
9
10
- use self :: counters:: { CounterIncrementSite , CoverageCounters } ;
11
- use self :: graph:: { BasicCoverageBlock , CoverageGraph } ;
12
- use self :: mappings:: CoverageSpans ;
13
-
14
- use crate :: MirPass ;
15
-
16
- use rustc_middle:: mir:: coverage:: * ;
10
+ use rustc_middle:: mir:: coverage:: {
11
+ CodeRegion , CoverageKind , DecisionInfo , FunctionCoverageInfo , Mapping , MappingKind ,
12
+ } ;
17
13
use rustc_middle:: mir:: {
18
14
self , BasicBlock , BasicBlockData , SourceInfo , Statement , StatementKind , Terminator ,
19
15
TerminatorKind ,
@@ -23,6 +19,11 @@ use rustc_span::def_id::LocalDefId;
23
19
use rustc_span:: source_map:: SourceMap ;
24
20
use rustc_span:: { BytePos , Pos , RelativeBytePos , Span , Symbol } ;
25
21
22
+ use crate :: coverage:: counters:: { CounterIncrementSite , CoverageCounters } ;
23
+ use crate :: coverage:: graph:: { BasicCoverageBlock , CoverageGraph } ;
24
+ use crate :: coverage:: mappings:: ExtractedMappings ;
25
+ use crate :: MirPass ;
26
+
26
27
/// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected
27
28
/// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen
28
29
/// to construct the coverage map.
@@ -69,24 +70,27 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
69
70
let basic_coverage_blocks = CoverageGraph :: from_mir ( mir_body) ;
70
71
71
72
////////////////////////////////////////////////////
72
- // Compute coverage spans from the `CoverageGraph`.
73
- let Some ( coverage_spans) =
74
- mappings:: generate_coverage_spans ( mir_body, & hir_info, & basic_coverage_blocks)
75
- else {
76
- // No relevant spans were found in MIR, so skip instrumenting this function.
77
- return ;
78
- } ;
73
+ // Extract coverage spans and other mapping info from MIR.
74
+ let extracted_mappings =
75
+ mappings:: extract_all_mapping_info_from_mir ( mir_body, & hir_info, & basic_coverage_blocks) ;
79
76
80
77
////////////////////////////////////////////////////
81
78
// Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure
82
79
// every coverage span has a `Counter` or `Expression` assigned to its `BasicCoverageBlock`
83
80
// and all `Expression` dependencies (operands) are also generated, for any other
84
81
// `BasicCoverageBlock`s not already associated with a coverage span.
85
- let bcb_has_coverage_spans = |bcb| coverage_spans. bcb_has_coverage_spans ( bcb) ;
82
+ let bcbs_with_counter_mappings =
83
+ extracted_mappings. all_bcbs_with_counter_mappings ( & basic_coverage_blocks) ;
84
+ if bcbs_with_counter_mappings. is_empty ( ) {
85
+ // No relevant spans were found in MIR, so skip instrumenting this function.
86
+ return ;
87
+ }
88
+
89
+ let bcb_has_counter_mappings = |bcb| bcbs_with_counter_mappings. contains ( bcb) ;
86
90
let coverage_counters =
87
- CoverageCounters :: make_bcb_counters ( & basic_coverage_blocks, bcb_has_coverage_spans ) ;
91
+ CoverageCounters :: make_bcb_counters ( & basic_coverage_blocks, bcb_has_counter_mappings ) ;
88
92
89
- let mappings = create_mappings ( tcx, & hir_info, & coverage_spans , & coverage_counters) ;
93
+ let mappings = create_mappings ( tcx, & hir_info, & extracted_mappings , & coverage_counters) ;
90
94
if mappings. is_empty ( ) {
91
95
// No spans could be converted into valid mappings, so skip this function.
92
96
debug ! ( "no spans could be converted into valid mappings; skipping" ) ;
@@ -96,13 +100,13 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
96
100
inject_coverage_statements (
97
101
mir_body,
98
102
& basic_coverage_blocks,
99
- bcb_has_coverage_spans ,
103
+ bcb_has_counter_mappings ,
100
104
& coverage_counters,
101
105
) ;
102
106
103
- inject_mcdc_statements ( mir_body, & basic_coverage_blocks, & coverage_spans ) ;
107
+ inject_mcdc_statements ( mir_body, & basic_coverage_blocks, & extracted_mappings ) ;
104
108
105
- let mcdc_num_condition_bitmaps = coverage_spans
109
+ let mcdc_num_condition_bitmaps = extracted_mappings
106
110
. mcdc_decisions
107
111
. iter ( )
108
112
. map ( |& mappings:: MCDCDecision { decision_depth, .. } | decision_depth)
@@ -112,7 +116,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
112
116
mir_body. function_coverage_info = Some ( Box :: new ( FunctionCoverageInfo {
113
117
function_source_hash : hir_info. function_source_hash ,
114
118
num_counters : coverage_counters. num_counters ( ) ,
115
- mcdc_bitmap_bytes : coverage_spans . test_vector_bitmap_bytes ( ) ,
119
+ mcdc_bitmap_bytes : extracted_mappings . mcdc_bitmap_bytes ,
116
120
expressions : coverage_counters. into_expressions ( ) ,
117
121
mappings,
118
122
mcdc_num_condition_bitmaps,
@@ -127,7 +131,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
127
131
fn create_mappings < ' tcx > (
128
132
tcx : TyCtxt < ' tcx > ,
129
133
hir_info : & ExtractedHirInfo ,
130
- coverage_spans : & CoverageSpans ,
134
+ extracted_mappings : & ExtractedMappings ,
131
135
coverage_counters : & CoverageCounters ,
132
136
) -> Vec < Mapping > {
133
137
let source_map = tcx. sess . source_map ( ) ;
@@ -148,17 +152,26 @@ fn create_mappings<'tcx>(
148
152
} ;
149
153
let region_for_span = |span : Span | make_code_region ( source_map, file_name, span, body_span) ;
150
154
155
+ // Fully destructure the mappings struct to make sure we don't miss any kinds.
156
+ let ExtractedMappings {
157
+ code_mappings,
158
+ branch_pairs,
159
+ mcdc_bitmap_bytes : _,
160
+ mcdc_branches,
161
+ mcdc_decisions,
162
+ } = extracted_mappings;
151
163
let mut mappings = Vec :: new ( ) ;
152
164
153
- mappings. extend ( coverage_spans. code_mappings . iter ( ) . filter_map (
165
+ mappings. extend ( code_mappings. iter ( ) . filter_map (
166
+ // Ordinary code mappings are the simplest kind.
154
167
|& mappings:: CodeMapping { span, bcb } | {
155
168
let code_region = region_for_span ( span) ?;
156
169
let kind = MappingKind :: Code ( term_for_bcb ( bcb) ) ;
157
170
Some ( Mapping { kind, code_region } )
158
171
} ,
159
172
) ) ;
160
173
161
- mappings. extend ( coverage_spans . branch_pairs . iter ( ) . filter_map (
174
+ mappings. extend ( branch_pairs. iter ( ) . filter_map (
162
175
|& mappings:: BranchPair { span, true_bcb, false_bcb } | {
163
176
let true_term = term_for_bcb ( true_bcb) ;
164
177
let false_term = term_for_bcb ( false_bcb) ;
@@ -168,7 +181,7 @@ fn create_mappings<'tcx>(
168
181
} ,
169
182
) ) ;
170
183
171
- mappings. extend ( coverage_spans . mcdc_branches . iter ( ) . filter_map (
184
+ mappings. extend ( mcdc_branches. iter ( ) . filter_map (
172
185
|& mappings:: MCDCBranch { span, true_bcb, false_bcb, condition_info, decision_depth : _ } | {
173
186
let code_region = region_for_span ( span) ?;
174
187
let true_term = term_for_bcb ( true_bcb) ;
@@ -181,7 +194,7 @@ fn create_mappings<'tcx>(
181
194
} ,
182
195
) ) ;
183
196
184
- mappings. extend ( coverage_spans . mcdc_decisions . iter ( ) . filter_map (
197
+ mappings. extend ( mcdc_decisions. iter ( ) . filter_map (
185
198
|& mappings:: MCDCDecision { span, bitmap_idx, conditions_num, .. } | {
186
199
let code_region = region_for_span ( span) ?;
187
200
let kind = MappingKind :: MCDCDecision ( DecisionInfo { bitmap_idx, conditions_num } ) ;
@@ -249,20 +262,16 @@ fn inject_coverage_statements<'tcx>(
249
262
fn inject_mcdc_statements < ' tcx > (
250
263
mir_body : & mut mir:: Body < ' tcx > ,
251
264
basic_coverage_blocks : & CoverageGraph ,
252
- coverage_spans : & CoverageSpans ,
265
+ extracted_mappings : & ExtractedMappings ,
253
266
) {
254
- if coverage_spans. test_vector_bitmap_bytes ( ) == 0 {
255
- return ;
256
- }
257
-
258
267
// Inject test vector update first because `inject_statement` always insert new statement at head.
259
268
for & mappings:: MCDCDecision {
260
269
span : _,
261
270
ref end_bcbs,
262
271
bitmap_idx,
263
272
conditions_num : _,
264
273
decision_depth,
265
- } in & coverage_spans . mcdc_decisions
274
+ } in & extracted_mappings . mcdc_decisions
266
275
{
267
276
for end in end_bcbs {
268
277
let end_bb = basic_coverage_blocks[ * end] . leader_bb ( ) ;
@@ -275,7 +284,7 @@ fn inject_mcdc_statements<'tcx>(
275
284
}
276
285
277
286
for & mappings:: MCDCBranch { span : _, true_bcb, false_bcb, condition_info, decision_depth } in
278
- & coverage_spans . mcdc_branches
287
+ & extracted_mappings . mcdc_branches
279
288
{
280
289
let Some ( condition_info) = condition_info else { continue } ;
281
290
let id = condition_info. condition_id ;
0 commit comments