Skip to content

Commit 5302c9d

Browse files
committed
Accumulate intermediate expressions into CoverageCounters
This avoids the need to pass around a separate vector to accumulate into, and avoids the need to create a fake empty vector when failure occurs.
1 parent c74db79 commit 5302c9d

File tree

3 files changed

+63
-95
lines changed

3 files changed

+63
-95
lines changed

compiler/rustc_mir_transform/src/coverage/counters.rs

+23-50
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ pub(super) struct CoverageCounters {
1818
function_source_hash: u64,
1919
next_counter_id: CounterId,
2020
next_expression_id: ExpressionId,
21+
22+
/// Expression nodes that are not directly associated with any particular
23+
/// BCB/edge, but are needed as operands to more complex expressions.
24+
/// These are always `CoverageKind::Expression`.
25+
pub(super) intermediate_expressions: Vec<CoverageKind>,
26+
2127
pub debug_counters: DebugCounters,
2228
}
2329

@@ -27,6 +33,9 @@ impl CoverageCounters {
2733
function_source_hash,
2834
next_counter_id: CounterId::START,
2935
next_expression_id: ExpressionId::START,
36+
37+
intermediate_expressions: Vec::new(),
38+
3039
debug_counters: DebugCounters::new(),
3140
}
3241
}
@@ -38,13 +47,13 @@ impl CoverageCounters {
3847
}
3948

4049
/// Makes `CoverageKind` `Counter`s and `Expressions` for the `BasicCoverageBlock`s directly or
41-
/// indirectly associated with `CoverageSpans`, and returns additional `Expression`s
50+
/// indirectly associated with `CoverageSpans`, and accumulates additional `Expression`s
4251
/// representing intermediate values.
4352
pub fn make_bcb_counters(
4453
&mut self,
4554
basic_coverage_blocks: &mut CoverageGraph,
4655
coverage_spans: &[CoverageSpan],
47-
) -> Result<Vec<CoverageKind>, Error> {
56+
) -> Result<(), Error> {
4857
MakeBcbCounters::new(self, basic_coverage_blocks).make_bcb_counters(coverage_spans)
4958
}
5059

