29
29
30
30
use crate :: MirPass ;
31
31
use rustc_data_structures:: fx:: { FxHashSet , FxIndexSet } ;
32
+ use rustc_index:: bit_set:: BitSet ;
32
33
use rustc_index:: { Idx , IndexSlice , IndexVec } ;
33
34
use rustc_middle:: mir:: coverage:: * ;
34
35
use 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>) {
345
346
346
347
let basic_blocks = body. basic_blocks . as_mut ( ) ;
347
348
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
-
361
349
if tcx. sess . instrument_coverage ( ) {
362
- save_unreachable_coverage ( basic_blocks, source_scopes, used_blocks ) ;
350
+ save_unreachable_coverage ( basic_blocks, source_scopes, & reachable ) ;
363
351
}
364
352
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
+ } ) ;
366
365
367
366
for block in basic_blocks {
368
367
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>) {
404
403
fn save_unreachable_coverage (
405
404
basic_blocks : & mut IndexSlice < BasicBlock , BasicBlockData < ' _ > > ,
406
405
source_scopes : & IndexSlice < SourceScope , SourceScopeData < ' _ > > ,
407
- first_dead_block : usize ,
406
+ reachable : & BitSet < BasicBlock > ,
408
407
) {
409
408
// Identify instances that still have some live coverage counters left.
410
409
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] ;
412
412
for statement in & basic_block. statements {
413
413
let StatementKind :: Coverage ( coverage) = & statement. kind else { continue } ;
414
414
let CoverageKind :: Counter { .. } = coverage. kind else { continue } ;
@@ -417,7 +417,8 @@ fn save_unreachable_coverage(
417
417
}
418
418
}
419
419
420
- for block in & mut basic_blocks. raw [ ..first_dead_block] {
420
+ for bb in reachable. iter ( ) {
421
+ let block = & mut basic_blocks[ bb] ;
421
422
for statement in & mut block. statements {
422
423
let StatementKind :: Coverage ( _) = & statement. kind else { continue } ;
423
424
let instance = statement. source_info . scope . inlined_instance ( source_scopes) ;
@@ -433,7 +434,11 @@ fn save_unreachable_coverage(
433
434
434
435
// Retain coverage for instances that still have some live counters left.
435
436
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] ;
437
442
for statement in & dead_block. statements {
438
443
let StatementKind :: Coverage ( coverage) = & statement. kind else { continue } ;
439
444
let Some ( code_region) = & coverage. code_region else { continue } ;
0 commit comments