@@ -13,15 +13,10 @@ pub(crate) fn provide(providers: &mut Providers) {
13
13
providers. covered_code_regions = |tcx, def_id| covered_code_regions ( tcx, def_id) ;
14
14
}
15
15
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.
25
20
///
26
21
/// MIR optimization may split and duplicate some BasicBlock sequences, or optimize out some code
27
22
/// 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) {
34
29
/// determining the maximum counter/expression ID, even if the underlying counter/expression is
35
30
/// no longer present.
36
31
struct CoverageVisitor {
37
- info : CoverageInfo ,
32
+ max_counter_id : CounterId ,
33
+ max_expression_id : ExpressionId ,
38
34
}
39
35
40
36
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.
42
38
#[ 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) ;
46
41
}
47
42
48
- /// Updates `num_expressions ` to the maximum encountered expression ID plus 1 .
43
+ /// Updates `max_expression_id ` to the maximum encountered expression ID.
49
44
#[ 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) ;
53
47
}
54
48
55
49
fn update_from_expression_operand ( & mut self , operand : Operand ) {
56
50
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) ,
59
53
Operand :: Zero => { }
60
54
}
61
55
}
@@ -68,9 +62,9 @@ impl CoverageVisitor {
68
62
69
63
fn visit_coverage ( & mut self , coverage : & Coverage ) {
70
64
match coverage. kind {
71
- CoverageKind :: Counter { id, .. } => self . update_num_counters ( id) ,
65
+ CoverageKind :: Counter { id, .. } => self . update_max_counter_id ( id) ,
72
66
CoverageKind :: Expression { id, lhs, rhs, .. } => {
73
- self . update_num_expressions ( id) ;
67
+ self . update_max_expression_id ( id) ;
74
68
self . update_from_expression_operand ( lhs) ;
75
69
self . update_from_expression_operand ( rhs) ;
76
70
}
@@ -82,12 +76,18 @@ impl CoverageVisitor {
82
76
fn coverageinfo < ' tcx > ( tcx : TyCtxt < ' tcx > , instance_def : ty:: InstanceDef < ' tcx > ) -> CoverageInfo {
83
77
let mir_body = tcx. instance_mir ( instance_def) ;
84
78
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
+ } ;
87
83
88
84
coverage_visitor. visit_body ( mir_body) ;
89
85
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
+ }
91
91
}
92
92
93
93
fn covered_code_regions ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> Vec < & CodeRegion > {
0 commit comments