Skip to content

Commit e54204c

Browse files
committed
coverage: In the visitor, track max counter/expression IDs without +1
This makes the visitor track the highest seen counter/expression IDs directly, and only add +1 (to convert to a vector length) at the very end.
1 parent f191b1c commit e54204c

File tree

1 file changed

+25
-25
lines changed
  • compiler/rustc_mir_transform/src/coverage

1 file changed

+25
-25
lines changed

compiler/rustc_mir_transform/src/coverage/query.rs

+25-25
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,10 @@ pub(crate) fn provide(providers: &mut Providers) {
1313
providers.covered_code_regions = |tcx, def_id| covered_code_regions(tcx, def_id);
1414
}
1515

16-
/// The `num_counters` argument to `llvm.instrprof.increment` is the max counter_id + 1, or in
17-
/// other words, the number of counter value references injected into the MIR (plus 1 for the
18-
/// reserved `ZERO` counter, which uses counter ID `0` when included in an expression). Injected
19-
/// counters have a counter ID from `1..num_counters-1`.
20-
///
21-
/// `num_expressions` is the number of counter expressions added to the MIR body.
22-
///
23-
/// Both `num_counters` and `num_expressions` are used to initialize new vectors, during backend
24-
/// code generate, to lookup counters and expressions by simple u32 indexes.
16+
/// Coverage codegen needs to know the total number of counter IDs and expression IDs that have
17+
/// been used by a function's coverage mappings. These totals are used to create vectors to hold
18+
/// the relevant counter and expression data, and the maximum counter ID (+ 1) is also needed by
19+
/// the `llvm.instrprof.increment` intrinsic.
2520
///
2621
/// MIR optimization may split and duplicate some BasicBlock sequences, or optimize out some code
2722
/// including injected counters. (It is OK if some counters are optimized out, but those counters
@@ -34,28 +29,27 @@ pub(crate) fn provide(providers: &mut Providers) {
3429
/// determining the maximum counter/expression ID, even if the underlying counter/expression is
3530
/// no longer present.
3631
struct CoverageVisitor {
37-
info: CoverageInfo,
32+
max_counter_id: CounterId,
33+
max_expression_id: ExpressionId,
3834
}
3935

4036
impl CoverageVisitor {
41-
/// Updates `num_counters` to the maximum encountered counter ID plus 1.
37+
/// Updates `max_counter_id` to the maximum encountered counter ID.
4238
#[inline(always)]
43-
fn update_num_counters(&mut self, counter_id: CounterId) {
44-
let counter_id = counter_id.as_u32();
45-
self.info.num_counters = std::cmp::max(self.info.num_counters, counter_id + 1);
39+
fn update_max_counter_id(&mut self, counter_id: CounterId) {
40+
self.max_counter_id = self.max_counter_id.max(counter_id);
4641
}
4742

48-
/// Updates `num_expressions` to the maximum encountered expression ID plus 1.
43+
/// Updates `max_expression_id` to the maximum encountered expression ID.
4944
#[inline(always)]
50-
fn update_num_expressions(&mut self, expression_id: ExpressionId) {
51-
let expression_id = expression_id.as_u32();
52-
self.info.num_expressions = std::cmp::max(self.info.num_expressions, expression_id + 1);
45+
fn update_max_expression_id(&mut self, expression_id: ExpressionId) {
46+
self.max_expression_id = self.max_expression_id.max(expression_id);
5347
}
5448

5549
fn update_from_expression_operand(&mut self, operand: Operand) {
5650
match operand {
57-
Operand::Counter(id) => self.update_num_counters(id),
58-
Operand::Expression(id) => self.update_num_expressions(id),
51+
Operand::Counter(id) => self.update_max_counter_id(id),
52+
Operand::Expression(id) => self.update_max_expression_id(id),
5953
Operand::Zero => {}
6054
}
6155
}
@@ -68,9 +62,9 @@ impl CoverageVisitor {
6862

6963
fn visit_coverage(&mut self, coverage: &Coverage) {
7064
match coverage.kind {
71-
CoverageKind::Counter { id, .. } => self.update_num_counters(id),
65+
CoverageKind::Counter { id, .. } => self.update_max_counter_id(id),
7266
CoverageKind::Expression { id, lhs, rhs, .. } => {
73-
self.update_num_expressions(id);
67+
self.update_max_expression_id(id);
7468
self.update_from_expression_operand(lhs);
7569
self.update_from_expression_operand(rhs);
7670
}
@@ -82,12 +76,18 @@ impl CoverageVisitor {
8276
fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, instance_def: ty::InstanceDef<'tcx>) -> CoverageInfo {
8377
let mir_body = tcx.instance_mir(instance_def);
8478

85-
let mut coverage_visitor =
86-
CoverageVisitor { info: CoverageInfo { num_counters: 0, num_expressions: 0 } };
79+
let mut coverage_visitor = CoverageVisitor {
80+
max_counter_id: CounterId::START,
81+
max_expression_id: ExpressionId::START,
82+
};
8783

8884
coverage_visitor.visit_body(mir_body);
8985

90-
coverage_visitor.info
86+
// Add 1 to the highest IDs to get the total number of IDs.
87+
CoverageInfo {
88+
num_counters: (coverage_visitor.max_counter_id + 1).as_u32(),
89+
num_expressions: (coverage_visitor.max_expression_id + 1).as_u32(),
90+
}
9191
}
9292

9393
fn covered_code_regions(tcx: TyCtxt<'_>, def_id: DefId) -> Vec<&CodeRegion> {

0 commit comments

Comments
 (0)