@@ -3,24 +3,22 @@ pub use super::ffi::*;
33use rustc_index:: { IndexSlice , IndexVec } ;
44use rustc_middle:: bug;
55use rustc_middle:: mir:: coverage:: {
6- CodeRegion , CounterValueReference , ExpressionOperandId , InjectedExpressionId ,
7- InjectedExpressionIndex , MappedExpressionIndex , Op ,
6+ CodeRegion , CounterId , ExpressionId , MappedExpressionIndex , Op , Operand ,
87} ;
98use rustc_middle:: ty:: Instance ;
109use rustc_middle:: ty:: TyCtxt ;
1110
1211#[ derive( Clone , Debug , PartialEq ) ]
1312pub struct Expression {
14- lhs : ExpressionOperandId ,
13+ lhs : Operand ,
1514 op : Op ,
16- rhs : ExpressionOperandId ,
15+ rhs : Operand ,
1716 region : Option < CodeRegion > ,
1817}
1918
2019/// Collects all of the coverage regions associated with (a) injected counters, (b) counter
2120/// expressions (additions or subtraction), and (c) unreachable regions (always counted as zero),
22- /// for a given Function. Counters and counter expressions have non-overlapping `id`s because they
23- /// can both be operands in an expression. This struct also stores the `function_source_hash`,
21+ /// for a given Function. This struct also stores the `function_source_hash`,
2422/// computed during instrumentation, and forwarded with counters.
2523///
2624/// Note, it may be important to understand LLVM's definitions of `unreachable` regions versus "gap
@@ -34,8 +32,8 @@ pub struct FunctionCoverage<'tcx> {
3432 instance : Instance < ' tcx > ,
3533 source_hash : u64 ,
3634 is_used : bool ,
37- counters : IndexVec < CounterValueReference , Option < CodeRegion > > ,
38- expressions : IndexVec < InjectedExpressionIndex , Option < Expression > > ,
35+ counters : IndexVec < CounterId , Option < CodeRegion > > ,
36+ expressions : IndexVec < ExpressionId , Option < Expression > > ,
3937 unreachable_regions : Vec < CodeRegion > ,
4038}
4139
@@ -82,48 +80,36 @@ impl<'tcx> FunctionCoverage<'tcx> {
8280 }
8381
8482 /// Adds a code region to be counted by an injected counter intrinsic.
85- pub fn add_counter ( & mut self , id : CounterValueReference , region : CodeRegion ) {
83+ pub fn add_counter ( & mut self , id : CounterId , region : CodeRegion ) {
8684 if let Some ( previous_region) = self . counters [ id] . replace ( region. clone ( ) ) {
8785 assert_eq ! ( previous_region, region, "add_counter: code region for id changed" ) ;
8886 }
8987 }
9088
9189 /// Both counters and "counter expressions" (or simply, "expressions") can be operands in other
92- /// expressions. Expression IDs start from `u32::MAX` and go down, so the range of expression
93- /// IDs will not overlap with the range of counter IDs. Counters and expressions can be added in
94- /// any order, and expressions can still be assigned contiguous (though descending) IDs, without
95- /// knowing what the last counter ID will be.
96- ///
97- /// When storing the expression data in the `expressions` vector in the `FunctionCoverage`
98- /// struct, its vector index is computed, from the given expression ID, by subtracting from
99- /// `u32::MAX`.
100- ///
101- /// Since the expression operands (`lhs` and `rhs`) can reference either counters or
102- /// expressions, an operand that references an expression also uses its original ID, descending
103- /// from `u32::MAX`. Theses operands are translated only during code generation, after all
104- /// counters and expressions have been added.
90+ /// expressions. These are tracked as separate variants of `Operand`, so there is no ambiguity
91+ /// between operands that are counter IDs and operands that are expression IDs.
10592 pub fn add_counter_expression (
10693 & mut self ,
107- expression_id : InjectedExpressionId ,
108- lhs : ExpressionOperandId ,
94+ expression_id : ExpressionId ,
95+ lhs : Operand ,
10996 op : Op ,
110- rhs : ExpressionOperandId ,
97+ rhs : Operand ,
11198 region : Option < CodeRegion > ,
11299 ) {
113100 debug ! (
114101 "add_counter_expression({:?}, lhs={:?}, op={:?}, rhs={:?} at {:?}" ,
115102 expression_id, lhs, op, rhs, region
116103 ) ;
117- let expression_index = self . expression_index ( u32:: from ( expression_id) ) ;
118104 debug_assert ! (
119- expression_index . as_usize( ) < self . expressions. len( ) ,
120- "expression_index {} is out of range for expressions.len() = {}
105+ expression_id . as_usize( ) < self . expressions. len( ) ,
106+ "expression_id {} is out of range for expressions.len() = {}
121107 for {:?}" ,
122- expression_index . as_usize( ) ,
108+ expression_id . as_usize( ) ,
123109 self . expressions. len( ) ,
124110 self ,
125111 ) ;
126- if let Some ( previous_expression) = self . expressions [ expression_index ] . replace ( Expression {
112+ if let Some ( previous_expression) = self . expressions [ expression_id ] . replace ( Expression {
127113 lhs,
128114 op,
129115 rhs,
@@ -186,14 +172,11 @@ impl<'tcx> FunctionCoverage<'tcx> {
186172
187173 // This closure converts any `Expression` operand (`lhs` or `rhs` of the `Op::Add` or
188174 // `Op::Subtract` operation) into its native `llvm::coverage::Counter::CounterKind` type
189- // and value. Operand ID value `0` maps to `CounterKind::Zero`; values in the known range
190- // of injected LLVM counters map to `CounterKind::CounterValueReference` (and the value
191- // matches the injected counter index); and any other value is converted into a
192- // `CounterKind::Expression` with the expression's `new_index`.
175+ // and value.
193176 //
194177 // Expressions will be returned from this function in a sequential vector (array) of
195178 // `CounterExpression`, so the expression IDs must be mapped from their original,
196- // potentially sparse set of indexes, originally in reverse order from `u32::MAX` .
179+ // potentially sparse set of indexes.
197180 //
198181 // An `Expression` as an operand will have already been encountered as an `Expression` with
199182 // operands, so its new_index will already have been generated (as a 1-up index value).
@@ -206,34 +189,19 @@ impl<'tcx> FunctionCoverage<'tcx> {
206189 // `expression_index`s lower than the referencing `Expression`. Therefore, it is
207190 // reasonable to look up the new index of an expression operand while the `new_indexes`
208191 // vector is only complete up to the current `ExpressionIndex`.
209- let id_to_counter = |new_indexes : & IndexSlice <
210- InjectedExpressionIndex ,
211- Option < MappedExpressionIndex > ,
212- > ,
213- id : ExpressionOperandId | {
214- if id == ExpressionOperandId :: ZERO {
215- Some ( Counter :: zero ( ) )
216- } else if id. index ( ) < self . counters . len ( ) {
217- debug_assert ! (
218- id. index( ) > 0 ,
219- "ExpressionOperandId indexes for counters are 1-based, but this id={}" ,
220- id. index( )
221- ) ;
222- // Note: Some codegen-injected Counters may be only referenced by `Expression`s,
223- // and may not have their own `CodeRegion`s,
224- let index = CounterValueReference :: from ( id. index ( ) ) ;
225- // Note, the conversion to LLVM `Counter` adjusts the index to be zero-based.
226- Some ( Counter :: counter_value_reference ( index) )
227- } else {
228- let index = self . expression_index ( u32:: from ( id) ) ;
192+ type NewIndexes = IndexSlice < ExpressionId , Option < MappedExpressionIndex > > ;
193+ let id_to_counter = |new_indexes : & NewIndexes , operand : Operand | match operand {
194+ Operand :: Zero => Some ( Counter :: zero ( ) ) ,
195+ Operand :: Counter ( id) => Some ( Counter :: counter_value_reference ( id) ) ,
196+ Operand :: Expression ( id) => {
229197 self . expressions
230- . get ( index )
198+ . get ( id )
231199 . expect ( "expression id is out of range" )
232200 . as_ref ( )
233201 // If an expression was optimized out, assume it would have produced a count
234202 // of zero. This ensures that expressions dependent on optimized-out
235203 // expressions are still valid.
236- . map_or ( Some ( Counter :: zero ( ) ) , |_| new_indexes[ index ] . map ( Counter :: expression) )
204+ . map_or ( Some ( Counter :: zero ( ) ) , |_| new_indexes[ id ] . map ( Counter :: expression) )
237205 }
238206 } ;
239207
@@ -340,9 +308,4 @@ impl<'tcx> FunctionCoverage<'tcx> {
340308 fn unreachable_regions ( & self ) -> impl Iterator < Item = ( Counter , & CodeRegion ) > {
341309 self . unreachable_regions . iter ( ) . map ( |region| ( Counter :: zero ( ) , region) )
342310 }
343-
344- fn expression_index ( & self , id_descending_from_max : u32 ) -> InjectedExpressionIndex {
345- debug_assert ! ( id_descending_from_max >= self . counters. len( ) as u32 ) ;
346- InjectedExpressionIndex :: from ( u32:: MAX - id_descending_from_max)
347- }
348311}
0 commit comments