Skip to content

Commit 1f544ca

Browse files
committed
Fold consecutive PtrToPtr casts.
1 parent f4cfd87 commit 1f544ca

13 files changed

+505
-507
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ use rustc_index::IndexVec;
9393
use rustc_middle::mir::interpret::GlobalAlloc;
9494
use rustc_middle::mir::visit::*;
9595
use rustc_middle::mir::*;
96-
use rustc_middle::ty::adjustment::PointerCoercion;
9796
use rustc_middle::ty::layout::LayoutOf;
9897
use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut};
9998
use rustc_span::def_id::DefId;
@@ -778,18 +777,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
778777

779778
// Operations.
780779
Rvalue::Len(ref mut place) => return self.simplify_len(place, location),
781-
Rvalue::Cast(kind, ref mut value, to) => {
782-
let from = value.ty(self.local_decls, self.tcx);
783-
let value = self.simplify_operand(value, location)?;
784-
if let CastKind::PointerCoercion(
785-
PointerCoercion::ReifyFnPointer | PointerCoercion::ClosureFnPointer(_),
786-
) = kind
787-
{
788-
// Each reification of a generic fn may get a different pointer.
789-
// Do not try to merge them.
790-
return self.new_opaque();
791-
}
792-
Value::Cast { kind, value, from, to }
780+
Rvalue::Cast(ref mut kind, ref mut value, to) => {
781+
return self.simplify_cast(kind, value, to, location);
793782
}
794783
Rvalue::BinaryOp(op, box (ref mut lhs, ref mut rhs)) => {
795784
let ty = lhs.ty(self.local_decls, self.tcx);
@@ -1035,6 +1024,47 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10351024
}
10361025
}
10371026

