@@ -59,7 +59,7 @@ use rustc::ty::layout::VariantIdx;
5959use rustc:: ty:: subst:: SubstsRef ;
6060use rustc_data_structures:: fx:: FxHashMap ;
6161use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
62- use rustc_data_structures:: bit_set:: BitSet ;
62+ use rustc_data_structures:: bit_set:: { BitSet , BitMatrix } ;
6363use std:: borrow:: Cow ;
6464use std:: iter;
6565use std:: mem;
@@ -408,7 +408,7 @@ struct LivenessInfo {
408408 /// For every saved local, the set of other saved locals that are
409409 /// storage-live at the same time as this local. We cannot overlap locals in
410410 /// the layout which have conflicting storage.
411- storage_conflicts : IndexVec < GeneratorSavedLocal , BitSet < GeneratorSavedLocal > > ,
411+ storage_conflicts : BitMatrix < GeneratorSavedLocal , GeneratorSavedLocal > ,
412412
413413 /// For every suspending block, the locals which are storage-live across
414414 /// that suspension point.
@@ -551,7 +551,9 @@ fn compute_storage_conflicts(
551551 ignored : & StorageIgnored ,
552552 storage_live : DataflowResults < ' tcx , MaybeStorageLive < ' mir , ' tcx > > ,
553553 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( ) ) ;
555557 debug ! ( "compute_storage_conflicts({:?})" , body. span) ;
556558 debug ! ( "ignored = {:?}" , ignored. 0 ) ;
557559
@@ -564,18 +566,15 @@ fn compute_storage_conflicts(
564566 // liveness. Those that do must be in the same variant to remain candidates.
565567 // FIXME(tmandry): Consider using sparse bitsets here once we have good
566568 // 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 ( ) ) ;
572571
573572 for_each_location ( body, & storage_live_analysis, & storage_live, |state, loc| {
574573 let mut eligible_storage_live = state. clone ( ) . to_dense ( ) ;
575574 eligible_storage_live. intersect ( & stored_locals) ;
576575
577576 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 ) ;
579578 }
580579
581580 if eligible_storage_live. count ( ) > 1 {
@@ -588,19 +587,22 @@ fn compute_storage_conflicts(
588587 // However, in practice these bitsets are not usually large. The layout code
589588 // also needs to keep track of how many conflicts each local has, so it's
590589 // 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+ }
600603 }
601- } )
602- . collect ( ) ;
603-
604+ }
605+ }
604606 storage_conflicts
605607}
606608
@@ -700,7 +702,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
700702 variant_fields. push ( fields) ;
701703 }
702704 debug ! ( "generator variant_fields = {:?}" , variant_fields) ;
703- debug ! ( "generator storage_conflicts = {:?}" , storage_conflicts) ;
705+ debug ! ( "generator storage_conflicts = {:# ?}" , storage_conflicts) ;
704706
705707 let layout = GeneratorLayout {
706708 field_tys : tys,
0 commit comments