Simplify unscheduling of drops after moves
This commit is contained in:
parent
2218520b8a
commit
b766abc88f
1 changed files with 22 additions and 30 deletions
|
@ -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();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue