Simplify Len.
This commit is contained in:
parent
5fc23ad8e6
commit
3c48243b6f
15 changed files with 96 additions and 52 deletions
|
@ -776,10 +776,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Operations.
|
// Operations.
|
||||||
Rvalue::Len(ref mut place) => {
|
Rvalue::Len(ref mut place) => return self.simplify_len(place, location),
|
||||||
let place = self.simplify_place_value(place, location)?;
|
|
||||||
Value::Len(place)
|
|
||||||
}
|
|
||||||
Rvalue::Cast(kind, ref mut value, to) => {
|
Rvalue::Cast(kind, ref mut value, to) => {
|
||||||
let from = value.ty(self.local_decls, self.tcx);
|
let from = value.ty(self.local_decls, self.tcx);
|
||||||
let value = self.simplify_operand(value, location)?;
|
let value = self.simplify_operand(value, location)?;
|
||||||
|
@ -1021,6 +1018,39 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
Some(result)
|
Some(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn simplify_len(&mut self, place: &mut Place<'tcx>, location: Location) -> Option<VnIndex> {
|
||||||
|
// Trivial case: we are fetching a statically known length.
|
||||||
|
let place_ty = place.ty(self.local_decls, self.tcx).ty;
|
||||||
|
if let ty::Array(_, len) = place_ty.kind() {
|
||||||
|
return self.insert_constant(Const::from_ty_const(*len, self.tcx));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut inner = self.simplify_place_value(place, location)?;
|
||||||
|
|
||||||
|
// The length information is stored in the fat pointer.
|
||||||
|
// Reborrowing copies length information from one pointer to the other.
|
||||||
|
while let Value::Address { place: borrowed, .. } = self.get(inner)
|
||||||
|
&& let [PlaceElem::Deref] = borrowed.projection[..]
|
||||||
|
&& let Some(borrowed) = self.locals[borrowed.local]
|
||||||
|
{
|
||||||
|
inner = borrowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have an unsizing cast, which assigns the length to fat pointer metadata.
|
||||||
|
if let Value::Cast { kind, from, to, .. } = self.get(inner)
|
||||||
|
&& let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize) = kind
|
||||||
|
&& let Some(from) = from.builtin_deref(true)
|
||||||
|
&& let ty::Array(_, len) = from.ty.kind()
|
||||||
|
&& let Some(to) = to.builtin_deref(true)
|
||||||
|
&& let ty::Slice(..) = to.ty.kind()
|
||||||
|
{
|
||||||
|
return self.insert_constant(Const::from_ty_const(*len, self.tcx));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: a symbolic `Len`.
|
||||||
|
Some(self.insert(Value::Len(inner)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_to_prop_const<'tcx>(
|
fn op_to_prop_const<'tcx>(
|
||||||
|
|
|
@ -18,11 +18,12 @@
|
||||||
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||||
StorageLive(_3);
|
StorageLive(_3);
|
||||||
_3 = const 2_usize;
|
_3 = const 2_usize;
|
||||||
_4 = Len(_2);
|
- _4 = Len(_2);
|
||||||
- _5 = Lt(_3, _4);
|
- _5 = Lt(_3, _4);
|
||||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
||||||
+ _5 = Lt(const 2_usize, _4);
|
+ _4 = const 4_usize;
|
||||||
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, const 2_usize) -> [success: bb1, unwind unreachable];
|
+ _5 = const true;
|
||||||
|
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
|
|
@ -18,11 +18,12 @@
|
||||||
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||||
StorageLive(_3);
|
StorageLive(_3);
|
||||||
_3 = const 2_usize;
|
_3 = const 2_usize;
|
||||||
_4 = Len(_2);
|
- _4 = Len(_2);
|
||||||
- _5 = Lt(_3, _4);
|
- _5 = Lt(_3, _4);
|
||||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||||
+ _5 = Lt(const 2_usize, _4);
|
+ _4 = const 4_usize;
|
||||||
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, const 2_usize) -> [success: bb1, unwind continue];
|
+ _5 = const true;
|
||||||
|
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
|
|
@ -18,11 +18,12 @@
|
||||||
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||||
StorageLive(_3);
|
StorageLive(_3);
|
||||||
_3 = const 2_usize;
|
_3 = const 2_usize;
|
||||||
_4 = Len(_2);
|
- _4 = Len(_2);
|
||||||
- _5 = Lt(_3, _4);
|
- _5 = Lt(_3, _4);
|
||||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
||||||
+ _5 = Lt(const 2_usize, _4);
|
+ _4 = const 4_usize;
|
||||||
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, const 2_usize) -> [success: bb1, unwind unreachable];
|
+ _5 = const true;
|
||||||
|
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
|
|
@ -18,11 +18,12 @@
|
||||||
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||||
StorageLive(_3);
|
StorageLive(_3);
|
||||||
_3 = const 2_usize;
|
_3 = const 2_usize;
|
||||||
_4 = Len(_2);
|
- _4 = Len(_2);
|
||||||
- _5 = Lt(_3, _4);
|
- _5 = Lt(_3, _4);
|
||||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||||
+ _5 = Lt(const 2_usize, _4);
|
+ _4 = const 4_usize;
|
||||||
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, const 2_usize) -> [success: bb1, unwind continue];
|
+ _5 = const true;
|
||||||
|
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
|
|
@ -18,11 +18,12 @@
|
||||||
_2 = [const 0_u8; 5000];
|
_2 = [const 0_u8; 5000];
|
||||||
StorageLive(_3);
|
StorageLive(_3);
|
||||||
_3 = const 2_usize;
|
_3 = const 2_usize;
|
||||||
_4 = Len(_2);
|
- _4 = Len(_2);
|
||||||
- _5 = Lt(_3, _4);
|
- _5 = Lt(_3, _4);
|
||||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
||||||
+ _5 = Lt(const 2_usize, _4);
|
+ _4 = const 5000_usize;
|
||||||
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, const 2_usize) -> [success: bb1, unwind unreachable];
|
+ _5 = const true;
|
||||||
|
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
|
|
@ -18,11 +18,12 @@
|
||||||
_2 = [const 0_u8; 5000];
|
_2 = [const 0_u8; 5000];
|
||||||
StorageLive(_3);
|
StorageLive(_3);
|
||||||
_3 = const 2_usize;
|
_3 = const 2_usize;
|
||||||
_4 = Len(_2);
|
- _4 = Len(_2);
|
||||||
- _5 = Lt(_3, _4);
|
- _5 = Lt(_3, _4);
|
||||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||||
+ _5 = Lt(const 2_usize, _4);
|
+ _4 = const 5000_usize;
|
||||||
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, const 2_usize) -> [success: bb1, unwind continue];
|
+ _5 = const true;
|
||||||
|
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
|
|
@ -18,11 +18,12 @@
|
||||||
_2 = [const 0_u8; 5000];
|
_2 = [const 0_u8; 5000];
|
||||||
StorageLive(_3);
|
StorageLive(_3);
|
||||||
_3 = const 2_usize;
|
_3 = const 2_usize;
|
||||||
_4 = Len(_2);
|
- _4 = Len(_2);
|
||||||
- _5 = Lt(_3, _4);
|
- _5 = Lt(_3, _4);
|
||||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind unreachable];
|
||||||
+ _5 = Lt(const 2_usize, _4);
|
+ _4 = const 5000_usize;
|
||||||
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, const 2_usize) -> [success: bb1, unwind unreachable];
|
+ _5 = const true;
|
||||||
|
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
|
|
@ -18,11 +18,12 @@
|
||||||
_2 = [const 0_u8; 5000];
|
_2 = [const 0_u8; 5000];
|
||||||
StorageLive(_3);
|
StorageLive(_3);
|
||||||
_3 = const 2_usize;
|
_3 = const 2_usize;
|
||||||
_4 = Len(_2);
|
- _4 = Len(_2);
|
||||||
- _5 = Lt(_3, _4);
|
- _5 = Lt(_3, _4);
|
||||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind continue];
|
||||||
+ _5 = Lt(const 2_usize, _4);
|
+ _4 = const 5000_usize;
|
||||||
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, const 2_usize) -> [success: bb1, unwind continue];
|
+ _5 = const true;
|
||||||
|
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
|
|
@ -20,11 +20,12 @@
|
||||||
_3 = [const 42_u32; 8];
|
_3 = [const 42_u32; 8];
|
||||||
StorageLive(_4);
|
StorageLive(_4);
|
||||||
_4 = const 2_usize;
|
_4 = const 2_usize;
|
||||||
_5 = Len(_3);
|
- _5 = Len(_3);
|
||||||
- _6 = Lt(_4, _5);
|
- _6 = Lt(_4, _5);
|
||||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable];
|
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable];
|
||||||
+ _6 = Lt(const 2_usize, _5);
|
+ _5 = const 8_usize;
|
||||||
+ assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, const 2_usize) -> [success: bb1, unwind unreachable];
|
+ _6 = const true;
|
||||||
|
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
|
|
@ -20,11 +20,12 @@
|
||||||
_3 = [const 42_u32; 8];
|
_3 = [const 42_u32; 8];
|
||||||
StorageLive(_4);
|
StorageLive(_4);
|
||||||
_4 = const 2_usize;
|
_4 = const 2_usize;
|
||||||
_5 = Len(_3);
|
- _5 = Len(_3);
|
||||||
- _6 = Lt(_4, _5);
|
- _6 = Lt(_4, _5);
|
||||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
|
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
|
||||||
+ _6 = Lt(const 2_usize, _5);
|
+ _5 = const 8_usize;
|
||||||
+ assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, const 2_usize) -> [success: bb1, unwind continue];
|
+ _6 = const true;
|
||||||
|
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
|
|
@ -20,11 +20,12 @@
|
||||||
_3 = [const 42_u32; 8];
|
_3 = [const 42_u32; 8];
|
||||||
StorageLive(_4);
|
StorageLive(_4);
|
||||||
_4 = const 2_usize;
|
_4 = const 2_usize;
|
||||||
_5 = Len(_3);
|
- _5 = Len(_3);
|
||||||
- _6 = Lt(_4, _5);
|
- _6 = Lt(_4, _5);
|
||||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable];
|
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable];
|
||||||
+ _6 = Lt(const 2_usize, _5);
|
+ _5 = const 8_usize;
|
||||||
+ assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, const 2_usize) -> [success: bb1, unwind unreachable];
|
+ _6 = const true;
|
||||||
|
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
|
|
@ -20,11 +20,12 @@
|
||||||
_3 = [const 42_u32; 8];
|
_3 = [const 42_u32; 8];
|
||||||
StorageLive(_4);
|
StorageLive(_4);
|
||||||
_4 = const 2_usize;
|
_4 = const 2_usize;
|
||||||
_5 = Len(_3);
|
- _5 = Len(_3);
|
||||||
- _6 = Lt(_4, _5);
|
- _6 = Lt(_4, _5);
|
||||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
|
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind continue];
|
||||||
+ _6 = Lt(const 2_usize, _5);
|
+ _5 = const 8_usize;
|
||||||
+ assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, const 2_usize) -> [success: bb1, unwind continue];
|
+ _6 = const true;
|
||||||
|
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
|
|
@ -32,11 +32,12 @@
|
||||||
StorageLive(_6);
|
StorageLive(_6);
|
||||||
StorageLive(_7);
|
StorageLive(_7);
|
||||||
_7 = const 0_usize;
|
_7 = const 0_usize;
|
||||||
_8 = Len(_3);
|
- _8 = Len(_3);
|
||||||
- _9 = Lt(_7, _8);
|
- _9 = Lt(_7, _8);
|
||||||
- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb1, unwind unreachable];
|
- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb1, unwind unreachable];
|
||||||
+ _9 = Lt(const 0_usize, _8);
|
+ _8 = const N;
|
||||||
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", _8, const 0_usize) -> [success: bb1, unwind unreachable];
|
+ _9 = Lt(const 0_usize, const N);
|
||||||
|
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
@ -57,9 +58,9 @@
|
||||||
- _13 = Len(_3);
|
- _13 = Len(_3);
|
||||||
- _14 = Lt(_12, _13);
|
- _14 = Lt(_12, _13);
|
||||||
- assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, _12) -> [success: bb3, unwind unreachable];
|
- assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, _12) -> [success: bb3, unwind unreachable];
|
||||||
+ _13 = _8;
|
+ _13 = const N;
|
||||||
+ _14 = Lt(_2, _8);
|
+ _14 = Lt(_2, const N);
|
||||||
+ assert(move _14, "index out of bounds: the length is {} but the index is {}", _8, _2) -> [success: bb3, unwind unreachable];
|
+ assert(move _14, "index out of bounds: the length is {} but the index is {}", const N, _2) -> [success: bb3, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb3: {
|
bb3: {
|
||||||
|
|
|
@ -32,11 +32,12 @@
|
||||||
StorageLive(_6);
|
StorageLive(_6);
|
||||||
StorageLive(_7);
|
StorageLive(_7);
|
||||||
_7 = const 0_usize;
|
_7 = const 0_usize;
|
||||||
_8 = Len(_3);
|
- _8 = Len(_3);
|
||||||
- _9 = Lt(_7, _8);
|
- _9 = Lt(_7, _8);
|
||||||
- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb1, unwind continue];
|
- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb1, unwind continue];
|
||||||
+ _9 = Lt(const 0_usize, _8);
|
+ _8 = const N;
|
||||||
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", _8, const 0_usize) -> [success: bb1, unwind continue];
|
+ _9 = Lt(const 0_usize, const N);
|
||||||
|
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind continue];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
|
@ -57,9 +58,9 @@
|
||||||
- _13 = Len(_3);
|
- _13 = Len(_3);
|
||||||
- _14 = Lt(_12, _13);
|
- _14 = Lt(_12, _13);
|
||||||
- assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, _12) -> [success: bb3, unwind continue];
|
- assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, _12) -> [success: bb3, unwind continue];
|
||||||
+ _13 = _8;
|
+ _13 = const N;
|
||||||
+ _14 = Lt(_2, _8);
|
+ _14 = Lt(_2, const N);
|
||||||
+ assert(move _14, "index out of bounds: the length is {} but the index is {}", _8, _2) -> [success: bb3, unwind continue];
|
+ assert(move _14, "index out of bounds: the length is {} but the index is {}", const N, _2) -> [success: bb3, unwind continue];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb3: {
|
bb3: {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue