1
Fork 0

add new rval, pull deref early

This commit is contained in:
ouz-a 2022-06-13 16:37:41 +03:00
parent b3f4c31199
commit cb0017f2f8
41 changed files with 274 additions and 103 deletions

View file

@ -1,3 +1,4 @@
use crate::deref_separator::deref_finder;
use crate::MirPass;
use rustc_data_structures::fx::FxHashMap;
use rustc_index::bit_set::BitSet;
@ -9,6 +10,7 @@ use rustc_mir_dataflow::elaborate_drops::{DropElaborator, DropFlagMode, DropStyl
use rustc_mir_dataflow::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
use rustc_mir_dataflow::on_lookup_result_bits;
use rustc_mir_dataflow::un_derefer::UnDerefer;
use rustc_mir_dataflow::MoveDataParamEnv;
use rustc_mir_dataflow::{on_all_children_bits, on_all_drop_children_bits};
use rustc_mir_dataflow::{Analysis, ResultsCursor};
@ -26,6 +28,8 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
debug!("elaborate_drops({:?} @ {:?})", body.source, body.span);
let mut un_derefer = UnDerefer { tcx: tcx, derefer_sidetable: Default::default() };
un_derefer.ref_finder(body);
let def_id = body.source.def_id();
let param_env = tcx.param_env_reveal_all_normalized(def_id);
let move_data = match MoveData::gather_moves(body, tcx, param_env) {
@ -41,7 +45,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
let elaborate_patch = {
let body = &*body;
let env = MoveDataParamEnv { move_data, param_env };
let dead_unwinds = find_dead_unwinds(tcx, body, &env);
let dead_unwinds = find_dead_unwinds(tcx, body, &env, &un_derefer);
let inits = MaybeInitializedPlaces::new(tcx, body, &env)
.into_engine(tcx, body)
@ -65,10 +69,12 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
init_data: InitializationData { inits, uninits },
drop_flags: Default::default(),
patch: MirPatch::new(body),
un_derefer: un_derefer,
}
.elaborate()
};
elaborate_patch.apply(body);
deref_finder(tcx, body);
}
}
@ -79,6 +85,7 @@ fn find_dead_unwinds<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
env: &MoveDataParamEnv<'tcx>,
und: &UnDerefer<'tcx>,
) -> BitSet<BasicBlock> {
debug!("find_dead_unwinds({:?})", body.span);
// We only need to do this pass once, because unwind edges can only
@ -92,7 +99,9 @@ fn find_dead_unwinds<'tcx>(
for (bb, bb_data) in body.basic_blocks().iter_enumerated() {
let place = match bb_data.terminator().kind {
TerminatorKind::Drop { ref place, unwind: Some(_), .. }
| TerminatorKind::DropAndReplace { ref place, unwind: Some(_), .. } => place,
| TerminatorKind::DropAndReplace { ref place, unwind: Some(_), .. } => {
und.derefer(place.as_ref(), body).unwrap_or(*place)
}
_ => continue,
};
@ -256,6 +265,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
init_data: InitializationData<'a, 'tcx>,
drop_flags: FxHashMap<MovePathIndex, Local>,
patch: MirPatch<'tcx>,
un_derefer: UnDerefer<'tcx>,
}
impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
@ -298,7 +308,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
let terminator = data.terminator();
let place = match terminator.kind {
TerminatorKind::Drop { ref place, .. }
| TerminatorKind::DropAndReplace { ref place, .. } => place,
| TerminatorKind::DropAndReplace { ref place, .. } => {
self.un_derefer.derefer(place.as_ref(), self.body).unwrap_or(*place)
}
_ => continue,
};
@ -312,12 +324,17 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
LookupResult::Parent(None) => continue,
LookupResult::Parent(Some(parent)) => {
let (_maybe_live, maybe_dead) = self.init_data.maybe_live_dead(parent);
if self.body.local_decls[place.local].is_deref_temp() {
continue;
}
if maybe_dead {
self.tcx.sess.delay_span_bug(
terminator.source_info.span,
&format!(
"drop of untracked, uninitialized value {:?}, place {:?} ({:?})",
bb, place, path,
bb, place, path
),
);
}
@ -348,7 +365,11 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
let resume_block = self.patch.resume_block();
match terminator.kind {
TerminatorKind::Drop { place, target, unwind } => {
TerminatorKind::Drop { mut place, target, unwind } => {
if let Some(new_place) = self.un_derefer.derefer(place.as_ref(), self.body) {
place = new_place;
}
self.init_data.seek_before(loc);
match self.move_data().rev_lookup.find(place.as_ref()) {
LookupResult::Exact(path) => elaborate_drop(
@ -372,9 +393,12 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
}
}
}
TerminatorKind::DropAndReplace { place, ref value, target, unwind } => {
TerminatorKind::DropAndReplace { mut place, ref value, target, unwind } => {
assert!(!data.is_cleanup);
if let Some(new_place) = self.un_derefer.derefer(place.as_ref(), self.body) {
place = new_place;
}
self.elaborate_replace(loc, place, value, target, unwind);
}
_ => continue,