2929
3030use crate :: MirPass ;
3131use rustc_data_structures:: fx:: { FxHashSet , FxIndexSet } ;
32+ use rustc_index:: bit_set:: BitSet ;
3233use rustc_index:: { Idx , IndexSlice , IndexVec } ;
3334use rustc_middle:: mir:: coverage:: * ;
3435use rustc_middle:: mir:: visit:: { MutVisitor , MutatingUseContext , PlaceContext , Visitor } ;
@@ -345,24 +346,22 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
345346
346347 let basic_blocks = body. basic_blocks . as_mut ( ) ;
347348 let source_scopes = & body. source_scopes ;
348- let mut replacements: Vec < _ > = ( 0 ..num_blocks) . map ( BasicBlock :: new) . collect ( ) ;
349- let mut used_blocks = 0 ;
350- for alive_index in reachable. iter ( ) {
351- let alive_index = alive_index. index ( ) ;
352- replacements[ alive_index] = BasicBlock :: new ( used_blocks) ;
353- if alive_index != used_blocks {
354- // Swap the next alive block data with the current available slot. Since
355- // alive_index is non-decreasing this is a valid operation.
356- basic_blocks. raw . swap ( alive_index, used_blocks) ;
357- }
358- used_blocks += 1 ;
359- }
360-
361349 if tcx. sess . instrument_coverage ( ) {
362- save_unreachable_coverage ( basic_blocks, source_scopes, used_blocks ) ;
350+ save_unreachable_coverage ( basic_blocks, source_scopes, & reachable ) ;
363351 }
364352
365- basic_blocks. raw . truncate ( used_blocks) ;
353+ let mut replacements: Vec < _ > = ( 0 ..num_blocks) . map ( BasicBlock :: new) . collect ( ) ;
354+ let mut orig_index = 0 ;
355+ let mut used_index = 0 ;
356+ basic_blocks. raw . retain ( |_| {
357+ let keep = reachable. contains ( BasicBlock :: new ( orig_index) ) ;
358+ if keep {
359+ replacements[ orig_index] = BasicBlock :: new ( used_index) ;
360+ used_index += 1 ;
361+ }
362+ orig_index += 1 ;
363+ keep
364+ } ) ;
366365
367366 for block in basic_blocks {
368367 for target in block. terminator_mut ( ) . successors_mut ( ) {
@@ -404,11 +403,12 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
404403fn save_unreachable_coverage (
405404 basic_blocks : & mut IndexSlice < BasicBlock , BasicBlockData < ' _ > > ,
406405 source_scopes : & IndexSlice < SourceScope , SourceScopeData < ' _ > > ,
407- first_dead_block : usize ,
406+ reachable : & BitSet < BasicBlock > ,
408407) {
409408 // Identify instances that still have some live coverage counters left.
410409 let mut live = FxHashSet :: default ( ) ;
411- for basic_block in & basic_blocks. raw [ 0 ..first_dead_block] {
410+ for bb in reachable. iter ( ) {
411+ let basic_block = & basic_blocks[ bb] ;
412412 for statement in & basic_block. statements {
413413 let StatementKind :: Coverage ( coverage) = & statement. kind else { continue } ;
414414 let CoverageKind :: Counter { .. } = coverage. kind else { continue } ;
@@ -417,7 +417,8 @@ fn save_unreachable_coverage(
417417 }
418418 }
419419
420- for block in & mut basic_blocks. raw [ ..first_dead_block] {
420+ for bb in reachable. iter ( ) {
421+ let block = & mut basic_blocks[ bb] ;
421422 for statement in & mut block. statements {
422423 let StatementKind :: Coverage ( _) = & statement. kind else { continue } ;
423424 let instance = statement. source_info . scope . inlined_instance ( source_scopes) ;
@@ -433,7 +434,11 @@ fn save_unreachable_coverage(
433434
434435 // Retain coverage for instances that still have some live counters left.
435436 let mut retained_coverage = Vec :: new ( ) ;
436- for dead_block in & basic_blocks. raw [ first_dead_block..] {
437+ for dead_block in basic_blocks. indices ( ) {
438+ if reachable. contains ( dead_block) {
439+ continue ;
440+ }
441+ let dead_block = & basic_blocks[ dead_block] ;
437442 for statement in & dead_block. statements {
438443 let StatementKind :: Coverage ( coverage) = & statement. kind else { continue } ;
439444 let Some ( code_region) = & coverage. code_region else { continue } ;
0 commit comments