1
Fork 0

Parametrize gather_moves by filter.

This commit is contained in:
Camille GILLOT 2023-09-30 20:55:15 +00:00
parent 4bedd7de6e
commit 252c64722f
6 changed files with 89 additions and 65 deletions

View file

@ -219,10 +219,10 @@ fn do_mir_borrowck<'tcx>(
let location_table_owned = LocationTable::new(body); let location_table_owned = LocationTable::new(body);
let location_table = &location_table_owned; let location_table = &location_table_owned;
let move_data = MoveData::gather_moves(&body, tcx, param_env); let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
let promoted_move_data = promoted let promoted_move_data = promoted
.iter_enumerated() .iter_enumerated()
.map(|(idx, body)| (idx, MoveData::gather_moves(&body, tcx, param_env))); .map(|(idx, body)| (idx, MoveData::gather_moves(&body, tcx, param_env, |_| true)));
let mdpe = MoveDataParamEnv { move_data, param_env }; let mdpe = MoveDataParamEnv { move_data, param_env };

View file

@ -1,7 +1,7 @@
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_middle::mir::tcx::RvalueInitializationState; use rustc_middle::mir::tcx::{PlaceTy, RvalueInitializationState};
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
use std::mem; use std::mem;
@ -12,19 +12,49 @@ use super::{
LocationMap, MoveData, MoveOut, MoveOutIndex, MovePath, MovePathIndex, MovePathLookup, LocationMap, MoveData, MoveOut, MoveOutIndex, MovePath, MovePathIndex, MovePathLookup,
}; };
struct MoveDataBuilder<'a, 'tcx> { struct MoveDataBuilder<'a, 'tcx, F> {
body: &'a Body<'tcx>, body: &'a Body<'tcx>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
data: MoveData<'tcx>, data: MoveData<'tcx>,
filter: F,
} }
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F>
fn new(body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self { where
F: Fn(Ty<'tcx>) -> bool,
{
fn new(
body: &'a Body<'tcx>,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
filter: F,
) -> Self {
let mut move_paths = IndexVec::new(); let mut move_paths = IndexVec::new();
let mut path_map = IndexVec::new(); let mut path_map = IndexVec::new();
let mut init_path_map = IndexVec::new(); let mut init_path_map = IndexVec::new();
let locals = body
.local_decls
.iter_enumerated()
.map(|(i, l)| {
if l.is_deref_temp() {
return None;
}
if filter(l.ty) {
Some(new_move_path(
&mut move_paths,
&mut path_map,
&mut init_path_map,
None,
Place::from(i),
))
} else {
None
}
})
.collect();
MoveDataBuilder { MoveDataBuilder {
body, body,
tcx, tcx,
@ -33,23 +63,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
moves: IndexVec::new(), moves: IndexVec::new(),
loc_map: LocationMap::new(body), loc_map: LocationMap::new(body),
rev_lookup: MovePathLookup { rev_lookup: MovePathLookup {
locals: body locals,
.local_decls
.iter_enumerated()
.map(|(i, l)| {
if l.is_deref_temp() {
None
} else {
Some(Self::new_move_path(
&mut move_paths,
&mut path_map,
&mut init_path_map,
None,
Place::from(i),
))
}
})
.collect(),
projections: Default::default(), projections: Default::default(),
un_derefer: Default::default(), un_derefer: Default::default(),
}, },
@ -59,32 +73,33 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
init_loc_map: LocationMap::new(body), init_loc_map: LocationMap::new(body),
init_path_map, init_path_map,
}, },
filter,
} }
} }
}
fn new_move_path( fn new_move_path<'tcx>(
move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>, move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>,
path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>, path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>,
init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>, init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>,
parent: Option<MovePathIndex>, parent: Option<MovePathIndex>,
place: Place<'tcx>, place: Place<'tcx>,
) -> MovePathIndex { ) -> MovePathIndex {
let move_path = let move_path =
move_paths.push(MovePath { next_sibling: None, first_child: None, parent, place }); move_paths.push(MovePath { next_sibling: None, first_child: None, parent, place });
if let Some(parent) = parent { if let Some(parent) = parent {
let next_sibling = mem::replace(&mut move_paths[parent].first_child, Some(move_path)); let next_sibling = mem::replace(&mut move_paths[parent].first_child, Some(move_path));
move_paths[move_path].next_sibling = next_sibling; move_paths[move_path].next_sibling = next_sibling;
}
let path_map_ent = path_map.push(smallvec![]);
assert_eq!(path_map_ent, move_path);
let init_path_map_ent = init_path_map.push(smallvec![]);
assert_eq!(init_path_map_ent, move_path);
move_path
} }
let path_map_ent = path_map.push(smallvec![]);
assert_eq!(path_map_ent, move_path);
let init_path_map_ent = init_path_map.push(smallvec![]);
assert_eq!(init_path_map_ent, move_path);
move_path
} }
enum MovePathResult { enum MovePathResult {
@ -93,7 +108,10 @@ enum MovePathResult {
Error, Error,
} }
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { impl<'b, 'a, 'tcx, F> Gatherer<'b, 'a, 'tcx, F>
where
F: Fn(Ty<'tcx>) -> bool,
{
/// This creates a MovePath for a given place, returning an `MovePathError` /// This creates a MovePath for a given place, returning an `MovePathError`
/// if that place can't be moved from. /// if that place can't be moved from.
/// ///
@ -214,11 +232,15 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
| ProjectionElem::Subtype(_) | ProjectionElem::Subtype(_)
| ProjectionElem::Downcast(_, _) => (), | ProjectionElem::Downcast(_, _) => (),
} }
let elem_ty = PlaceTy::from_ty(place_ty).projection_ty(tcx, elem).ty;
if !(self.builder.filter)(elem_ty) {
return MovePathResult::Error;
}
if union_path.is_none() { if union_path.is_none() {
// inlined from add_move_path because of a borrowck conflict with the iterator // inlined from add_move_path because of a borrowck conflict with the iterator
base = base =
*data.rev_lookup.projections.entry((base, elem.lift())).or_insert_with(|| { *data.rev_lookup.projections.entry((base, elem.lift())).or_insert_with(|| {
MoveDataBuilder::new_move_path( new_move_path(
&mut data.move_paths, &mut data.move_paths,
&mut data.path_map, &mut data.path_map,
&mut data.init_path_map, &mut data.init_path_map,
@ -249,13 +271,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
.. ..
} = self.builder; } = self.builder;
*rev_lookup.projections.entry((base, elem.lift())).or_insert_with(move || { *rev_lookup.projections.entry((base, elem.lift())).or_insert_with(move || {
MoveDataBuilder::new_move_path( new_move_path(move_paths, path_map, init_path_map, Some(base), mk_place(*tcx))
move_paths,
path_map,
init_path_map,
Some(base),
mk_place(*tcx),
)
}) })
} }
@ -266,7 +282,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
} }
} }
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F> {
fn finalize(self) -> MoveData<'tcx> { fn finalize(self) -> MoveData<'tcx> {
debug!("{}", { debug!("{}", {
debug!("moves for {:?}:", self.body.span); debug!("moves for {:?}:", self.body.span);
@ -288,8 +304,9 @@ pub(super) fn gather_moves<'tcx>(
body: &Body<'tcx>, body: &Body<'tcx>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
filter: impl Fn(Ty<'tcx>) -> bool,
) -> MoveData<'tcx> { ) -> MoveData<'tcx> {
let mut builder = MoveDataBuilder::new(body, tcx, param_env); let mut builder = MoveDataBuilder::new(body, tcx, param_env, filter);
builder.gather_args(); builder.gather_args();
@ -306,7 +323,10 @@ pub(super) fn gather_moves<'tcx>(
builder.finalize() builder.finalize()
} }
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F>
where
F: Fn(Ty<'tcx>) -> bool,
{
fn gather_args(&mut self) { fn gather_args(&mut self) {
for arg in self.body.args_iter() { for arg in self.body.args_iter() {
if let Some(path) = self.data.rev_lookup.find_local(arg) { if let Some(path) = self.data.rev_lookup.find_local(arg) {
@ -334,12 +354,15 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
} }
} }
struct Gatherer<'b, 'a, 'tcx> { struct Gatherer<'b, 'a, 'tcx, F> {
builder: &'b mut MoveDataBuilder<'a, 'tcx>, builder: &'b mut MoveDataBuilder<'a, 'tcx, F>,
loc: Location, loc: Location,
} }
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { impl<'b, 'a, 'tcx, F> Gatherer<'b, 'a, 'tcx, F>
where
F: Fn(Ty<'tcx>) -> bool,
{
fn gather_statement(&mut self, stmt: &Statement<'tcx>) { fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
match &stmt.kind { match &stmt.kind {
StatementKind::Assign(box (place, Rvalue::CopyForDeref(reffed))) => { StatementKind::Assign(box (place, Rvalue::CopyForDeref(reffed))) => {

View file

@ -2,7 +2,7 @@ use crate::un_derefer::UnDerefer;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_index::{IndexSlice, IndexVec}; use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::{ParamEnv, TyCtxt}; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
use rustc_span::Span; use rustc_span::Span;
use smallvec::SmallVec; use smallvec::SmallVec;
@ -351,8 +351,9 @@ impl<'tcx> MoveData<'tcx> {
body: &Body<'tcx>, body: &Body<'tcx>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
filter: impl Fn(Ty<'tcx>) -> bool,
) -> MoveData<'tcx> { ) -> MoveData<'tcx> {
builder::gather_moves(body, tcx, param_env) builder::gather_moves(body, tcx, param_env, filter)
} }
/// For the move path `mpi`, returns the root local variable (if any) that starts the path. /// For the move path `mpi`, returns the root local variable (if any) that starts the path.

View file

@ -34,7 +34,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
} }
let param_env = tcx.param_env(def_id); let param_env = tcx.param_env(def_id);
let move_data = MoveData::gather_moves(body, tcx, param_env); let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
let mdpe = MoveDataParamEnv { move_data, param_env }; let mdpe = MoveDataParamEnv { move_data, param_env };
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() { if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() {

View file

@ -54,7 +54,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
let def_id = body.source.def_id(); let def_id = body.source.def_id();
let param_env = tcx.param_env_reveal_all_normalized(def_id); let param_env = tcx.param_env_reveal_all_normalized(def_id);
let move_data = MoveData::gather_moves(body, tcx, param_env); let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
let elaborate_patch = { let elaborate_patch = {
let env = MoveDataParamEnv { move_data, param_env }; let env = MoveDataParamEnv { move_data, param_env };

View file

@ -24,7 +24,7 @@ pub struct RemoveUninitDrops;
impl<'tcx> MirPass<'tcx> for RemoveUninitDrops { impl<'tcx> MirPass<'tcx> for RemoveUninitDrops {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let param_env = tcx.param_env(body.source.def_id()); let param_env = tcx.param_env(body.source.def_id());
let move_data = MoveData::gather_moves(body, tcx, param_env); let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
let mdpe = MoveDataParamEnv { move_data, param_env }; let mdpe = MoveDataParamEnv { move_data, param_env };
let mut maybe_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe) let mut maybe_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe)