Skip to content

Commit 2e76831

Browse files
committed
Count &T*const T conversions as free in inlining
1 parent d816e32 commit 2e76831

File tree

3 files changed

+152
-9
lines changed

3 files changed

+152
-9
lines changed

compiler/rustc_mir_transform/src/cost_checker.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,25 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> {
4040
}
4141
}
4242

43+
fn rvalue_is_nop(rvalue: &Rvalue<'_>) -> bool {
44+
match rvalue {
45+
// Treat `&*pointer` and `addr_of!(*reference)` as free when inlining
46+
Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
47+
**place.projection == [PlaceElem::Deref]
48+
}
49+
_ => false,
50+
}
51+
}
52+
4353
impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
4454
fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
4555
// Don't count StorageLive/StorageDead in the inlining cost.
46-
match statement.kind {
56+
match &statement.kind {
4757
StatementKind::StorageLive(_)
4858
| StatementKind::StorageDead(_)
4959
| StatementKind::Deinit(_)
5060
| StatementKind::Nop => {}
61+
StatementKind::Assign(place_and_rvalue) if rvalue_is_nop(&place_and_rvalue.1) => {}
5162
_ => self.cost += INSTR_COST,
5263
}
5364
}

tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir

+70-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,78 @@
33
fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
44
debug v => _1;
55
let mut _0: &[u8];
6-
7-
bb0: {
8-
_0 = <Vec<u8> as Deref>::deref(move _1) -> [return: bb1, unwind unreachable];
6+
scope 1 (inlined <Vec<u8> as Deref>::deref) {
7+
debug self => _1;
8+
let mut _4: *const u8;
9+
let mut _5: usize;
10+
scope 2 (inlined Vec::<u8>::as_ptr) {
11+
debug self => _1;
12+
let mut _2: &alloc::raw_vec::RawVec<u8>;
13+
scope 3 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
14+
debug self => _2;
15+
let mut _3: std::ptr::NonNull<u8>;
16+
scope 4 (inlined Unique::<u8>::as_ptr) {
17+
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _3;
18+
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
19+
scope 5 (inlined NonNull::<u8>::as_ptr) {
20+
debug self => _3;
21+
}
22+
}
23+
}
24+
}
25+
scope 6 (inlined std::slice::from_raw_parts::<'_, u8>) {
26+
debug data => _4;
27+
debug len => _5;
28+
let _9: *const [u8];
29+
scope 7 (inlined core::ub_checks::check_language_ub) {
30+
scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
31+
}
32+
}
33+
scope 9 (inlined std::mem::size_of::<u8>) {
34+
}
35+
scope 10 (inlined align_of::<u8>) {
36+
}
37+
scope 11 (inlined slice_from_raw_parts::<u8>) {
38+
debug data => _4;
39+
debug len => _5;
40+
let mut _6: *const ();
41+
scope 12 (inlined std::ptr::const_ptr::<impl *const u8>::cast::<()>) {
42+
debug self => _4;
43+
}
44+
scope 13 (inlined std::ptr::from_raw_parts::<[u8]>) {
45+
debug data_pointer => _6;
46+
debug metadata => _5;
47+
let mut _7: std::ptr::metadata::PtrComponents<[u8]>;
48+
let mut _8: std::ptr::metadata::PtrRepr<[u8]>;
49+
}
50+
}
51+
}
952
}
1053

