11use  rustc_data_structures:: captures:: Captures ; 
2- use  rustc_index:: IndexSlice ; 
32use  rustc_index:: bit_set:: DenseBitSet ; 
43use  rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ; 
5- use  rustc_middle:: mir:: coverage:: { 
6-     BasicCoverageBlock ,  CounterId ,  CovTerm ,  CoverageIdsInfo ,  CoverageKind ,  Expression , 
7-     ExpressionId ,  MappingKind ,  Op , 
8- } ; 
4+ use  rustc_middle:: mir:: coverage:: { BasicCoverageBlock ,  CoverageIdsInfo ,  CoverageKind ,  MappingKind } ; 
95use  rustc_middle:: mir:: { Body ,  Statement ,  StatementKind } ; 
106use  rustc_middle:: ty:: { self ,  TyCtxt } ; 
117use  rustc_middle:: util:: Providers ; 
@@ -134,44 +130,12 @@ fn coverage_ids_info<'tcx>(
134130    let  node_counters = make_node_counters ( & fn_cov_info. node_flow_data ,  & fn_cov_info. priority_list ) ; 
135131    let  coverage_counters = transcribe_counters ( & node_counters,  & bcb_needs_counter,  & bcbs_seen) ; 
136132
137-     let  mut  counters_seen = DenseBitSet :: new_empty ( coverage_counters. node_counters . len ( ) ) ; 
138-     let  mut  expressions_seen = DenseBitSet :: new_filled ( coverage_counters. expressions . len ( ) ) ; 
139- 
140-     // For each expression ID that is directly used by one or more mappings, 
141-     // mark it as not-yet-seen. This indicates that we expect to see a 
142-     // corresponding `VirtualCounter` statement during MIR traversal. 
143-     for  mapping in  fn_cov_info. mappings . iter ( )  { 
144-         // Currently we only worry about ordinary code mappings. 
145-         // For branch and MC/DC mappings, expressions might not correspond 
146-         // to any particular point in the control-flow graph. 
147-         if  let  MappingKind :: Code  {  bcb }  = mapping. kind 
148-             && let  Some ( CovTerm :: Expression ( id) )  = coverage_counters. node_counters [ bcb] 
149-         { 
150-             expressions_seen. remove ( id) ; 
151-         } 
152-     } 
153- 
154-     for  bcb in  bcbs_seen. iter ( )  { 
155-         if  let  Some ( & id)  = coverage_counters. phys_counter_for_node . get ( & bcb)  { 
156-             counters_seen. insert ( id) ; 
157-         } 
158-         if  let  Some ( CovTerm :: Expression ( id) )  = coverage_counters. node_counters [ bcb]  { 
159-             expressions_seen. insert ( id) ; 
160-         } 
161-     } 
162- 
163-     let  zero_expressions = identify_zero_expressions ( 
164-         & coverage_counters. expressions , 
165-         & counters_seen, 
166-         & expressions_seen, 
167-     ) ; 
168- 
169-     let  CoverageCounters  {  phys_counter_for_node,  node_counters,  expressions,  .. }  =
170-         coverage_counters; 
133+     let  CoverageCounters  { 
134+         phys_counter_for_node,  next_counter_id,  node_counters,  expressions,  ..
135+     }  = coverage_counters; 
171136
172137    Some ( CoverageIdsInfo  { 
173-         counters_seen, 
174-         zero_expressions, 
138+         num_counters :  next_counter_id. as_u32 ( ) , 
175139        phys_counter_for_node, 
176140        term_for_bcb :  node_counters, 
177141        expressions, 
@@ -193,94 +157,3 @@ fn is_inlined(body: &Body<'_>, statement: &Statement<'_>) -> bool {
193157    let  scope_data = & body. source_scopes [ statement. source_info . scope ] ; 
194158    scope_data. inlined . is_some ( )  || scope_data. inlined_parent_scope . is_some ( ) 
195159} 
196- 
197- /// Identify expressions that will always have a value of zero, and note their 
198- /// IDs in a `DenseBitSet`. Mappings that refer to a zero expression can instead 
199- /// become mappings to a constant zero value. 
200- /// 
201- /// This function mainly exists to preserve the simplifications that were 
202- /// already being performed by the Rust-side expression renumbering, so that 
203- /// the resulting coverage mappings don't get worse. 
204- fn  identify_zero_expressions ( 
205-     expressions :  & IndexSlice < ExpressionId ,  Expression > , 
206-     counters_seen :  & DenseBitSet < CounterId > , 
207-     expressions_seen :  & DenseBitSet < ExpressionId > , 
208- )  -> DenseBitSet < ExpressionId >  { 
209-     // The set of expressions that either were optimized out entirely, or 
210-     // have zero as both of their operands, and will therefore always have 
211-     // a value of zero. Other expressions that refer to these as operands 
212-     // can have those operands replaced with `CovTerm::Zero`. 
213-     let  mut  zero_expressions = DenseBitSet :: new_empty ( expressions. len ( ) ) ; 
214- 
215-     // Simplify a copy of each expression based on lower-numbered expressions, 
216-     // and then update the set of always-zero expressions if necessary. 
217-     // (By construction, expressions can only refer to other expressions 
218-     // that have lower IDs, so one pass is sufficient.) 
219-     for  ( id,  expression)  in  expressions. iter_enumerated ( )  { 
220-         if  !expressions_seen. contains ( id)  { 
221-             // If an expression was not seen, it must have been optimized away, 
222-             // so any operand that refers to it can be replaced with zero. 
223-             zero_expressions. insert ( id) ; 
224-             continue ; 
225-         } 
226- 
227-         // We don't need to simplify the actual expression data in the 
228-         // expressions list; we can just simplify a temporary copy and then 
229-         // use that to update the set of always-zero expressions. 
230-         let  Expression  {  mut  lhs,  op,  mut  rhs }  = * expression; 
231- 
232-         // If an expression has an operand that is also an expression, the 
233-         // operand's ID must be strictly lower. This is what lets us find 
234-         // all zero expressions in one pass. 
235-         let  assert_operand_expression_is_lower = |operand_id :  ExpressionId | { 
236-             assert ! ( 
237-                 operand_id < id, 
238-                 "Operand {operand_id:?} should be less than {id:?} in {expression:?}" , 
239-             ) 
240-         } ; 
241- 
242-         // If an operand refers to a counter or expression that is always 
243-         // zero, then that operand can be replaced with `CovTerm::Zero`. 
244-         let  maybe_set_operand_to_zero = |operand :  & mut  CovTerm | { 
245-             if  let  CovTerm :: Expression ( id)  = * operand { 
246-                 assert_operand_expression_is_lower ( id) ; 
247-             } 
248- 
249-             if  is_zero_term ( & counters_seen,  & zero_expressions,  * operand)  { 
250-                 * operand = CovTerm :: Zero ; 
251-             } 
252-         } ; 
253-         maybe_set_operand_to_zero ( & mut  lhs) ; 
254-         maybe_set_operand_to_zero ( & mut  rhs) ; 
255- 
256-         // Coverage counter values cannot be negative, so if an expression 
257-         // involves subtraction from zero, assume that its RHS must also be zero. 
258-         // (Do this after simplifications that could set the LHS to zero.) 
259-         if  lhs == CovTerm :: Zero  && op == Op :: Subtract  { 
260-             rhs = CovTerm :: Zero ; 
261-         } 
262- 
263-         // After the above simplifications, if both operands are zero, then 
264-         // we know that this expression is always zero too. 
265-         if  lhs == CovTerm :: Zero  && rhs == CovTerm :: Zero  { 
266-             zero_expressions. insert ( id) ; 
267-         } 
268-     } 
269- 
270-     zero_expressions
271- } 
272- 
273- /// Returns `true` if the given term is known to have a value of zero, taking 
274- /// into account knowledge of which counters are unused and which expressions 
275- /// are always zero. 
276- fn  is_zero_term ( 
277-     counters_seen :  & DenseBitSet < CounterId > , 
278-     zero_expressions :  & DenseBitSet < ExpressionId > , 
279-     term :  CovTerm , 
280- )  -> bool  { 
281-     match  term { 
282-         CovTerm :: Zero  => true , 
283-         CovTerm :: Counter ( id)  => !counters_seen. contains ( id) , 
284-         CovTerm :: Expression ( id)  => zero_expressions. contains ( id) , 
285-     } 
286- } 
0 commit comments