1
Fork 0

Simplify unscheduling of drops after moves

This commit is contained in:
Matthew Jasper 2020-10-05 22:10:37 +01:00
parent 2218520b8a
commit b766abc88f

View file

@ -121,8 +121,6 @@ struct Scope {
/// end of the vector (top of the stack) first. /// end of the vector (top of the stack) first.
drops: Vec<DropData>, drops: Vec<DropData>,
moved_locals: Vec<Local>,
/// The drop index that will drop everything in and below this scope on an /// The drop index that will drop everything in and below this scope on an
/// unwind path. /// unwind path.
cached_unwind_block: Option<DropIdx>, cached_unwind_block: Option<DropIdx>,
@ -406,7 +404,6 @@ impl<'tcx> Scopes<'tcx> {
region_scope: region_scope.0, region_scope: region_scope.0,
region_scope_span: region_scope.1.span, region_scope_span: region_scope.1.span,
drops: vec![], drops: vec![],
moved_locals: vec![],
cached_unwind_block: None, cached_unwind_block: None,
cached_generator_drop_block: None, cached_generator_drop_block: None,
}); });
@ -904,29 +901,32 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
return; return;
} }
Some(local_scope) => self Some(local_scope) => {
.scopes let top_scope = self.scopes.scopes.last_mut().unwrap();
.scopes assert!(
.iter_mut() top_scope.region_scope == local_scope,
.rfind(|scope| scope.region_scope == local_scope) "local scope ({:?}) is not the topmost scope!",
.unwrap_or_else(|| bug!("scope {:?} not found in scope list!", local_scope)), local_scope
);
top_scope
}
}; };
// look for moves of a local variable, like `MOVE(_X)` // look for moves of a local variable, like `MOVE(_X)`
let locals_moved = operands.iter().flat_map(|operand| match operand { let locals_moved = operands
Operand::Copy(_) | Operand::Constant(_) => None, .iter()
Operand::Move(place) => place.as_local(), .filter_map(|operand| match operand {
}); Operand::Copy(_) | Operand::Constant(_) => None,
Operand::Move(place) => place.as_local(),
})
.collect::<FxHashSet<_>>();
for local in locals_moved { // Remove the drops for the moved operands.
// check if we have a Drop for this operand and -- if so scope
// -- add it to the list of moved operands. Note that this .drops
// local might not have been an operand created for this .retain(|drop| drop.kind == DropKind::Storage || !locals_moved.contains(&drop.local));
// call, it could come from other places too. scope.invalidate_cache();
if scope.drops.iter().any(|drop| drop.local == local && drop.kind == DropKind::Value) {
scope.moved_locals.push(local);
}
}
} }
// Other // Other
@ -1174,14 +1174,6 @@ fn build_scope_drops<'tcx>(
debug_assert_eq!(unwind_drops.drops[unwind_to].0.kind, drop_data.kind); debug_assert_eq!(unwind_drops.drops[unwind_to].0.kind, drop_data.kind);
unwind_to = unwind_drops.drops[unwind_to].1; unwind_to = unwind_drops.drops[unwind_to].1;
// If the operand has been moved, and we are not on an unwind
// path, then don't generate the drop. (We only take this into
// account for non-unwind paths so as not to disturb the
// caching mechanism.)
if scope.moved_locals.iter().any(|&o| o == local) {
continue;
}
unwind_drops.add_entry(block, unwind_to); unwind_drops.add_entry(block, unwind_to);
let next = cfg.start_new_block(); let next = cfg.start_new_block();