Only introduce stable projections.
This commit is contained in:
parent
109edab245
commit
d9caf840e1
4 changed files with 15 additions and 9 deletions
|
@ -980,7 +980,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(place) = self.try_as_place(copy_from_local_value, location) {
|
// Allow introducing places with non-constant offsets, as those are still better than
|
||||||
|
// reconstructing an aggregate.
|
||||||
|
if let Some(place) = self.try_as_place(copy_from_local_value, location, true) {
|
||||||
if rvalue.ty(self.local_decls, self.tcx) == place.ty(self.local_decls, self.tcx).ty {
|
if rvalue.ty(self.local_decls, self.tcx) == place.ty(self.local_decls, self.tcx).ty {
|
||||||
self.reused_locals.insert(place.local);
|
self.reused_locals.insert(place.local);
|
||||||
*rvalue = Rvalue::Use(Operand::Copy(place));
|
*rvalue = Rvalue::Use(Operand::Copy(place));
|
||||||
|
@ -1665,7 +1667,7 @@ impl<'tcx> VnState<'_, 'tcx> {
|
||||||
fn try_as_operand(&mut self, index: VnIndex, location: Location) -> Option<Operand<'tcx>> {
|
fn try_as_operand(&mut self, index: VnIndex, location: Location) -> Option<Operand<'tcx>> {
|
||||||
if let Some(const_) = self.try_as_constant(index) {
|
if let Some(const_) = self.try_as_constant(index) {
|
||||||
Some(Operand::Constant(Box::new(const_)))
|
Some(Operand::Constant(Box::new(const_)))
|
||||||
} else if let Some(place) = self.try_as_place(index, location) {
|
} else if let Some(place) = self.try_as_place(index, location, false) {
|
||||||
self.reused_locals.insert(place.local);
|
self.reused_locals.insert(place.local);
|
||||||
Some(Operand::Copy(place))
|
Some(Operand::Copy(place))
|
||||||
} else {
|
} else {
|
||||||
|
@ -1704,7 +1706,12 @@ impl<'tcx> VnState<'_, 'tcx> {
|
||||||
/// dominate `loc`. If you used this place, add its base local to `reused_locals` to remove
|
/// dominate `loc`. If you used this place, add its base local to `reused_locals` to remove
|
||||||
/// storage statements.
|
/// storage statements.
|
||||||
#[instrument(level = "trace", skip(self), ret)]
|
#[instrument(level = "trace", skip(self), ret)]
|
||||||
fn try_as_place(&mut self, mut index: VnIndex, loc: Location) -> Option<Place<'tcx>> {
|
fn try_as_place(
|
||||||
|
&mut self,
|
||||||
|
mut index: VnIndex,
|
||||||
|
loc: Location,
|
||||||
|
allow_complex_projection: bool,
|
||||||
|
) -> Option<Place<'tcx>> {
|
||||||
let mut projection = SmallVec::<[PlaceElem<'tcx>; 1]>::new();
|
let mut projection = SmallVec::<[PlaceElem<'tcx>; 1]>::new();
|
||||||
loop {
|
loop {
|
||||||
if let Some(local) = self.try_as_local(index, loc) {
|
if let Some(local) = self.try_as_local(index, loc) {
|
||||||
|
@ -1713,6 +1720,7 @@ impl<'tcx> VnState<'_, 'tcx> {
|
||||||
Place { local, projection: self.tcx.mk_place_elems(projection.as_slice()) };
|
Place { local, projection: self.tcx.mk_place_elems(projection.as_slice()) };
|
||||||
return Some(place);
|
return Some(place);
|
||||||
} else if let Value::Projection(pointer, proj) = *self.get(index)
|
} else if let Value::Projection(pointer, proj) = *self.get(index)
|
||||||
|
&& (allow_complex_projection || proj.is_stable_offset())
|
||||||
&& let Some(proj) = self.try_as_place_elem(proj, loc)
|
&& let Some(proj) = self.try_as_place_elem(proj, loc)
|
||||||
{
|
{
|
||||||
projection.push(proj);
|
projection.push(proj);
|
||||||
|
@ -1773,7 +1781,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
if let Some(const_) = self.try_as_constant(value) {
|
if let Some(const_) = self.try_as_constant(value) {
|
||||||
*rvalue = Rvalue::Use(Operand::Constant(Box::new(const_)));
|
*rvalue = Rvalue::Use(Operand::Constant(Box::new(const_)));
|
||||||
} else if let Some(place) = self.try_as_place(value, location)
|
} else if let Some(place) = self.try_as_place(value, location, false)
|
||||||
&& *rvalue != Rvalue::Use(Operand::Move(place))
|
&& *rvalue != Rvalue::Use(Operand::Move(place))
|
||||||
&& *rvalue != Rvalue::Use(Operand::Copy(place))
|
&& *rvalue != Rvalue::Use(Operand::Copy(place))
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
bb0: {
|
bb0: {
|
||||||
_3 = copy (*_1) as *const u8 (PtrToPtr);
|
_3 = copy (*_1) as *const u8 (PtrToPtr);
|
||||||
_4 = copy _2 as *const u8 (PtrToPtr);
|
_4 = copy _2 as *const u8 (PtrToPtr);
|
||||||
- _0 = Eq(copy _3, copy _4);
|
_0 = Eq(copy _3, copy _4);
|
||||||
+ _0 = Eq(copy (*_1), copy _2);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
bb0: {
|
bb0: {
|
||||||
_3 = copy (*_1) as *const u8 (PtrToPtr);
|
_3 = copy (*_1) as *const u8 (PtrToPtr);
|
||||||
_4 = copy _2 as *const u8 (PtrToPtr);
|
_4 = copy _2 as *const u8 (PtrToPtr);
|
||||||
- _0 = Eq(copy _3, copy _4);
|
_0 = Eq(copy _3, copy _4);
|
||||||
+ _0 = Eq(copy (*_1), copy _2);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1048,7 +1048,7 @@ fn remove_casts_must_change_both_sides(mut_a: &*mut u8, mut_b: *mut u8) -> bool
|
||||||
let a = *mut_a as *const u8;
|
let a = *mut_a as *const u8;
|
||||||
// CHECK: [[B:_.+]] = copy _2 as *const u8 (PtrToPtr);
|
// CHECK: [[B:_.+]] = copy _2 as *const u8 (PtrToPtr);
|
||||||
let b = mut_b as *const u8;
|
let b = mut_b as *const u8;
|
||||||
// CHECK: _0 = Eq(copy (*_1), copy _2);
|
// CHECK: _0 = Eq(copy [[A]], copy [[B]]);
|
||||||
RET = a == b;
|
RET = a == b;
|
||||||
Return()
|
Return()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue