Skip to content

Commit b40d6c6

Browse files
committed
Auto merge of rust-lang#123843 - scottmcm:inlining-costs-again, r=<try>
[mir-inlining] Count `&T` ↔ `*const T` conversions as free Let's see if it's worth it... r? ghost
2 parents 6475796 + 2e76831 commit b40d6c6

File tree

4 files changed

+185
-1
lines changed

4 files changed

+185
-1
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
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// skip-filecheck
2+
//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=2
3+
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
4+
5+
#![crate_type = "lib"]
6+
7+
// Added after it stopped inlining in a nightly; see
8+
// <https://github.com/rust-lang/rust/issues/123174>
9+
10+
// EMIT_MIR vec_deref.vec_deref_to_slice.PreCodegen.after.mir
11+
pub fn vec_deref_to_slice(v: &Vec<u8>) -> &[u8] {
12+
v
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// MIR for `vec_deref_to_slice` after PreCodegen
2+
3+
fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
4+
debug v => _1;
5+
let mut _0: &[u8];
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+
}
52+
}
53+
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);
78+
return;
79+
}
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// MIR for `vec_deref_to_slice` after PreCodegen
2+
3+
fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
4+
debug v => _1;
5+
let mut _0: &[u8];
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+
}
52+
}
53+
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);
78+
return;
79+
}
80+
}

0 commit comments

Comments
 (0)