1027+
fn simplify_cast(
1028+
&mut self,
1029+
kind: &mut CastKind,
1030+
operand: &mut Operand<'tcx>,
1031+
to: Ty<'tcx>,
1032+
location: Location,
1033+
) -> Option<VnIndex> {
1034+
use rustc_middle::ty::adjustment::PointerCoercion::*;
1035+
use CastKind::*;
1036+
1037+
let mut from = operand.ty(self.local_decls, self.tcx);
1038+
let mut value = self.simplify_operand(operand, location)?;
1039+
1040+
if let CastKind::PointerCoercion(ReifyFnPointer | ClosureFnPointer(_)) = kind {
1041+
// Each reification of a generic fn may get a different pointer.
1042+
// Do not try to merge them.
1043+
return self.new_opaque();
1044+
}
1045+
1046+
if let PtrToPtr | PointerCoercion(MutToConstPointer) = kind
1047+
&& let Value::Cast { kind: inner_kind, value: inner_value, from: inner_from, to: _ } =
1048+
*self.get(value)
1049+
&& let PtrToPtr | PointerCoercion(MutToConstPointer) = inner_kind
1050+
{
1051+
from = inner_from;
1052+
value = inner_value;
1053+
*kind = PtrToPtr;
1054+
if inner_from == to {
1055+
return Some(inner_value);
1056+
}
1057+
if let Some(const_) = self.try_as_constant(value) {
1058+
*operand = Operand::Constant(Box::new(const_));
1059+
} else if let Some(local) = self.try_as_local(value, location) {
1060+
*operand = Operand::Copy(local.into());
1061+
self.reused_locals.insert(local);
1062+
}
1063+
}
1064+
1065+
Some(self.insert(Value::Cast { kind: *kind, value, from, to }))
1066+
}
1067+
10381068
fn simplify_len(&mut self, place: &mut Place<'tcx>, location: Location) -> Option<VnIndex> {
10391069
// Trivial case: we are fetching a statically known length.
10401070
let place_ty = place.ty(self.local_decls, self.tcx).ty;

tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,16 @@
111111
StorageDead(_15);
112112
StorageDead(_12);
113113
StorageDead(_6);
114-
StorageLive(_18);
114+
- StorageLive(_18);
115+
+ nop;
115116
_18 = (_5.0: *const [u8]);
116-
_4 = move _18 as *mut [u8] (PtrToPtr);
117-
StorageDead(_18);
117+
- _4 = move _18 as *mut [u8] (PtrToPtr);
118+
- StorageDead(_18);
119+
+ _4 = _18 as *mut [u8] (PtrToPtr);
120+
+ nop;
118121
StorageDead(_5);
119-
_3 = move _4 as *mut u8 (PtrToPtr);
122+
- _3 = move _4 as *mut u8 (PtrToPtr);
123+
+ _3 = _18 as *mut u8 (PtrToPtr);
120124
StorageDead(_4);
121125
StorageDead(_3);
122126
- StorageDead(_1);

tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,16 @@
5050

5151
bb1: {
5252
StorageDead(_6);
53-
StorageLive(_12);
53+
- StorageLive(_12);
54+
+ nop;
5455
_12 = (_5.0: *const [u8]);
55-
_4 = move _12 as *mut [u8] (PtrToPtr);
56-
StorageDead(_12);
56+
- _4 = move _12 as *mut [u8] (PtrToPtr);
57+
- StorageDead(_12);
58+
+ _4 = _12 as *mut [u8] (PtrToPtr);
59+
+ nop;
5760
StorageDead(_5);
58-
_3 = move _4 as *mut u8 (PtrToPtr);
61+
- _3 = move _4 as *mut u8 (PtrToPtr);
62+
+ _3 = _12 as *mut u8 (PtrToPtr);
5963
StorageDead(_4);
6064
StorageDead(_3);
6165
- StorageDead(_1);

tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,16 @@
111111
StorageDead(_15);
112112
StorageDead(_12);
113113
StorageDead(_6);
114-
StorageLive(_18);
114+
- StorageLive(_18);
115+
+ nop;
115116
_18 = (_5.0: *const [u8]);
116-
_4 = move _18 as *mut [u8] (PtrToPtr);
117-
StorageDead(_18);
117+
- _4 = move _18 as *mut [u8] (PtrToPtr);
118+
- StorageDead(_18);
119+
+ _4 = _18 as *mut [u8] (PtrToPtr);
120+
+ nop;
118121
StorageDead(_5);
119-
_3 = move _4 as *mut u8 (PtrToPtr);
122+
- _3 = move _4 as *mut u8 (PtrToPtr);
123+
+ _3 = _18 as *mut u8 (PtrToPtr);
120124
StorageDead(_4);
121125
StorageDead(_3);
122126
- StorageDead(_1);

tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,16 @@
5050

5151
bb1: {
5252
StorageDead(_6);
53-
StorageLive(_12);
53+
- StorageLive(_12);
54+
+ nop;
5455
_12 = (_5.0: *const [u8]);
55-
_4 = move _12 as *mut [u8] (PtrToPtr);
56-
StorageDead(_12);
56+
- _4 = move _12 as *mut [u8] (PtrToPtr);
57+
- StorageDead(_12);
58+
+ _4 = _12 as *mut [u8] (PtrToPtr);
59+
+ nop;
5760
StorageDead(_5);
58-
_3 = move _4 as *mut u8 (PtrToPtr);
61+
- _3 = move _4 as *mut u8 (PtrToPtr);
62+
+ _3 = _12 as *mut u8 (PtrToPtr);
5963
StorageDead(_4);
6064
StorageDead(_3);
6165
- StorageDead(_1);

tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
8989
StorageLive(_12);
9090
StorageLive(_11);
9191
StorageLive(_10);
92-
_10 = _9 as *const () (PointerCoercion(MutToConstPointer));
92+
_10 = _8 as *const () (PtrToPtr);
9393
_11 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: move _10, metadata: _6 };
9494
StorageDead(_10);
9595
_12 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 };

tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
8989
StorageLive(_12);
9090
StorageLive(_11);
9191
StorageLive(_10);
92-
_10 = _9 as *const () (PointerCoercion(MutToConstPointer));
92+
_10 = _8 as *const () (PtrToPtr);
9393
_11 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: move _10, metadata: _6 };
9494
StorageDead(_10);
9595
_12 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 };

0 commit comments

Comments
 (0)