about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDylan MacKenzie <ecstaticmorse@gmail.com>2020-02-12 13:41:26 -0800
committerDylan MacKenzie <ecstaticmorse@gmail.com>2020-02-12 14:45:18 -0800
commit1d737fb032b762e69e8d809c0e042d45e08b457d (patch)
treedc922aaf40eac547941cbbf15c20b7627c964b27 /src
parent9972502bafab062b06ef04c02c653f1b868937bd (diff)
downloadrust-1d737fb032b762e69e8d809c0e042d45e08b457d.tar.gz
rust-1d737fb032b762e69e8d809c0e042d45e08b457d.zip
Use `MaybeBorrowedLocals` for generator analyses
It should have the same semantics as `HaveBeenBorrowedLocals`
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/dataflow/impls/storage_liveness.rs46
-rw-r--r--src/librustc_mir/transform/generator.rs20
2 files changed, 27 insertions, 39 deletions
diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs
index 040c13e8210..7508d71945e 100644
--- a/src/librustc_mir/dataflow/impls/storage_liveness.rs
+++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs
@@ -1,8 +1,8 @@
 pub use super::*;
 
+use crate::dataflow::generic::{Results, ResultsRefCursor};
 use crate::dataflow::BitDenotation;
-use crate::dataflow::HaveBeenBorrowedLocals;
-use crate::dataflow::{DataflowResults, DataflowResultsCursor, DataflowResultsRefCursor};
+use crate::dataflow::MaybeBorrowedLocals;
 use rustc::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
 use rustc::mir::*;
 use std::cell::RefCell;
@@ -69,22 +69,23 @@ impl<'a, 'tcx> BottomValue for MaybeStorageLive<'a, 'tcx> {
     const BOTTOM_VALUE: bool = false;
 }
 
+type BorrowedLocalsResults<'a, 'tcx> = ResultsRefCursor<'a, 'a, 'tcx, MaybeBorrowedLocals>;
+
 /// Dataflow analysis that determines whether each local requires storage at a
 /// given location; i.e. whether its storage can go away without being observed.
 pub struct RequiresStorage<'mir, 'tcx> {
     body: ReadOnlyBodyAndCache<'mir, 'tcx>,
-    borrowed_locals:
-        RefCell<DataflowResultsRefCursor<'mir, 'tcx, HaveBeenBorrowedLocals<'mir, 'tcx>>>,
+    borrowed_locals: RefCell<BorrowedLocalsResults<'mir, 'tcx>>,
 }
 
 impl<'mir, 'tcx: 'mir> RequiresStorage<'mir, 'tcx> {
     pub fn new(
         body: ReadOnlyBodyAndCache<'mir, 'tcx>,
-        borrowed_locals: &'mir DataflowResults<'tcx, HaveBeenBorrowedLocals<'mir, 'tcx>>,
+        borrowed_locals: &'mir Results<'tcx, MaybeBorrowedLocals>,
     ) -> Self {
         RequiresStorage {
             body,
-            borrowed_locals: RefCell::new(DataflowResultsCursor::new(borrowed_locals, *body)),
+            borrowed_locals: RefCell::new(ResultsRefCursor::new(*body, borrowed_locals)),
         }
     }
 