@@ -134,13 +143,9 @@ impl<'a> MakeBcbCounters<'a> {
134143
/// Returns any non-code-span expressions created to represent intermediate values (such as to
135144
/// add two counters so the result can be subtracted from another counter), or an Error with
136145
/// message for subsequent debugging.
137-
fn make_bcb_counters(
138-
&mut self,
139-
coverage_spans: &[CoverageSpan],
140-
) -> Result<Vec<CoverageKind>, Error> {
146+
fn make_bcb_counters(&mut self, coverage_spans: &[CoverageSpan]) -> Result<(), Error> {
141147
debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock");
142148
let num_bcbs = self.basic_coverage_blocks.num_nodes();
143-
let mut collect_intermediate_expressions = Vec::with_capacity(num_bcbs);
144149

145150
let mut bcbs_with_coverage = BitSet::new_empty(num_bcbs);
146151
for covspan in coverage_spans {
@@ -161,16 +166,10 @@ impl<'a> MakeBcbCounters<'a> {
161166
while let Some(bcb) = traversal.next(self.basic_coverage_blocks) {
162167
if bcbs_with_coverage.contains(bcb) {
163168
debug!("{:?} has at least one `CoverageSpan`. Get or make its counter", bcb);
164-
let branching_counter_operand =
165-
self.get_or_make_counter_operand(bcb, &mut collect_intermediate_expressions)?;
169+
let branching_counter_operand = self.get_or_make_counter_operand(bcb)?;
166170

167171
if self.bcb_needs_branch_counters(bcb) {
168-
self.make_branch_counters(
169-
&mut traversal,
170-
bcb,
171-
branching_counter_operand,
172-
&mut collect_intermediate_expressions,
173-
)?;
172+
self.make_branch_counters(&mut traversal, bcb, branching_counter_operand)?;
174173
}
175174
} else {
176175
debug!(
@@ -182,7 +181,7 @@ impl<'a> MakeBcbCounters<'a> {
182181
}
183182

184183
if traversal.is_complete() {
185-
Ok(collect_intermediate_expressions)
184+
Ok(())
186185
} else {
187186
Error::from_string(format!(
188187
"`TraverseCoverageGraphWithLoops` missed some `BasicCoverageBlock`s: {:?}",
@@ -196,7 +195,6 @@ impl<'a> MakeBcbCounters<'a> {
196195
traversal: &mut TraverseCoverageGraphWithLoops,
197196
branching_bcb: BasicCoverageBlock,
198197
branching_counter_operand: Operand,
199-
collect_intermediate_expressions: &mut Vec<CoverageKind>,
200198
) -> Result<(), Error> {
201199
let branches = self.bcb_branches(branching_bcb);
202200
debug!(
@@ -232,17 +230,10 @@ impl<'a> MakeBcbCounters<'a> {
232230
counter",
233231
branch, branching_bcb
234232
);
235-
self.get_or_make_counter_operand(
236-
branch.target_bcb,
237-
collect_intermediate_expressions,
238-
)?
233+
self.get_or_make_counter_operand(branch.target_bcb)?
239234
} else {
240235
debug!(" {:?} has multiple incoming edges, so adding an edge counter", branch);
241-
self.get_or_make_edge_counter_operand(
242-
branching_bcb,
243-
branch.target_bcb,
244-
collect_intermediate_expressions,
245-
)?
236+
self.get_or_make_edge_counter_operand(branching_bcb, branch.target_bcb)?
246237
};
247238
if let Some(sumup_counter_operand) =
248239
some_sumup_counter_operand.replace(branch_counter_operand)
@@ -258,7 +249,7 @@ impl<'a> MakeBcbCounters<'a> {
258249
self.format_counter(&intermediate_expression)
259250
);
260251
let intermediate_expression_operand = intermediate_expression.as_operand();
261-
collect_intermediate_expressions.push(intermediate_expression);
252+
self.coverage_counters.intermediate_expressions.push(intermediate_expression);
262253
some_sumup_counter_operand.replace(intermediate_expression_operand);
263254
}
264255
}
@@ -290,18 +281,13 @@ impl<'a> MakeBcbCounters<'a> {
290281
Ok(())
291282
}
292283

293-
fn get_or_make_counter_operand(
294-
&mut self,
295-
bcb: BasicCoverageBlock,
296-
collect_intermediate_expressions: &mut Vec<CoverageKind>,
297-
) -> Result<Operand, Error> {
298-
self.recursive_get_or_make_counter_operand(bcb, collect_intermediate_expressions, 1)
284+
fn get_or_make_counter_operand(&mut self, bcb: BasicCoverageBlock) -> Result<Operand, Error> {
285+
self.recursive_get_or_make_counter_operand(bcb, 1)
299286
}
300287

301288
fn recursive_get_or_make_counter_operand(
302289
&mut self,
303290
bcb: BasicCoverageBlock,
304-
collect_intermediate_expressions: &mut Vec<CoverageKind>,
305291
debug_indent_level: usize,
306292
) -> Result<Operand, Error> {
307293
// If the BCB already has a counter, return it.
@@ -354,15 +340,13 @@ impl<'a> MakeBcbCounters<'a> {
354340
let first_edge_counter_operand = self.recursive_get_or_make_edge_counter_operand(
355341
predecessors.next().unwrap(),
356342
bcb,
357-
collect_intermediate_expressions,
358343
debug_indent_level + 1,
359344
)?;
360345
let mut some_sumup_edge_counter_operand = None;
361346
for predecessor in predecessors {
362347
let edge_counter_operand = self.recursive_get_or_make_edge_counter_operand(
363348
predecessor,
364349
bcb,
365-
collect_intermediate_expressions,
366350
debug_indent_level + 1,
367351
)?;
368352
if let Some(sumup_edge_counter_operand) =
@@ -380,7 +364,7 @@ impl<'a> MakeBcbCounters<'a> {
380364
self.format_counter(&intermediate_expression)
381365
);
382366
let intermediate_expression_operand = intermediate_expression.as_operand();
383-
collect_intermediate_expressions.push(intermediate_expression);
367+
self.coverage_counters.intermediate_expressions.push(intermediate_expression);
384368
some_sumup_edge_counter_operand.replace(intermediate_expression_operand);
385369
}
386370
}
@@ -403,32 +387,21 @@ impl<'a> MakeBcbCounters<'a> {
403387
&mut self,
404388
from_bcb: BasicCoverageBlock,
405389
to_bcb: BasicCoverageBlock,
406-
collect_intermediate_expressions: &mut Vec<CoverageKind>,
407390
) -> Result<Operand, Error> {
408-
self.recursive_get_or_make_edge_counter_operand(
409-
from_bcb,
410-
to_bcb,
411-
collect_intermediate_expressions,
412-
1,
413-
)
391+
self.recursive_get_or_make_edge_counter_operand(from_bcb, to_bcb, 1)
414392
}
415393

416394
fn recursive_get_or_make_edge_counter_operand(
417395
&mut self,
418396
from_bcb: BasicCoverageBlock,
419397
to_bcb: BasicCoverageBlock,
420-
collect_intermediate_expressions: &mut Vec<CoverageKind>,
421398
debug_indent_level: usize,
422399
) -> Result<Operand, Error> {
423400
// If the source BCB has only one successor (assumed to be the given target), an edge
424401
// counter is unnecessary. Just get or make a counter for the source BCB.
425402
let successors = self.bcb_successors(from_bcb).iter();
426403
if successors.len() == 1 {
427-
return self.recursive_get_or_make_counter_operand(
428-
from_bcb,
429-
collect_intermediate_expressions,
430-
debug_indent_level + 1,
431-
);
404+
return self.recursive_get_or_make_counter_operand(from_bcb, debug_indent_level + 1);
432405
}
433406

434407
// If the edge already has a counter, return it.

compiler/rustc_mir_transform/src/coverage/mod.rs

+38-43
Original file line numberDiff line numberDiff line change
@@ -199,52 +199,47 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
199199
// `BasicCoverageBlock`s not already associated with a `CoverageSpan`.
200200
//
201201
// Intermediate expressions (used to compute other `Expression` values), which have no
202-
// direct associate to any `BasicCoverageBlock`, are returned in the method `Result`.
203-
let intermediate_expressions_or_error = self
202+
// direct association with any `BasicCoverageBlock`, are accumulated inside `coverage_counters`.
203+
let result = self
204204
.coverage_counters
205205
.make_bcb_counters(&mut self.basic_coverage_blocks, &coverage_spans);
206206

207-
let (result, intermediate_expressions) = match intermediate_expressions_or_error {
208-
Ok(intermediate_expressions) => {
209-
// If debugging, add any intermediate expressions (which are not associated with any
210-
// BCB) to the `debug_used_expressions` map.
211-
if debug_used_expressions.is_enabled() {
212-
for intermediate_expression in &intermediate_expressions {
213-
debug_used_expressions.add_expression_operands(intermediate_expression);
214-
}
207+
if let Ok(()) = result {
208+
// If debugging, add any intermediate expressions (which are not associated with any
209+
// BCB) to the `debug_used_expressions` map.
210+
if debug_used_expressions.is_enabled() {
211+
for intermediate_expression in &self.coverage_counters.intermediate_expressions {
212+
debug_used_expressions.add_expression_operands(intermediate_expression);
215213
}
216-
217-
////////////////////////////////////////////////////
218-
// Remove the counter or edge counter from of each `CoverageSpan`s associated
219-
// `BasicCoverageBlock`, and inject a `Coverage` statement into the MIR.
220-
//
221-
// `Coverage` statements injected from `CoverageSpan`s will include the code regions
222-
// (source code start and end positions) to be counted by the associated counter.
223-
//
224-
// These `CoverageSpan`-associated counters are removed from their associated
225-
// `BasicCoverageBlock`s so that the only remaining counters in the `CoverageGraph`
226-
// are indirect counters (to be injected next, without associated code regions).
227-
self.inject_coverage_span_counters(
228-
coverage_spans,
229-
&mut graphviz_data,
230-
&mut debug_used_expressions,
231-
);
232-
233-
////////////////////////////////////////////////////
234-
// For any remaining `BasicCoverageBlock` counters (that were not associated with
235-
// any `CoverageSpan`), inject `Coverage` statements (_without_ code region `Span`s)
236-
// to ensure `BasicCoverageBlock` counters that other `Expression`s may depend on
237-
// are in fact counted, even though they don't directly contribute to counting
238-
// their own independent code region's coverage.
239-
self.inject_indirect_counters(&mut graphviz_data, &mut debug_used_expressions);
240-
241-
// Intermediate expressions will be injected as the final step, after generating
242-
// debug output, if any.
243-
////////////////////////////////////////////////////
244-
245-
(Ok(()), intermediate_expressions)
246214
}
247-
Err(e) => (Err(e), Vec::new()),
215+
216+
////////////////////////////////////////////////////
217+
// Remove the counter or edge counter from of each `CoverageSpan`s associated
218+
// `BasicCoverageBlock`, and inject a `Coverage` statement into the MIR.
219+
//
220+
// `Coverage` statements injected from `CoverageSpan`s will include the code regions
221+
// (source code start and end positions) to be counted by the associated counter.
222+
//
223+
// These `CoverageSpan`-associated counters are removed from their associated
224+
// `BasicCoverageBlock`s so that the only remaining counters in the `CoverageGraph`
225+
// are indirect counters (to be injected next, without associated code regions).
226+
self.inject_coverage_span_counters(
227+
coverage_spans,
228+
&mut graphviz_data,
229+
&mut debug_used_expressions,
230+
);
231+
232+
////////////////////////////////////////////////////
233+
// For any remaining `BasicCoverageBlock` counters (that were not associated with
234+
// any `CoverageSpan`), inject `Coverage` statements (_without_ code region `Span`s)
235+
// to ensure `BasicCoverageBlock` counters that other `Expression`s may depend on
236+
// are in fact counted, even though they don't directly contribute to counting
237+
// their own independent code region's coverage.
238+
self.inject_indirect_counters(&mut graphviz_data, &mut debug_used_expressions);
239+
240+
// Intermediate expressions will be injected as the final step, after generating
241+
// debug output, if any.
242+
////////////////////////////////////////////////////
248243
};
249244

250245
if graphviz_data.is_enabled() {
@@ -257,7 +252,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
257252
&self.basic_coverage_blocks,
258253
&self.coverage_counters.debug_counters,
259254
&graphviz_data,
260-
&intermediate_expressions,
255+
&self.coverage_counters.intermediate_expressions,
261256
&debug_used_expressions,
262257
);
263258
}
@@ -273,7 +268,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
273268

274269
////////////////////////////////////////////////////
275270
// Finally, inject the intermediate expressions collected along the way.
276-
for intermediate_expression in intermediate_expressions {
271+
for intermediate_expression in self.coverage_counters.intermediate_expressions.drain(..) {
277272
inject_intermediate_expression(self.mir_body, intermediate_expression);
278273
}
279274
}

compiler/rustc_mir_transform/src/coverage/tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -676,10 +676,10 @@ fn test_make_bcb_counters() {
676676
}
677677
}
678678
let mut coverage_counters = counters::CoverageCounters::new(0);
679-
let intermediate_expressions = coverage_counters
679+
let () = coverage_counters
680680
.make_bcb_counters(&mut basic_coverage_blocks, &coverage_spans)
681681
.expect("should be Ok");
682-
assert_eq!(intermediate_expressions.len(), 0);
682+
assert_eq!(coverage_counters.intermediate_expressions.len(), 0);
683683

684684
let_bcb!(1);
685685
assert_eq!(

0 commit comments

Comments
 (0)