5050//! Otherwise it drops all the values in scope at the last suspension point.
5151
5252use crate :: dataflow:: { self , Analysis } ;
53- use crate :: dataflow:: { MaybeBorrowedLocals , MaybeRequiresStorage , MaybeStorageLive } ;
53+ use crate :: dataflow:: {
54+ MaybeBorrowedLocals , MaybeLiveLocals , MaybeRequiresStorage , MaybeStorageLive ,
55+ } ;
5456use crate :: transform:: no_landing_pads:: no_landing_pads;
5557use crate :: transform:: simplify;
5658use crate :: transform:: { MirPass , MirSource } ;
5759use crate :: util:: dump_mir;
58- use crate :: util:: liveness;
5960use crate :: util:: storage;
6061use rustc_data_structures:: fx:: FxHashMap ;
6162use rustc_hir as hir;
@@ -195,7 +196,7 @@ struct SuspensionPoint<'tcx> {
195196 /// Which block to jump to if the generator is dropped in this state.
196197 drop : Option < BasicBlock > ,
197198 /// Set of locals that have live storage while at this suspension point.
198- storage_liveness : liveness :: LiveVarSet ,
199+ storage_liveness : BitSet < Local > ,
199200}
200201
201202struct TransformVisitor < ' tcx > {
@@ -211,7 +212,7 @@ struct TransformVisitor<'tcx> {
211212 remap : FxHashMap < Local , ( Ty < ' tcx > , VariantIdx , usize ) > ,
212213
213214 // A map from a suspension point in a block to the locals which have live storage at that point
214- storage_liveness : IndexVec < BasicBlock , Option < liveness :: LiveVarSet > > ,
215+ storage_liveness : IndexVec < BasicBlock , Option < BitSet < Local > > > ,
215216
216217 // A list of suspension points, generated during the transform
217218 suspension_points : Vec < SuspensionPoint < ' tcx > > ,
@@ -418,7 +419,7 @@ struct LivenessInfo {
418419 /// GeneratorSavedLocal is indexed in terms of the elements in this set;
419420 /// i.e. GeneratorSavedLocal::new(1) corresponds to the second local
420421 /// included in this set.
421- live_locals : liveness :: LiveVarSet ,
422+ live_locals : BitSet < Local > ,
422423
423424 /// The set of saved locals live at each suspension point.
424425 live_locals_at_suspension_points : Vec < BitSet < GeneratorSavedLocal > > ,
@@ -430,7 +431,7 @@ struct LivenessInfo {
430431
431432 /// For every suspending block, the locals which are storage-live across
432433 /// that suspension point.
433- storage_liveness : IndexVec < BasicBlock , Option < liveness :: LiveVarSet > > ,
434+ storage_liveness : IndexVec < BasicBlock , Option < BitSet < Local > > > ,
434435}
435436
436437fn locals_live_across_suspend_points (
@@ -467,18 +468,22 @@ fn locals_live_across_suspend_points(
467468 dataflow:: ResultsCursor :: new ( body_ref, & requires_storage_results) ;
468469
469470 // Calculate the liveness of MIR locals ignoring borrows.
470- let mut liveness = liveness:: liveness_of_locals ( body) ;
471- liveness:: dump_mir ( tcx, "generator_liveness" , source, body_ref, & liveness) ;
471+ let mut liveness = MaybeLiveLocals
472+ . into_engine ( tcx, body_ref, def_id)
473+ . iterate_to_fixpoint ( )
474+ . into_results_cursor ( body_ref) ;
472475
473476 let mut storage_liveness_map = IndexVec :: from_elem ( None , body. basic_blocks ( ) ) ;
474477 let mut live_locals_at_suspension_points = Vec :: new ( ) ;
475- let mut live_locals_at_any_suspension_point =
476- liveness:: LiveVarSet :: new_empty ( body. local_decls . len ( ) ) ;
478+ let mut live_locals_at_any_suspension_point = BitSet :: new_empty ( body. local_decls . len ( ) ) ;
477479
478480 for ( block, data) in body. basic_blocks ( ) . iter_enumerated ( ) {
479481 if let TerminatorKind :: Yield { .. } = data. terminator ( ) . kind {
480482 let loc = Location { block, statement_index : data. statements . len ( ) } ;
481483
484+ liveness. seek_to_block_end ( block) ;
485+ let mut live_locals = liveness. get ( ) . clone ( ) ;
486+
482487 if !movable {
483488 // The `liveness` variable contains the liveness of MIR locals ignoring borrows.
484489 // This is correct for movable generators since borrows cannot live across
@@ -491,22 +496,19 @@ fn locals_live_across_suspend_points(
491496 // forever. Note that the final liveness is still bounded by the storage liveness
492497 // of the local, which happens using the `intersect` operation below.
493498 borrowed_locals_cursor. seek_before_primary_effect ( loc) ;
494- liveness . outs [ block ] . union ( borrowed_locals_cursor. get ( ) ) ;
499+ live_locals . union ( borrowed_locals_cursor. get ( ) ) ;
495500 }
496501
497502 // Store the storage liveness for later use so we can restore the state
498503 // after a suspension point
499504 storage_live. seek_before_primary_effect ( loc) ;
500505 storage_liveness_map[ block] = Some ( storage_live. get ( ) . clone ( ) ) ;
501506
502- requires_storage_cursor. seek_before_primary_effect ( loc) ;
503- let storage_required = requires_storage_cursor. get ( ) . clone ( ) ;
504-
505507 // Locals live are live at this point only if they are used across
506508 // suspension points (the `liveness` variable)
507509 // and their storage is required (the `storage_required` variable)
508- let mut live_locals = storage_required ;
509- live_locals. intersect ( & liveness . outs [ block ] ) ;
510+ requires_storage_cursor . seek_before_primary_effect ( loc ) ;
511+ live_locals. intersect ( requires_storage_cursor . get ( ) ) ;
510512
511513 // The generator argument is ignored.
512514 live_locals. remove ( SELF_ARG ) ;
@@ -551,7 +553,7 @@ fn locals_live_across_suspend_points(
551553/// `[0, 1, 2]`. Thus, if `input = [3, 5]` we would return `[1, 2]`.
552554fn renumber_bitset (
553555 input : & BitSet < Local > ,
554- stored_locals : & liveness :: LiveVarSet ,
556+ stored_locals : & BitSet < Local > ,
555557) -> BitSet < GeneratorSavedLocal > {
556558 assert ! ( stored_locals. superset( & input) , "{:?} not a superset of {:?}" , stored_locals, input) ;
557559 let mut out = BitSet :: new_empty ( stored_locals. count ( ) ) ;
@@ -571,7 +573,7 @@ fn renumber_bitset(
571573/// computation; see `GeneratorLayout` for more.
572574fn compute_storage_conflicts (
573575 body : & ' mir Body < ' tcx > ,
574- stored_locals : & liveness :: LiveVarSet ,
576+ stored_locals : & BitSet < Local > ,
575577 always_live_locals : storage:: AlwaysLiveLocals ,
576578 requires_storage : dataflow:: Results < ' tcx , MaybeRequiresStorage < ' mir , ' tcx > > ,
577579) -> BitMatrix < GeneratorSavedLocal , GeneratorSavedLocal > {
@@ -626,7 +628,7 @@ fn compute_storage_conflicts(
626628
627629struct StorageConflictVisitor < ' mir , ' tcx , ' s > {
628630 body : & ' mir Body < ' tcx > ,
629- stored_locals : & ' s liveness :: LiveVarSet ,
631+ stored_locals : & ' s BitSet < Local > ,
630632 // FIXME(tmandry): Consider using sparse bitsets here once we have good
631633 // benchmarks for generators.
632634 local_conflicts : BitMatrix < Local , Local > ,
@@ -635,7 +637,7 @@ struct StorageConflictVisitor<'mir, 'tcx, 's> {
635637impl dataflow:: ResultsVisitor < ' mir , ' tcx > for StorageConflictVisitor < ' mir , ' tcx , ' _ > {
636638 type FlowState = BitSet < Local > ;
637639
638- fn visit_statement (
640+ fn visit_statement_before_primary_effect (
639641 & mut self ,
640642 state : & Self :: FlowState ,
641643 _statement : & ' mir Statement < ' tcx > ,
@@ -644,7 +646,7 @@ impl dataflow::ResultsVisitor<'mir, 'tcx> for StorageConflictVisitor<'mir, 'tcx,
644646 self . apply_state ( state, loc) ;
645647 }
646648
647- fn visit_terminator (
649+ fn visit_terminator_before_primary_effect (
648650 & mut self ,
649651 state : & Self :: FlowState ,
650652 _terminator : & ' mir Terminator < ' tcx > ,
@@ -685,7 +687,7 @@ fn compute_layout<'tcx>(
685687) -> (
686688 FxHashMap < Local , ( Ty < ' tcx > , VariantIdx , usize ) > ,
687689 GeneratorLayout < ' tcx > ,
688- IndexVec < BasicBlock , Option < liveness :: LiveVarSet > > ,
690+ IndexVec < BasicBlock , Option < BitSet < Local > > > ,
689691) {
690692 // Use a liveness analysis to compute locals which are live across a suspension point
691693 let LivenessInfo {
0 commit comments