diff options
Diffstat (limited to 'compiler/rustc_mir_dataflow/src/impls')
-rw-r--r-- | compiler/rustc_mir_dataflow/src/impls/liveness.rs | 1 | ||||
-rw-r--r-- | compiler/rustc_mir_dataflow/src/impls/mod.rs | 4 | ||||
-rw-r--r-- | compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs | 67 |
3 files changed, 70 insertions, 2 deletions
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index 1309ea525..6ae6bdc17 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -197,6 +197,7 @@ impl DefUse { | NonMutatingUseContext::Copy | NonMutatingUseContext::Inspect | NonMutatingUseContext::Move + | NonMutatingUseContext::PlaceMention | NonMutatingUseContext::ShallowBorrow | NonMutatingUseContext::SharedBorrow, ) => Some(DefUse::Use), diff --git a/compiler/rustc_mir_dataflow/src/impls/mod.rs b/compiler/rustc_mir_dataflow/src/impls/mod.rs index 4b5324e20..171db6965 100644 --- a/compiler/rustc_mir_dataflow/src/impls/mod.rs +++ b/compiler/rustc_mir_dataflow/src/impls/mod.rs @@ -3,7 +3,7 @@ //! zero-sized structure. use rustc_index::bit_set::{BitSet, ChunkedBitSet}; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::mir::visit::{MirVisitable, Visitor}; use rustc_middle::mir::{self, Body, Location}; use rustc_middle::ty::{self, TyCtxt}; @@ -26,7 +26,7 @@ pub use self::borrowed_locals::borrowed_locals; pub use self::borrowed_locals::MaybeBorrowedLocals; pub use self::liveness::MaybeLiveLocals; pub use self::liveness::MaybeTransitiveLiveLocals; -pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageLive}; +pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageDead, MaybeStorageLive}; /// `MaybeInitializedPlaces` tracks all places that might be /// initialized upon reaching a particular point in the control flow diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 4a5d9d520..463ce083a 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -74,6 +74,73 @@ impl<'tcx, 'a> crate::GenKillAnalysis<'tcx> for MaybeStorageLive<'a> { } } +#[derive(Clone)] +pub struct MaybeStorageDead { + always_live_locals: BitSet<Local>, +} + +impl MaybeStorageDead { + pub fn new(always_live_locals: BitSet<Local>) -> Self { + MaybeStorageDead { always_live_locals } + } +} + +impl<'tcx> crate::AnalysisDomain<'tcx> for MaybeStorageDead { + type Domain = BitSet<Local>; + + const NAME: &'static str = "maybe_storage_dead"; + + fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain { + // bottom = live + BitSet::new_empty(body.local_decls.len()) + } + + fn initialize_start_block(&self, body: &mir::Body<'tcx>, on_entry: &mut Self::Domain) { + assert_eq!(body.local_decls.len(), self.always_live_locals.domain_size()); + // Do not iterate on return place and args, as they are trivially always live. + for local in body.vars_and_temps_iter() { + if !self.always_live_locals.contains(local) { + on_entry.insert(local); + } + } + } +} + +impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageDead { + type Idx = Local; + + fn statement_effect( + &self, + trans: &mut impl GenKill<Self::Idx>, + stmt: &mir::Statement<'tcx>, + _: Location, + ) { + match stmt.kind { + StatementKind::StorageLive(l) => trans.kill(l), + StatementKind::StorageDead(l) => trans.gen(l), + _ => (), + } + } + + fn terminator_effect( + &self, + _trans: &mut impl GenKill<Self::Idx>, + _: &mir::Terminator<'tcx>, + _: Location, + ) { + // Terminators have no effect + } + + fn call_return_effect( + &self, + _trans: &mut impl GenKill<Self::Idx>, + _block: BasicBlock, + _return_places: CallReturnPlaces<'_, 'tcx>, + ) { + // Nothing to do when a call returns successfully + } +} + type BorrowedLocalsResults<'a, 'tcx> = ResultsRefCursor<'a, 'a, 'tcx, MaybeBorrowedLocals>; /// Dataflow analysis that determines whether each local requires storage at a |