about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan MacKenzie <ecstaticmorse@gmail.com>2020-04-10 11:13:31 -0700
committerDylan MacKenzie <ecstaticmorse@gmail.com>2020-05-03 11:36:11 -0700
commit91003401c87148cc6fa41d29d72225c0a14a3a51 (patch)
tree03f4154a217b5019d329d94064ba36f99493c369
parent4c34ec6848b1e09624a521255d1ce69f9d62555e (diff)
downloadrust-91003401c87148cc6fa41d29d72225c0a14a3a51.tar.gz
rust-91003401c87148cc6fa41d29d72225c0a14a3a51.zip
Use new liveness analysis during generator transform
-rw-r--r--src/librustc_mir/transform/generator.rs46
1 files changed, 24 insertions, 22 deletions
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index a95c5bce5b1..25804c2a62c 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -50,12 +50,13 @@
 //! Otherwise it drops all the values in scope at the last suspension point.
 
 use crate::dataflow::{self, Analysis};
-use crate::dataflow::{MaybeBorrowedLocals, MaybeRequiresStorage, MaybeStorageLive};
+use crate::dataflow::{
+    MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive,
+};
 use crate::transform::no_landing_pads::no_landing_pads;
 use crate::transform::simplify;
 use crate::transform::{MirPass, MirSource};
 use crate::util::dump_mir;
-use crate::util::liveness;
 use crate::util::storage;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
@@ -195,7 +196,7 @@ struct SuspensionPoint<'tcx> {
     /// Which block to jump to if the generator is dropped in this state.
     drop: Option<BasicBlock>,
     /// Set of locals that have live storage while at this suspension point.
-    storage_liveness: liveness::LiveVarSet,
+    storage_liveness: BitSet<Local>,
 }
 
 struct TransformVisitor<'tcx> {
@@ -211,7 +212,7 @@ struct TransformVisitor<'tcx> {
     remap: FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>,
 
     // A map from a suspension point in a block to the locals which have live storage at that point
-    storage_liveness: IndexVec<BasicBlock, Option<liveness::LiveVarSet>>,
+    storage_liveness: IndexVec<BasicBlock, Option<BitSet<Local>>>,
 
     // A list of suspension points, generated during the transform
     suspension_points: Vec<SuspensionPoint<'tcx>>,
