1
- use rustc_data_structures:: fx:: FxIndexMap ;
1
+ use rustc_data_structures:: captures:: Captures ;
2
+ use rustc_data_structures:: fx:: FxHashMap ;
2
3
use rustc_data_structures:: graph:: WithNumNodes ;
3
4
use rustc_index:: bit_set:: BitSet ;
4
5
use rustc_index:: IndexVec ;
@@ -38,19 +39,27 @@ impl Debug for BcbCounter {
38
39
}
39
40
}
40
41
42
+ #[ derive( Debug ) ]
43
+ pub ( super ) enum CounterIncrementSite {
44
+ Node { bcb : BasicCoverageBlock } ,
45
+ Edge { from_bcb : BasicCoverageBlock , to_bcb : BasicCoverageBlock } ,
46
+ }
47
+
41
48
/// Generates and stores coverage counter and coverage expression information
42
49
/// associated with nodes/edges in the BCB graph.
43
50
pub ( super ) struct CoverageCounters {
44
- next_counter_id : CounterId ,
51
+ /// List of places where a counter-increment statement should be injected
52
+ /// into MIR, each with its corresponding counter ID.
53
+ counter_increment_sites : IndexVec < CounterId , CounterIncrementSite > ,
45
54
46
55
/// Coverage counters/expressions that are associated with individual BCBs.
47
56
bcb_counters : IndexVec < BasicCoverageBlock , Option < BcbCounter > > ,
48
57
/// Coverage counters/expressions that are associated with the control-flow
49
58
/// edge between two BCBs.
50
59
///
51
- /// The iteration order of this map can affect the precise contents of MIR ,
52
- /// so we use `FxIndexMap` to avoid query stability hazards.
53
- bcb_edge_counters : FxIndexMap < ( BasicCoverageBlock , BasicCoverageBlock ) , BcbCounter > ,
60
+ /// We currently don't iterate over this map, but if we do in the future ,
61
+ /// switch it back to `FxIndexMap` to avoid query stability hazards.
62
+ bcb_edge_counters : FxHashMap < ( BasicCoverageBlock , BasicCoverageBlock ) , BcbCounter > ,
54
63
/// Tracks which BCBs have a counter associated with some incoming edge.
55
64
/// Only used by assertions, to verify that BCBs with incoming edge
56
65
/// counters do not have their own physical counters (expressions are allowed).
@@ -71,9 +80,9 @@ impl CoverageCounters {
71
80
let num_bcbs = basic_coverage_blocks. num_nodes ( ) ;
72
81
73
82
let mut this = Self {
74
- next_counter_id : CounterId :: START ,
83
+ counter_increment_sites : IndexVec :: new ( ) ,
75
84
bcb_counters : IndexVec :: from_elem_n ( None , num_bcbs) ,
76
- bcb_edge_counters : FxIndexMap :: default ( ) ,
85
+ bcb_edge_counters : FxHashMap :: default ( ) ,
77
86
bcb_has_incoming_edge_counters : BitSet :: new_empty ( num_bcbs) ,
78
87
expressions : IndexVec :: new ( ) ,
79
88
} ;
@@ -84,8 +93,8 @@ impl CoverageCounters {
84
93
this
85
94
}
86
95
87
- fn make_counter ( & mut self ) -> BcbCounter {
88
- let id = self . next_counter ( ) ;
96
+ fn make_counter ( & mut self , site : CounterIncrementSite ) -> BcbCounter {
97
+ let id = self . counter_increment_sites . push ( site ) ;
89
98
BcbCounter :: Counter { id }
90
99
}
91
100
@@ -103,15 +112,8 @@ impl CoverageCounters {
103
112
self . make_expression ( lhs, Op :: Add , rhs)
104
113
}
105
114
106
- /// Counter IDs start from one and go up.
107
- fn next_counter ( & mut self ) -> CounterId {
108
- let next = self . next_counter_id ;
109
- self . next_counter_id = self . next_counter_id + 1 ;
110
- next
111
- }
112
-
113
115
pub ( super ) fn num_counters ( & self ) -> usize {
114
- self . next_counter_id . as_usize ( )
116
+ self . counter_increment_sites . len ( )
115
117
}
116
118
117
119
#[ cfg( test) ]
@@ -171,22 +173,26 @@ impl CoverageCounters {
171
173
self . bcb_counters [ bcb]
172
174
}
173
175
174
- pub ( super ) fn bcb_node_counters (
176
+ /// Returns an iterator over all the nodes/edges in the coverage graph that
177
+ /// should have a counter-increment statement injected into MIR, along with
178
+ /// each site's corresponding counter ID.
179
+ pub ( super ) fn counter_increment_sites (
175
180
& self ,
176
- ) -> impl Iterator < Item = ( BasicCoverageBlock , & BcbCounter ) > {
177
- self . bcb_counters
178
- . iter_enumerated ( )
179
- . filter_map ( |( bcb, counter_kind) | Some ( ( bcb, counter_kind. as_ref ( ) ?) ) )
181
+ ) -> impl Iterator < Item = ( CounterId , & CounterIncrementSite ) > {
182
+ self . counter_increment_sites . iter_enumerated ( )
180
183
}
181
184
182
- /// For each edge in the BCB graph that has an associated counter, yields
183
- /// that edge's *from* and *to* nodes, and its counter .
184
- pub ( super ) fn bcb_edge_counters (
185
+ /// Returns an iterator over the subset of BCB nodes that have been associated
186
+ /// with a counter *expression*, along with the ID of that expression .
187
+ pub ( super ) fn bcb_nodes_with_coverage_expressions (
185
188
& self ,
186
- ) -> impl Iterator < Item = ( BasicCoverageBlock , BasicCoverageBlock , & BcbCounter ) > {
187
- self . bcb_edge_counters
188
- . iter ( )
189
- . map ( |( & ( from_bcb, to_bcb) , counter_kind) | ( from_bcb, to_bcb, counter_kind) )
189
+ ) -> impl Iterator < Item = ( BasicCoverageBlock , ExpressionId ) > + Captures < ' _ > {
190
+ self . bcb_counters . iter_enumerated ( ) . filter_map ( |( bcb, & counter_kind) | match counter_kind {
191
+ // Yield the BCB along with its associated expression ID.
192
+ Some ( BcbCounter :: Expression { id } ) => Some ( ( bcb, id) ) ,
193
+ // This BCB is associated with a counter or nothing, so skip it.
194
+ Some ( BcbCounter :: Counter { .. } ) | None => None ,
195
+ } )
190
196
}
191
197
192
198
pub ( super ) fn into_expressions ( self ) -> IndexVec < ExpressionId , Expression > {
@@ -339,7 +345,8 @@ impl<'a> MakeBcbCounters<'a> {
339
345
// program results in a tight infinite loop, but it should still compile.
340
346
let one_path_to_target = !self . basic_coverage_blocks . bcb_has_multiple_in_edges ( bcb) ;
341
347
if one_path_to_target || self . bcb_predecessors ( bcb) . contains ( & bcb) {
342
- let counter_kind = self . coverage_counters . make_counter ( ) ;
348
+ let counter_kind =
349
+ self . coverage_counters . make_counter ( CounterIncrementSite :: Node { bcb } ) ;
343
350
if one_path_to_target {
344
351
debug ! ( "{bcb:?} gets a new counter: {counter_kind:?}" ) ;
345
352
} else {
@@ -401,7 +408,8 @@ impl<'a> MakeBcbCounters<'a> {
401
408
}
402
409
403
410
// Make a new counter to count this edge.
404
- let counter_kind = self . coverage_counters . make_counter ( ) ;
411
+ let counter_kind =
412
+ self . coverage_counters . make_counter ( CounterIncrementSite :: Edge { from_bcb, to_bcb } ) ;
405
413
debug ! ( "Edge {from_bcb:?}->{to_bcb:?} gets a new counter: {counter_kind:?}" ) ;
406
414
self . coverage_counters . set_bcb_edge_counter ( from_bcb, to_bcb, counter_kind)
407
415
}
0 commit comments