deref related cleanups in ref_prop
This commit is contained in:
parent
0c0c58b8e4
commit
7ce81d1453
1 changed files with 13 additions and 20 deletions
|
|
@ -195,10 +195,10 @@ fn compute_replacement<'tcx>(
|
|||
// including DEF. This violates the DEF dominates USE condition, and so is impossible.
|
||||
let is_constant_place = |place: Place<'_>| {
|
||||
// We only allow `Deref` as the first projection, to avoid surprises.
|
||||
if place.projection.first() == Some(&PlaceElem::Deref) {
|
||||
if let Some((&PlaceElem::Deref, rest)) = place.projection.split_first() {
|
||||
// `place == (*some_local).xxx`, it is constant only if `some_local` is constant.
|
||||
// We approximate constness using SSAness.
|
||||
ssa.is_ssa(place.local) && place.projection[1..].iter().all(PlaceElem::is_stable_offset)
|
||||
ssa.is_ssa(place.local) && rest.iter().all(PlaceElem::is_stable_offset)
|
||||
} else {
|
||||
storage_live.has_single_storage(place.local)
|
||||
&& place.projection[..].iter().all(PlaceElem::is_stable_offset)
|
||||
|
|
@ -206,7 +206,7 @@ fn compute_replacement<'tcx>(
|
|||
};
|
||||
|
||||
let mut can_perform_opt = |target: Place<'tcx>, loc: Location| {
|
||||
if target.projection.first() == Some(&PlaceElem::Deref) {
|
||||
if target.is_indirect_first_projection() {
|
||||
// We are creating a reborrow. As `place.local` is a reference, removing the storage
|
||||
// statements should not make it much harder for LLVM to optimize.
|
||||
storage_to_remove.insert(target.local);
|
||||
|
|
@ -266,7 +266,7 @@ fn compute_replacement<'tcx>(
|
|||
Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
|
||||
let mut place = *place;
|
||||
// Try to see through `place` in order to collapse reborrow chains.
|
||||
if place.projection.first() == Some(&PlaceElem::Deref)
|
||||
if let Some((&PlaceElem::Deref, rest)) = place.projection.split_first()
|
||||
&& let Value::Pointer(target, inner_needs_unique) = targets[place.local]
|
||||
// Only see through immutable reference and pointers, as we do not know yet if
|
||||
// mutable references are fully replaced.
|
||||
|
|
@ -274,7 +274,7 @@ fn compute_replacement<'tcx>(
|
|||
// Only collapse chain if the pointee is definitely live.
|
||||
&& can_perform_opt(target, location)
|
||||
{
|
||||
place = target.project_deeper(&place.projection[1..], tcx);
|
||||
place = target.project_deeper(rest, tcx);
|
||||
}
|
||||
assert_ne!(place.local, local);
|
||||
if is_constant_place(place) {
|
||||
|
|
@ -323,7 +323,7 @@ fn compute_replacement<'tcx>(
|
|||
return;
|
||||
}
|
||||
|
||||
if place.projection.first() != Some(&PlaceElem::Deref) {
|
||||
if !place.is_indirect_first_projection() {
|
||||
// This is not a dereference, nothing to do.
|
||||
return;
|
||||
}
|
||||
|
|
@ -392,20 +392,15 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
|
|||
}
|
||||
|
||||
fn visit_var_debug_info(&mut self, debuginfo: &mut VarDebugInfo<'tcx>) {
|
||||
// If the debuginfo is a pointer to another place:
|
||||
// - if it's a reborrow, see through it;
|
||||
// - if it's a direct borrow, increase `debuginfo.references`.
|
||||
// If the debuginfo is a pointer to another place
|
||||
// and it's a reborrow: see through it
|
||||
while let VarDebugInfoContents::Place(ref mut place) = debuginfo.value
|
||||
&& place.projection.is_empty()
|
||||
&& let Value::Pointer(target, _) = self.targets[place.local]
|
||||
&& target.projection.iter().all(|p| p.can_use_in_debuginfo())
|
||||
&& let &[PlaceElem::Deref] = &target.projection[..]
|
||||
{
|
||||
if let Some((&PlaceElem::Deref, rest)) = target.projection.split_last() {
|
||||
*place = Place::from(target.local).project_deeper(rest, self.tcx);
|
||||
self.any_replacement = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
*place = Place::from(target.local);
|
||||
self.any_replacement = true;
|
||||
}
|
||||
|
||||
// Simplify eventual projections left inside `debuginfo`.
|
||||
|
|
@ -414,9 +409,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
|
|||
|
||||
fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) {
|
||||
loop {
|
||||
if place.projection.first() != Some(&PlaceElem::Deref) {
|
||||
return;
|
||||
}
|
||||
let Some((&PlaceElem::Deref, rest)) = place.projection.split_first() else { return };
|
||||
|
||||
let Value::Pointer(target, _) = self.targets[place.local] else { return };
|
||||
|
||||
|
|
@ -432,7 +425,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
*place = target.project_deeper(&place.projection[1..], self.tcx);
|
||||
*place = target.project_deeper(rest, self.tcx);
|
||||
self.any_replacement = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue