@@ -59,167 +59,154 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
59
59
_ => { }
60
60
}
61
61
62
- trace ! ( "InstrumentCoverage starting for {def_id:?}" ) ;
63
- Instrumentor :: new ( tcx, mir_body) . inject_counters ( ) ;
64
- trace ! ( "InstrumentCoverage done for {def_id:?}" ) ;
62
+ instrument_function_for_coverage ( tcx, mir_body) ;
65
63
}
66
64
}
67
65
68
- struct Instrumentor < ' a , ' tcx > {
69
- tcx : TyCtxt < ' tcx > ,
70
- mir_body : & ' a mut mir:: Body < ' tcx > ,
71
- hir_info : ExtractedHirInfo ,
72
- basic_coverage_blocks : CoverageGraph ,
73
- }
74
-
75
- impl < ' a , ' tcx > Instrumentor < ' a , ' tcx > {
76
- fn new ( tcx : TyCtxt < ' tcx > , mir_body : & ' a mut mir:: Body < ' tcx > ) -> Self {
77
- let hir_info = extract_hir_info ( tcx, mir_body. source . def_id ( ) . expect_local ( ) ) ;
66
+ fn instrument_function_for_coverage < ' tcx > ( tcx : TyCtxt < ' tcx > , mir_body : & mut mir:: Body < ' tcx > ) {
67
+ let def_id = mir_body. source . def_id ( ) ;
68
+ let _span = debug_span ! ( "instrument_function_for_coverage" , ?def_id) . entered ( ) ;
78
69
79
- debug ! ( ?hir_info, "instrumenting {:?}" , mir_body. source. def_id( ) ) ;
70
+ let hir_info = extract_hir_info ( tcx, def_id. expect_local ( ) ) ;
71
+ let basic_coverage_blocks = CoverageGraph :: from_mir ( mir_body) ;
80
72
81
- let basic_coverage_blocks = CoverageGraph :: from_mir ( mir_body) ;
73
+ ////////////////////////////////////////////////////
74
+ // Compute coverage spans from the `CoverageGraph`.
75
+ let Some ( coverage_spans) =
76
+ spans:: generate_coverage_spans ( mir_body, & hir_info, & basic_coverage_blocks)
77
+ else {
78
+ // No relevant spans were found in MIR, so skip instrumenting this function.
79
+ return ;
80
+ } ;
82
81
83
- Self { tcx, mir_body, hir_info, basic_coverage_blocks }
82
+ ////////////////////////////////////////////////////
83
+ // Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure
84
+ // every coverage span has a `Counter` or `Expression` assigned to its `BasicCoverageBlock`
85
+ // and all `Expression` dependencies (operands) are also generated, for any other
86
+ // `BasicCoverageBlock`s not already associated with a coverage span.
87
+ let bcb_has_coverage_spans = |bcb| coverage_spans. bcb_has_coverage_spans ( bcb) ;
88
+ let coverage_counters =
89
+ CoverageCounters :: make_bcb_counters ( & basic_coverage_blocks, bcb_has_coverage_spans) ;
90
+
91
+ let mappings = create_mappings ( tcx, & hir_info, & coverage_spans, & coverage_counters) ;
92
+ if mappings. is_empty ( ) {
93
+ // No spans could be converted into valid mappings, so skip this function.
94
+ debug ! ( "no spans could be converted into valid mappings; skipping" ) ;
95
+ return ;
84
96
}
85
97
86
- fn inject_counters ( & ' a mut self ) {
87
- ////////////////////////////////////////////////////
88
- // Compute coverage spans from the `CoverageGraph`.
89
- let Some ( coverage_spans) = CoverageSpans :: generate_coverage_spans (
90
- self . mir_body ,
91
- & self . hir_info ,
92
- & self . basic_coverage_blocks ,
93
- ) else {
94
- // No relevant spans were found in MIR, so skip instrumenting this function.
95
- return ;
96
- } ;
97
-
98
- ////////////////////////////////////////////////////
99
- // Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure
100
- // every coverage span has a `Counter` or `Expression` assigned to its `BasicCoverageBlock`
101
- // and all `Expression` dependencies (operands) are also generated, for any other
102
- // `BasicCoverageBlock`s not already associated with a coverage span.
103
- let bcb_has_coverage_spans = |bcb| coverage_spans. bcb_has_coverage_spans ( bcb) ;
104
- let coverage_counters = CoverageCounters :: make_bcb_counters (
105
- & self . basic_coverage_blocks ,
106
- bcb_has_coverage_spans,
107
- ) ;
98
+ inject_coverage_statements (
99
+ mir_body,
100
+ & basic_coverage_blocks,
101
+ bcb_has_coverage_spans,
102
+ & coverage_counters,
103
+ ) ;
108
104
109
- let mappings = self . create_mappings ( & coverage_spans, & coverage_counters) ;
110
- if mappings. is_empty ( ) {
111
- // No spans could be converted into valid mappings, so skip this function.
112
- debug ! ( "no spans could be converted into valid mappings; skipping" ) ;
113
- return ;
114
- }
105
+ mir_body. function_coverage_info = Some ( Box :: new ( FunctionCoverageInfo {
106
+ function_source_hash : hir_info. function_source_hash ,
107
+ num_counters : coverage_counters. num_counters ( ) ,
108
+ expressions : coverage_counters. into_expressions ( ) ,
109
+ mappings,
110
+ } ) ) ;
111
+ }
115
112
116
- self . inject_coverage_statements ( bcb_has_coverage_spans, & coverage_counters) ;
113
+ /// For each coverage span extracted from MIR, create a corresponding
114
+ /// mapping.
115
+ ///
116
+ /// Precondition: All BCBs corresponding to those spans have been given
117
+ /// coverage counters.
118
+ fn create_mappings < ' tcx > (
119
+ tcx : TyCtxt < ' tcx > ,
120
+ hir_info : & ExtractedHirInfo ,
121
+ coverage_spans : & CoverageSpans ,
122
+ coverage_counters : & CoverageCounters ,
123
+ ) -> Vec < Mapping > {
124
+ let source_map = tcx. sess . source_map ( ) ;
125
+ let body_span = hir_info. body_span ;
126
+
127
+ let source_file = source_map. lookup_source_file ( body_span. lo ( ) ) ;
128
+ use rustc_session:: RemapFileNameExt ;
129
+ let file_name = Symbol :: intern ( & source_file. name . for_codegen ( tcx. sess ) . to_string_lossy ( ) ) ;
130
+
131
+ let term_for_bcb = |bcb| {
132
+ coverage_counters
133
+ . bcb_counter ( bcb)
134
+ . expect ( "all BCBs with spans were given counters" )
135
+ . as_term ( )
136
+ } ;
117
137
118
- self . mir_body . function_coverage_info = Some ( Box :: new ( FunctionCoverageInfo {
119
- function_source_hash : self . hir_info . function_source_hash ,
120
- num_counters : coverage_counters. num_counters ( ) ,
121
- expressions : coverage_counters. into_expressions ( ) ,
122
- mappings,
123
- } ) ) ;
124
- }
138
+ coverage_spans
139
+ . all_bcb_mappings ( )
140
+ . filter_map ( |& BcbMapping { kind : bcb_mapping_kind, span } | {
141
+ let kind = match bcb_mapping_kind {
142
+ BcbMappingKind :: Code ( bcb) => MappingKind :: Code ( term_for_bcb ( bcb) ) ,
143
+ } ;
144
+ let code_region = make_code_region ( source_map, file_name, span, body_span) ?;
145
+ Some ( Mapping { kind, code_region } )
146
+ } )
147
+ . collect :: < Vec < _ > > ( )
148
+ }
125
149
126
- /// For each coverage span extracted from MIR, create a corresponding
127
- /// mapping.
128
- ///
129
- /// Precondition: All BCBs corresponding to those spans have been given
130
- /// coverage counters.
131
- fn create_mappings (
132
- & self ,
133
- coverage_spans : & CoverageSpans ,
134
- coverage_counters : & CoverageCounters ,
135
- ) -> Vec < Mapping > {
136
- let source_map = self . tcx . sess . source_map ( ) ;
137
- let body_span = self . hir_info . body_span ;
138
-
139
- let source_file = source_map. lookup_source_file ( body_span. lo ( ) ) ;
140
- use rustc_session:: RemapFileNameExt ;
141
- let file_name =
142
- Symbol :: intern ( & source_file. name . for_codegen ( self . tcx . sess ) . to_string_lossy ( ) ) ;
143
-
144
- let term_for_bcb = |bcb| {
145
- coverage_counters
146
- . bcb_counter ( bcb)
147
- . expect ( "all BCBs with spans were given counters" )
148
- . as_term ( )
150
+ /// For each BCB node or BCB edge that has an associated coverage counter,
151
+ /// inject any necessary coverage statements into MIR.
152
+ fn inject_coverage_statements < ' tcx > (
153
+ mir_body : & mut mir:: Body < ' tcx > ,
154
+ basic_coverage_blocks : & CoverageGraph ,
155
+ bcb_has_coverage_spans : impl Fn ( BasicCoverageBlock ) -> bool ,
156
+ coverage_counters : & CoverageCounters ,
157
+ ) {
158
+ // Process the counters associated with BCB nodes.
159
+ for ( bcb, counter_kind) in coverage_counters. bcb_node_counters ( ) {
160
+ let do_inject = match counter_kind {
161
+ // Counter-increment statements always need to be injected.
162
+ BcbCounter :: Counter { .. } => true ,
163
+ // The only purpose of expression-used statements is to detect
164
+ // when a mapping is unreachable, so we only inject them for
165
+ // expressions with one or more mappings.
166
+ BcbCounter :: Expression { .. } => bcb_has_coverage_spans ( bcb) ,
149
167
} ;
150
-
151
- coverage_spans
152
- . all_bcb_mappings ( )
153
- . filter_map ( |& BcbMapping { kind : bcb_mapping_kind, span } | {
154
- let kind = match bcb_mapping_kind {
155
- BcbMappingKind :: Code ( bcb) => MappingKind :: Code ( term_for_bcb ( bcb) ) ,
156
- } ;
157
- let code_region = make_code_region ( source_map, file_name, span, body_span) ?;
158
- Some ( Mapping { kind, code_region } )
159
- } )
160
- . collect :: < Vec < _ > > ( )
168
+ if do_inject {
169
+ inject_statement (
170
+ mir_body,
171
+ make_mir_coverage_kind ( counter_kind) ,
172
+ basic_coverage_blocks[ bcb] . leader_bb ( ) ,
173
+ ) ;
174
+ }
161
175
}
162
176
163
- /// For each BCB node or BCB edge that has an associated coverage counter,
164
- /// inject any necessary coverage statements into MIR.
165
- fn inject_coverage_statements (
166
- & mut self ,
167
- bcb_has_coverage_spans : impl Fn ( BasicCoverageBlock ) -> bool ,
168
- coverage_counters : & CoverageCounters ,
169
- ) {
170
- // Process the counters associated with BCB nodes.
171
- for ( bcb, counter_kind) in coverage_counters. bcb_node_counters ( ) {
172
- let do_inject = match counter_kind {
173
- // Counter-increment statements always need to be injected.
174
- BcbCounter :: Counter { .. } => true ,
175
- // The only purpose of expression-used statements is to detect
176
- // when a mapping is unreachable, so we only inject them for
177
- // expressions with one or more mappings.
178
- BcbCounter :: Expression { .. } => bcb_has_coverage_spans ( bcb) ,
179
- } ;
180
- if do_inject {
181
- inject_statement (
182
- self . mir_body ,
183
- self . make_mir_coverage_kind ( counter_kind) ,
184
- self . basic_coverage_blocks [ bcb] . leader_bb ( ) ,
185
- ) ;
186
- }
177
+ // Process the counters associated with BCB edges.
178
+ for ( from_bcb, to_bcb, counter_kind) in coverage_counters. bcb_edge_counters ( ) {
179
+ let do_inject = match counter_kind {
180
+ // Counter-increment statements always need to be injected.
181
+ BcbCounter :: Counter { .. } => true ,
182
+ // BCB-edge expressions never have mappings, so they never need
183
+ // a corresponding statement.
184
+ BcbCounter :: Expression { .. } => false ,
185
+ } ;
186
+ if !do_inject {
187
+ continue ;
187
188
}
188
189
189
- // Process the counters associated with BCB edges.
190
- for ( from_bcb, to_bcb, counter_kind) in coverage_counters. bcb_edge_counters ( ) {
191
- let do_inject = match counter_kind {
192
- // Counter-increment statements always need to be injected.
193
- BcbCounter :: Counter { .. } => true ,
194
- // BCB-edge expressions never have mappings, so they never need
195
- // a corresponding statement.
196
- BcbCounter :: Expression { .. } => false ,
197
- } ;
198
- if !do_inject {
199
- continue ;
200
- }
190
+ // We need to inject a coverage statement into a new BB between the
191
+ // last BB of `from_bcb` and the first BB of `to_bcb`.
192
+ let from_bb = basic_coverage_blocks[ from_bcb] . last_bb ( ) ;
193
+ let to_bb = basic_coverage_blocks[ to_bcb] . leader_bb ( ) ;
201
194
202
- // We need to inject a coverage statement into a new BB between the
203
- // last BB of `from_bcb` and the first BB of `to_bcb`.
204
- let from_bb = self . basic_coverage_blocks [ from_bcb] . last_bb ( ) ;
205
- let to_bb = self . basic_coverage_blocks [ to_bcb] . leader_bb ( ) ;
206
-
207
- let new_bb = inject_edge_counter_basic_block ( self . mir_body , from_bb, to_bb) ;
208
- debug ! (
209
- "Edge {from_bcb:?} (last {from_bb:?}) -> {to_bcb:?} (leader {to_bb:?}) \
195
+ let new_bb = inject_edge_counter_basic_block ( mir_body, from_bb, to_bb) ;
196
+ debug ! (
197
+ "Edge {from_bcb:?} (last {from_bb:?}) -> {to_bcb:?} (leader {to_bb:?}) \
210
198
requires a new MIR BasicBlock {new_bb:?} for edge counter {counter_kind:?}",
211
- ) ;
199
+ ) ;
212
200
213
- // Inject a counter into the newly-created BB.
214
- inject_statement ( self . mir_body , self . make_mir_coverage_kind ( counter_kind) , new_bb) ;
215
- }
201
+ // Inject a counter into the newly-created BB.
202
+ inject_statement ( mir_body, make_mir_coverage_kind ( counter_kind) , new_bb) ;
216
203
}
204
+ }
217
205
218
- fn make_mir_coverage_kind ( & self , counter_kind : & BcbCounter ) -> CoverageKind {
219
- match * counter_kind {
220
- BcbCounter :: Counter { id } => CoverageKind :: CounterIncrement { id } ,
221
- BcbCounter :: Expression { id } => CoverageKind :: ExpressionUsed { id } ,
222
- }
206
+ fn make_mir_coverage_kind ( counter_kind : & BcbCounter ) -> CoverageKind {
207
+ match * counter_kind {
208
+ BcbCounter :: Counter { id } => CoverageKind :: CounterIncrement { id } ,
209
+ BcbCounter :: Expression { id } => CoverageKind :: ExpressionUsed { id } ,
223
210
}
224
211
}
225
212
0 commit comments