@@ -418,7 +419,7 @@ struct LivenessInfo {
     /// GeneratorSavedLocal is indexed in terms of the elements in this set;
     /// i.e. GeneratorSavedLocal::new(1) corresponds to the second local
     /// included in this set.
-    live_locals: liveness::LiveVarSet,
+    live_locals: BitSet<Local>,
 
     /// The set of saved locals live at each suspension point.
     live_locals_at_suspension_points: Vec<BitSet<GeneratorSavedLocal>>,
@@ -430,7 +431,7 @@ struct LivenessInfo {
 
     /// For every suspending block, the locals which are storage-live across
     /// that suspension point.
-    storage_liveness: IndexVec<BasicBlock, Option<liveness::LiveVarSet>>,
+    storage_liveness: IndexVec<BasicBlock, Option<BitSet<Local>>>,
 }
 
 fn locals_live_across_suspend_points(
@@ -467,18 +468,22 @@ fn locals_live_across_suspend_points(
         dataflow::ResultsCursor::new(body_ref, &requires_storage_results);
 
     // Calculate the liveness of MIR locals ignoring borrows.
-    let mut liveness = liveness::liveness_of_locals(body);
-    liveness::dump_mir(tcx, "generator_liveness", source, body_ref, &liveness);
+    let mut liveness = MaybeLiveLocals
+        .into_engine(tcx, body_ref, def_id)
+        .iterate_to_fixpoint()
+        .into_results_cursor(body_ref);
 
     let mut storage_liveness_map = IndexVec::from_elem(None, body.basic_blocks());
     let mut live_locals_at_suspension_points = Vec::new();
-    let mut live_locals_at_any_suspension_point =
-        liveness::LiveVarSet::new_empty(body.local_decls.len());
+    let mut live_locals_at_any_suspension_point = BitSet::new_empty(body.local_decls.len());
 
     for (block, data) in body.basic_blocks().iter_enumerated() {
         if let TerminatorKind::Yield { .. } = data.terminator().kind {
             let loc = Location { block, statement_index: data.statements.len() };
 
+            liveness.seek_to_block_end(block);
+            let mut live_locals = liveness.get().clone();
+
             if !movable {
                 // The `liveness` variable contains the liveness of MIR locals ignoring borrows.
                 // This is correct for movable generators since borrows cannot live across
@@ -491,7 +496,7 @@ fn locals_live_across_suspend_points(
                 // forever. Note that the final liveness is still bounded by the storage liveness
                 // of the local, which happens using the `intersect` operation below.
                 borrowed_locals_cursor.seek_before_primary_effect(loc);
-                liveness.outs[block].union(borrowed_locals_cursor.get());
+                live_locals.union(borrowed_locals_cursor.get());
             }
 
             // Store the storage liveness for later use so we can restore the state
@@ -499,14 +504,11 @@ fn locals_live_across_suspend_points(
             storage_live.seek_before_primary_effect(loc);
             storage_liveness_map[block] = Some(storage_live.get().clone());
 
-            requires_storage_cursor.seek_before_primary_effect(loc);
-            let storage_required = requires_storage_cursor.get().clone();
-
             // Locals live are live at this point only if they are used across
             // suspension points (the `liveness` variable)
             // and their storage is required (the `storage_required` variable)
-            let mut live_locals = storage_required;
-            live_locals.intersect(&liveness.outs[block]);
+            requires_storage_cursor.seek_before_primary_effect(loc);
+            live_locals.intersect(requires_storage_cursor.get());
 
             // The generator argument is ignored.
             live_locals.remove(SELF_ARG);
@@ -551,7 +553,7 @@ fn locals_live_across_suspend_points(
 /// `[0, 1, 2]`. Thus, if `input = [3, 5]` we would return `[1, 2]`.
 fn renumber_bitset(
     input: &BitSet<Local>,
-    stored_locals: &liveness::LiveVarSet,
+    stored_locals: &BitSet<Local>,
 ) -> BitSet<GeneratorSavedLocal> {
     assert!(stored_locals.superset(&input), "{:?} not a superset of {:?}", stored_locals, input);
     let mut out = BitSet::new_empty(stored_locals.count());
@@ -571,7 +573,7 @@ fn renumber_bitset(
 /// computation; see `GeneratorLayout` for more.
 fn compute_storage_conflicts(
     body: &'mir Body<'tcx>,
-    stored_locals: &liveness::LiveVarSet,
+    stored_locals: &BitSet<Local>,
     always_live_locals: storage::AlwaysLiveLocals,
     requires_storage: dataflow::Results<'tcx, MaybeRequiresStorage<'mir, 'tcx>>,
 ) -> BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal> {
@@ -626,7 +628,7 @@ fn compute_storage_conflicts(
 
 struct StorageConflictVisitor<'mir, 'tcx, 's> {
     body: &'mir Body<'tcx>,
-    stored_locals: &'s liveness::LiveVarSet,
+    stored_locals: &'s BitSet<Local>,
     // FIXME(tmandry): Consider using sparse bitsets here once we have good
     // benchmarks for generators.
     local_conflicts: BitMatrix<Local, Local>,
@@ -635,7 +637,7 @@ struct StorageConflictVisitor<'mir, 'tcx, 's> {
 impl dataflow::ResultsVisitor<'mir, 'tcx> for StorageConflictVisitor<'mir, 'tcx, '_> {
     type FlowState = BitSet<Local>;
 
-    fn visit_statement(
+    fn visit_statement_before_primary_effect(
         &mut self,
         state: &Self::FlowState,
         _statement: &'mir Statement<'tcx>,
@@ -644,7 +646,7 @@ impl dataflow::ResultsVisitor<'mir, 'tcx> for StorageConflictVisitor<'mir, 'tcx,
         self.apply_state(state, loc);
     }
 
-    fn visit_terminator(
+    fn visit_terminator_before_primary_effect(
         &mut self,
         state: &Self::FlowState,
         _terminator: &'mir Terminator<'tcx>,
@@ -685,7 +687,7 @@ fn compute_layout<'tcx>(
 ) -> (
     FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>,
     GeneratorLayout<'tcx>,
-    IndexVec<BasicBlock, Option<liveness::LiveVarSet>>,
+    IndexVec<BasicBlock, Option<BitSet<Local>>>,
 ) {
     // Use a liveness analysis to compute locals which are live across a suspension point
     let LivenessInfo {