Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 157631b

Browse files
Remove MaybeRequiresStorage
1 parent 3508592 commit 157631b

File tree

2 files changed

+2
-234
lines changed

2 files changed

+2
-234
lines changed

src/librustc_mir/dataflow/impls/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub use self::borrowed_locals::{MaybeBorrowedLocals, MaybeMutBorrowedLocals};
3030
pub use self::borrows::Borrows;
3131
pub use self::init_locals::MaybeInitializedLocals;
3232
pub use self::liveness::MaybeLiveLocals;
33-
pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageLive};
33+
pub use self::storage_liveness::MaybeStorageLive;
3434

3535
/// `MaybeInitializedPlaces` tracks all places that might be
3636
/// initialized upon reaching a particular point in the control flow
Lines changed: 1 addition & 233 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
pub use super::*;
22

33
use crate::dataflow::BottomValue;
4-
use crate::dataflow::{self, GenKill, Results, ResultsRefCursor};
4+
use crate::dataflow::{self, GenKill};
55
use crate::util::storage::AlwaysLiveLocals;
6-
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
76
use rustc_middle::mir::*;
8-
use std::cell::RefCell;
97

108
#[derive(Clone)]
119
pub struct MaybeStorageLive {
@@ -78,233 +76,3 @@ impl BottomValue for MaybeStorageLive {
7876
/// bottom = dead
7977
const BOTTOM_VALUE: bool = false;
8078
}
81-
82-
type BorrowedLocalsResults<'a, 'tcx> = ResultsRefCursor<'a, 'a, 'tcx, MaybeBorrowedLocals>;
83-
84-
/// Dataflow analysis that determines whether each local requires storage at a
85-
/// given location; i.e. whether its storage can go away without being observed.
86-
pub struct MaybeRequiresStorage<'mir, 'tcx> {
87-
body: &'mir Body<'tcx>,
88-
borrowed_locals: RefCell<BorrowedLocalsResults<'mir, 'tcx>>,
89-
}
90-
91-
impl<'mir, 'tcx> MaybeRequiresStorage<'mir, 'tcx> {
92-
pub fn new(
93-
body: &'mir Body<'tcx>,
94-
borrowed_locals: &'mir Results<'tcx, MaybeBorrowedLocals>,
95-
) -> Self {
96-
MaybeRequiresStorage {
97-
body,
98-
borrowed_locals: RefCell::new(ResultsRefCursor::new(&body, borrowed_locals)),
99-
}
100-
}
101-
}
102-
103-
impl<'mir, 'tcx> dataflow::AnalysisDomain<'tcx> for MaybeRequiresStorage<'mir, 'tcx> {
104-
type Idx = Local;
105-
106-
const NAME: &'static str = "requires_storage";
107-
108-
fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize {
109-
body.local_decls.len()
110-
}
111-
112-
fn initialize_start_block(&self, body: &mir::Body<'tcx>, on_entry: &mut BitSet<Self::Idx>) {
113-
// The resume argument is live on function entry (we don't care about
114-
// the `self` argument)
115-
for arg in body.args_iter().skip(1) {
116-
on_entry.insert(arg);
117-
}
118-
}
119-
}
120-
121-
impl<'mir, 'tcx> dataflow::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tcx> {
122-
fn before_statement_effect(
123-
&self,
124-
trans: &mut impl GenKill<Self::Idx>,
125-
stmt: &mir::Statement<'tcx>,
126-
loc: Location,
127-
) {
128-
// If a place is borrowed in a statement, it needs storage for that statement.
129-
self.borrowed_locals.borrow().analysis().statement_effect(trans, stmt, loc);
130-
131-
match &stmt.kind {
132-
StatementKind::StorageDead(l) => trans.kill(*l),
133-
134-
// If a place is assigned to in a statement, it needs storage for that statement.
135-
StatementKind::Assign(box (place, _))
136-
| StatementKind::SetDiscriminant { box place, .. } => {
137-
trans.gen(place.local);
138-
}
139-
StatementKind::LlvmInlineAsm(asm) => {
140-
for place in &*asm.outputs {
141-
trans.gen(place.local);
142-
}
143-
}
144-
145-
// Nothing to do for these. Match exhaustively so this fails to compile when new
146-
// variants are added.
147-
StatementKind::AscribeUserType(..)
148-
| StatementKind::FakeRead(..)
149-
| StatementKind::Nop
150-
| StatementKind::Retag(..)
151-
| StatementKind::StorageLive(..) => {}
152-
}
153-
}
154-
155-
fn statement_effect(
156-
&self,
157-
trans: &mut impl GenKill<Self::Idx>,
158-
_: &mir::Statement<'tcx>,
159-
loc: Location,
160-
) {
161-
// If we move from a place then only stops needing storage *after*
162-
// that statement.
163-
self.check_for_move(trans, loc);
164-
}
165-
166-
fn before_terminator_effect(
167-
&self,
168-
trans: &mut impl GenKill<Self::Idx>,
169-
terminator: &mir::Terminator<'tcx>,
170-
loc: Location,
171-
) {
172-
// If a place is borrowed in a terminator, it needs storage for that terminator.
173-
self.borrowed_locals.borrow().analysis().terminator_effect(trans, terminator, loc);
174-
175-
match &terminator.kind {
176-
TerminatorKind::Call { destination: Some((place, _)), .. } => {
177-
trans.gen(place.local);
178-
}
179-
180-
// Note that we do *not* gen the `resume_arg` of `Yield` terminators. The reason for
181-
// that is that a `yield` will return from the function, and `resume_arg` is written
182-
// only when the generator is later resumed. Unlike `Call`, this doesn't require the
183-
// place to have storage *before* the yield, only after.
184-
TerminatorKind::Yield { .. } => {}
185-
186-
TerminatorKind::InlineAsm { operands, .. } => {
187-
for op in operands {
188-
match op {
189-
InlineAsmOperand::Out { place, .. }
190-
| InlineAsmOperand::InOut { out_place: place, .. } => {
191-
if let Some(place) = place {
192-
trans.gen(place.local);
193-
}
194-
}
195-
InlineAsmOperand::In { .. }
196-
| InlineAsmOperand::Const { .. }
197-
| InlineAsmOperand::SymFn { .. }
198-
| InlineAsmOperand::SymStatic { .. } => {}
199-
}
200-
}
201-
}
202-
203-
// Nothing to do for these. Match exhaustively so this fails to compile when new
204-
// variants are added.
205-
TerminatorKind::Call { destination: None, .. }
206-
| TerminatorKind::Abort
207-
| TerminatorKind::Assert { .. }
208-
| TerminatorKind::Drop { .. }
209-
| TerminatorKind::DropAndReplace { .. }
210-
| TerminatorKind::FalseEdges { .. }
211-
| TerminatorKind::FalseUnwind { .. }
212-
| TerminatorKind::GeneratorDrop
213-
| TerminatorKind::Goto { .. }
214-
| TerminatorKind::Resume
215-
| TerminatorKind::Return
216-
| TerminatorKind::SwitchInt { .. }
217-
| TerminatorKind::Unreachable => {}
218-
}
219-
}
220-
221-
fn terminator_effect(
222-
&self,
223-
trans: &mut impl GenKill<Self::Idx>,
224-
terminator: &mir::Terminator<'tcx>,
225-
loc: Location,
226-
) {
227-
match &terminator.kind {
228-
// For call terminators the destination requires storage for the call
229-
// and after the call returns successfully, but not after a panic.
230-
// Since `propagate_call_unwind` doesn't exist, we have to kill the
231-
// destination here, and then gen it again in `call_return_effect`.
232-
TerminatorKind::Call { destination: Some((place, _)), .. } => {
233-
trans.kill(place.local);
234-
}
235-
236-
// Nothing to do for these. Match exhaustively so this fails to compile when new
237-
// variants are added.
238-
TerminatorKind::Call { destination: None, .. }
239-
| TerminatorKind::Yield { .. }
240-
| TerminatorKind::Abort
241-
| TerminatorKind::Assert { .. }
242-
| TerminatorKind::Drop { .. }
243-
| TerminatorKind::DropAndReplace { .. }
244-
| TerminatorKind::FalseEdges { .. }
245-
| TerminatorKind::FalseUnwind { .. }
246-
| TerminatorKind::GeneratorDrop
247-
| TerminatorKind::Goto { .. }
248-
| TerminatorKind::InlineAsm { .. }
249-
| TerminatorKind::Resume
250-
| TerminatorKind::Return
251-
| TerminatorKind::SwitchInt { .. }
252-
| TerminatorKind::Unreachable => {}
253-
}
254-
255-
self.check_for_move(trans, loc);
256-
}
257-
258-
fn call_return_effect(
259-
&self,
260-
trans: &mut impl GenKill<Self::Idx>,
261-
_block: BasicBlock,
262-
_func: &mir::Operand<'tcx>,
263-
_args: &[mir::Operand<'tcx>],
264-
return_place: mir::Place<'tcx>,
265-
) {
266-
trans.gen(return_place.local);
267-
}
268-
269-
fn yield_resume_effect(
270-
&self,
271-
trans: &mut impl GenKill<Self::Idx>,
272-
_resume_block: BasicBlock,
273-
resume_place: mir::Place<'tcx>,
274-
) {
275-
trans.gen(resume_place.local);
276-
}
277-
}
278-
279-
impl<'mir, 'tcx> MaybeRequiresStorage<'mir, 'tcx> {
280-
/// Kill locals that are fully moved and have not been borrowed.
281-
fn check_for_move(&self, trans: &mut impl GenKill<Local>, loc: Location) {
282-
let mut visitor = MoveVisitor { trans, borrowed_locals: &self.borrowed_locals };
283-
visitor.visit_location(&self.body, loc);
284-
}
285-
}
286-
287-
impl<'mir, 'tcx> BottomValue for MaybeRequiresStorage<'mir, 'tcx> {
288-
/// bottom = dead
289-
const BOTTOM_VALUE: bool = false;
290-
}
291-
292-
struct MoveVisitor<'a, 'mir, 'tcx, T> {
293-
borrowed_locals: &'a RefCell<BorrowedLocalsResults<'mir, 'tcx>>,
294-
trans: &'a mut T,
295-
}
296-
297-
impl<'a, 'mir, 'tcx, T> Visitor<'tcx> for MoveVisitor<'a, 'mir, 'tcx, T>
298-
where
299-
T: GenKill<Local>,
300-
{
301-
fn visit_local(&mut self, local: &Local, context: PlaceContext, loc: Location) {
302-
if PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) == context {
303-
let mut borrowed_locals = self.borrowed_locals.borrow_mut();
304-
borrowed_locals.seek_before_primary_effect(loc);
305-
if !borrowed_locals.contains(*local) {
306-
self.trans.kill(*local);
307-
}
308-
}
309-
}
310-
}

0 commit comments

Comments
 (0)