@@ -59,7 +59,7 @@ use rustc::ty::layout::VariantIdx;
59
59
use rustc:: ty:: subst:: SubstsRef ;
60
60
use rustc_data_structures:: fx:: FxHashMap ;
61
61
use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
62
- use rustc_data_structures:: bit_set:: BitSet ;
62
+ use rustc_data_structures:: bit_set:: { BitSet , BitMatrix } ;
63
63
use std:: borrow:: Cow ;
64
64
use std:: iter;
65
65
use std:: mem;
@@ -408,7 +408,7 @@ struct LivenessInfo {
408
408
/// For every saved local, the set of other saved locals that are
409
409
/// storage-live at the same time as this local. We cannot overlap locals in
410
410
/// the layout which have conflicting storage.
411
- storage_conflicts : IndexVec < GeneratorSavedLocal , BitSet < GeneratorSavedLocal > > ,
411
+ storage_conflicts : BitMatrix < GeneratorSavedLocal , GeneratorSavedLocal > ,
412
412
413
413
/// For every suspending block, the locals which are storage-live across
414
414
/// that suspension point.
@@ -551,7 +551,9 @@ fn compute_storage_conflicts(
551
551
ignored : & StorageIgnored ,
552
552
storage_live : DataflowResults < ' tcx , MaybeStorageLive < ' mir , ' tcx > > ,
553
553
storage_live_analysis : MaybeStorageLive < ' mir , ' tcx > ,
554
- ) -> IndexVec < GeneratorSavedLocal , BitSet < GeneratorSavedLocal > > {
554
+ ) -> BitMatrix < GeneratorSavedLocal , GeneratorSavedLocal > {
555
+ assert_eq ! ( body. local_decls. len( ) , ignored. 0 . domain_size( ) ) ;
556
+ assert_eq ! ( body. local_decls. len( ) , stored_locals. domain_size( ) ) ;
555
557
debug ! ( "compute_storage_conflicts({:?})" , body. span) ;
556
558
debug ! ( "ignored = {:?}" , ignored. 0 ) ;
557
559
@@ -564,18 +566,15 @@ fn compute_storage_conflicts(
564
566
// liveness. Those that do must be in the same variant to remain candidates.
565
567
// FIXME(tmandry): Consider using sparse bitsets here once we have good
566
568
// benchmarks for generators.
567
- let mut local_conflicts: IndexVec < Local , _ > =
568
- // Add conflicts for every ineligible local.
569
- iter:: repeat ( ineligible_locals. clone ( ) )
570
- . take ( body. local_decls . len ( ) )
571
- . collect ( ) ;
569
+ let mut local_conflicts: BitMatrix < Local , Local > =
570
+ BitMatrix :: from_row_n ( & ineligible_locals, body. local_decls . len ( ) ) ;
572
571
573
572
for_each_location ( body, & storage_live_analysis, & storage_live, |state, loc| {
574
573
let mut eligible_storage_live = state. clone ( ) . to_dense ( ) ;
575
574
eligible_storage_live. intersect ( & stored_locals) ;
576
575
577
576
for local in eligible_storage_live. iter ( ) {
578
- local_conflicts[ local ] . union ( & eligible_storage_live) ;
577
+ local_conflicts. union_row_with ( & eligible_storage_live, local ) ;
579
578
}
580
579
581
580
if eligible_storage_live. count ( ) > 1 {
@@ -588,19 +587,22 @@ fn compute_storage_conflicts(
588
587
// However, in practice these bitsets are not usually large. The layout code
589
588
// also needs to keep track of how many conflicts each local has, so it's
590
589
// simpler to keep it this way for now.
591
- let storage_conflicts: IndexVec < GeneratorSavedLocal , _ > = stored_locals
592
- . iter ( )
593
- . map ( |local_a| {
594
- if ineligible_locals. contains ( local_a) {
595
- // Conflicts with everything.
596
- BitSet :: new_filled ( stored_locals. count ( ) )
597
- } else {
598
- // Keep overlap information only for stored locals.
599
- renumber_bitset ( & local_conflicts[ local_a] , stored_locals)
590
+ let mut storage_conflicts = BitMatrix :: new ( stored_locals. count ( ) , stored_locals. count ( ) ) ;
591
+ for ( idx_a, local_a) in stored_locals. iter ( ) . enumerate ( ) {
592
+ let saved_local_a = GeneratorSavedLocal :: new ( idx_a) ;
593
+ if ineligible_locals. contains ( local_a) {
594
+ // Conflicts with everything.
595
+ storage_conflicts. insert_all_into_row ( saved_local_a) ;
596
+ } else {
597
+ // Keep overlap information only for stored locals.
598
+ for ( idx_b, local_b) in stored_locals. iter ( ) . enumerate ( ) {
599
+ let saved_local_b = GeneratorSavedLocal :: new ( idx_b) ;
600
+ if local_conflicts. contains ( local_a, local_b) {
601
+ storage_conflicts. insert ( saved_local_a, saved_local_b) ;
602
+ }
600
603
}
601
- } )
602
- . collect ( ) ;
603
-
604
+ }
605
+ }
604
606
storage_conflicts
605
607
}
606
608
@@ -700,7 +702,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
700
702
variant_fields. push ( fields) ;
701
703
}
702
704
debug ! ( "generator variant_fields = {:?}" , variant_fields) ;
703
- debug ! ( "generator storage_conflicts = {:?}" , storage_conflicts) ;
705
+ debug ! ( "generator storage_conflicts = {:# ?}" , storage_conflicts) ;
704
706
705
707
let layout = GeneratorLayout {
706
708
field_tys : tys,
0 commit comments