11-
bb1: {
54+
bb0: {
55+
StorageLive(_4);
56+
StorageLive(_2);
57+
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
58+
StorageLive(_3);
59+
_3 = ((((*_1).0: alloc::raw_vec::RawVec<u8>).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
60+
_4 = (_3.0: *const u8);
61+
StorageDead(_3);
62+
StorageDead(_2);
63+
StorageLive(_5);
64+
_5 = ((*_1).1: usize);
65+
StorageLive(_6);
66+
_6 = _4 as *const () (PtrToPtr);
67+
StorageLive(_8);
68+
StorageLive(_7);
69+
_7 = std::ptr::metadata::PtrComponents::<[u8]> { data_pointer: _6, metadata: _5 };
70+
_8 = std::ptr::metadata::PtrRepr::<[u8]> { const_ptr: move _7 };
71+
StorageDead(_7);
72+
_9 = (_8.0: *const [u8]);
73+
StorageDead(_8);
74+
StorageDead(_6);
75+
StorageDead(_5);
76+
StorageDead(_4);
77+
_0 = &(*_9);
1278
return;
1379
}
1480
}

tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir

+70-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,78 @@
33
fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
44
debug v => _1;
55
let mut _0: &[u8];
6-
7-
bb0: {
8-
_0 = <Vec<u8> as Deref>::deref(move _1) -> [return: bb1, unwind continue];
6+
scope 1 (inlined <Vec<u8> as Deref>::deref) {
7+
debug self => _1;
8+
let mut _4: *const u8;
9+
let mut _5: usize;
10+
scope 2 (inlined Vec::<u8>::as_ptr) {
11+
debug self => _1;
12+
let mut _2: &alloc::raw_vec::RawVec<u8>;
13+
scope 3 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
14+
debug self => _2;
15+
let mut _3: std::ptr::NonNull<u8>;
16+
scope 4 (inlined Unique::<u8>::as_ptr) {
17+
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _3;
18+
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
19+
scope 5 (inlined NonNull::<u8>::as_ptr) {
20+
debug self => _3;
21+
}
22+
}
23+
}
24+
}
25+
scope 6 (inlined std::slice::from_raw_parts::<'_, u8>) {
26+
debug data => _4;
27+
debug len => _5;
28+
let _9: *const [u8];
29+
scope 7 (inlined core::ub_checks::check_language_ub) {
30+
scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
31+
}
32+
}
33+
scope 9 (inlined std::mem::size_of::<u8>) {
34+
}
35+
scope 10 (inlined align_of::<u8>) {
36+
}
37+
scope 11 (inlined slice_from_raw_parts::<u8>) {
38+
debug data => _4;
39+
debug len => _5;
40+
let mut _6: *const ();
41+
scope 12 (inlined std::ptr::const_ptr::<impl *const u8>::cast::<()>) {
42+
debug self => _4;
43+
}
44+
scope 13 (inlined std::ptr::from_raw_parts::<[u8]>) {
45+
debug data_pointer => _6;
46+
debug metadata => _5;
47+
let mut _7: std::ptr::metadata::PtrComponents<[u8]>;
48+
let mut _8: std::ptr::metadata::PtrRepr<[u8]>;
49+
}
50+
}
51+
}
952
}
1053

11-
bb1: {
54+
bb0: {
55+
StorageLive(_4);
56+
StorageLive(_2);
57+
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
58+
StorageLive(_3);
59+
_3 = ((((*_1).0: alloc::raw_vec::RawVec<u8>).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
60+
_4 = (_3.0: *const u8);
61+
StorageDead(_3);
62+
StorageDead(_2);
63+
StorageLive(_5);
64+
_5 = ((*_1).1: usize);
65+
StorageLive(_6);
66+
_6 = _4 as *const () (PtrToPtr);
67+
StorageLive(_8);
68+
StorageLive(_7);
69+
_7 = std::ptr::metadata::PtrComponents::<[u8]> { data_pointer: _6, metadata: _5 };
70+
_8 = std::ptr::metadata::PtrRepr::<[u8]> { const_ptr: move _7 };
71+
StorageDead(_7);
72+
_9 = (_8.0: *const [u8]);
73+
StorageDead(_8);
74+
StorageDead(_6);
75+
StorageDead(_5);
76+
StorageDead(_4);
77+
_0 = &(*_9);
1278
return;
1379
}
1480
}

0 commit comments

Comments
 (0)