@@ -111,11 +112,12 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
     }
 
     fn before_statement_effect(&self, sets: &mut GenKillSet<Self::Idx>, loc: Location) {
-        // If we borrow or assign to a place then it needs storage for that
-        // statement.
-        self.check_for_borrow(sets, loc);
-
         let stmt = &self.body[loc.block].statements[loc.statement_index];
+
+        // If a place is borrowed in a statement, it needs storage for that statement.
+        self.borrowed_locals.borrow().analysis().statement_effect(sets, stmt, loc);
+
+        // If a place is assigned to in a statement, it needs storage for that statement.
         match stmt.kind {
             StatementKind::StorageDead(l) => sets.kill(l),
             StatementKind::Assign(box (ref place, _))
@@ -138,12 +140,13 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
     }
 
     fn before_terminator_effect(&self, sets: &mut GenKillSet<Local>, loc: Location) {
-        self.check_for_borrow(sets, loc);
+        let terminator = self.body[loc.block].terminator();
 
-        if let TerminatorKind::Call { destination: Some((Place { local, .. }, _)), .. } =
-            self.body[loc.block].terminator().kind
-        {
-            sets.gen(local);
+        // If a place is borrowed in a terminator, it needs storage for that terminator.
+        self.borrowed_locals.borrow().analysis().terminator_effect(sets, terminator, loc);
+
+        if let TerminatorKind::Call { destination: Some((place, _)), .. } = terminator.kind {
+            sets.gen(place.local);
         }
     }
 
@@ -179,14 +182,6 @@ impl<'mir, 'tcx> RequiresStorage<'mir, 'tcx> {
         let mut visitor = MoveVisitor { sets, borrowed_locals: &self.borrowed_locals };
         visitor.visit_location(self.body, loc);
     }
-
-    /// Gen locals that are newly borrowed. This includes borrowing any part of
-    /// a local (we rely on this behavior of `HaveBeenBorrowedLocals`).
-    fn check_for_borrow(&self, sets: &mut GenKillSet<Local>, loc: Location) {
-        let mut borrowed_locals = self.borrowed_locals.borrow_mut();
-        borrowed_locals.seek(loc);
-        borrowed_locals.each_gen_bit(|l| sets.gen(l));
-    }
 }
 
 impl<'mir, 'tcx> BottomValue for RequiresStorage<'mir, 'tcx> {
@@ -195,8 +190,7 @@ impl<'mir, 'tcx> BottomValue for RequiresStorage<'mir, 'tcx> {
 }
 
 struct MoveVisitor<'a, 'mir, 'tcx> {
-    borrowed_locals:
-        &'a RefCell<DataflowResultsRefCursor<'mir, 'tcx, HaveBeenBorrowedLocals<'mir, 'tcx>>>,
+    borrowed_locals: &'a RefCell<BorrowedLocalsResults<'mir, 'tcx>>,
     sets: &'a mut GenKillSet<Local>,
 }
 
@@ -204,7 +198,7 @@ impl<'a, 'mir: 'a, 'tcx> Visitor<'tcx> for MoveVisitor<'a, 'mir, 'tcx> {
     fn visit_local(&mut self, local: &Local, context: PlaceContext, loc: Location) {
         if PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) == context {
             let mut borrowed_locals = self.borrowed_locals.borrow_mut();
-            borrowed_locals.seek(loc);
+            borrowed_locals.seek_before(loc);
             if !borrowed_locals.contains(*local) {
                 self.sets.kill(*local);
             }
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index a6fc6573178..cd00274afcc 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -49,9 +49,10 @@
 //! For generators with state 1 (returned) and state 2 (poisoned) it does nothing.
 //! Otherwise it drops all the values in scope at the last suspension point.
 
+use crate::dataflow::generic::{Analysis, ResultsCursor};
 use crate::dataflow::{do_dataflow, DataflowResultsCursor, DebugFormatted};
 use crate::dataflow::{DataflowResults, DataflowResultsConsumer, FlowAtLocation};
-use crate::dataflow::{HaveBeenBorrowedLocals, MaybeStorageLive, RequiresStorage};
+use crate::dataflow::{MaybeBorrowedLocals, MaybeStorageLive, RequiresStorage};
 use crate::transform::no_landing_pads::no_landing_pads;
 use crate::transform::simplify;
 use crate::transform::{MirPass, MirSource};
@@ -471,17 +472,10 @@ fn locals_live_across_suspend_points(
 
     // Calculate the MIR locals which have been previously
     // borrowed (even if they are still active).
-    let borrowed_locals_analysis = HaveBeenBorrowedLocals::new(body_ref);
-    let borrowed_locals_results = do_dataflow(
-        tcx,
-        body_ref,
-        def_id,
-        &[],
-        &dead_unwinds,
-        borrowed_locals_analysis,
-        |bd, p| DebugFormatted::new(&bd.body().local_decls[p]),
-    );
-    let mut borrowed_locals_cursor = DataflowResultsCursor::new(&borrowed_locals_results, body_ref);
+    let borrowed_locals_results =
+        MaybeBorrowedLocals::new().into_engine(tcx, body_ref, def_id).iterate_to_fixpoint();
+
+    let mut borrowed_locals_cursor = ResultsCursor::new(body_ref, &borrowed_locals_results);
 
     // Calculate the MIR locals that we actually need to keep storage around
     // for.
@@ -521,7 +515,7 @@ fn locals_live_across_suspend_points(
                 // If a borrow is converted to a raw reference, we must also assume that it lives
                 // 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(loc);
+                borrowed_locals_cursor.seek_before(loc);
                 liveness.outs[block].union(borrowed_locals_cursor.get());
             }