Skip to content

Commit 4cc9f86

Browse files
committed
Penalize -> ! calls less
1 parent 9caf3bd commit 4cc9f86

File tree

3 files changed

+139
-5
lines changed

3 files changed

+139
-5
lines changed

compiler/rustc_mir_transform/src/cost_checker.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
55

66
const INSTR_COST: usize = 5;
77
const CALL_PENALTY: usize = 25;
8+
const DIVERGING_CALL_PENALTY: usize = 10;
89
const LANDINGPAD_PENALTY: usize = 50;
910
const RESUME_PENALTY: usize = 45;
1011
const LARGE_SWITCH_PENALTY: usize = 20;
@@ -169,15 +170,24 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
169170
self.bonus += REMOVABLE_DROP_BONUS;
170171
}
171172
}
172-
TerminatorKind::Call { func, unwind, .. } => {
173+
TerminatorKind::Call { func, unwind, destination, .. } => {
173174
self.penalty += if let Some((def_id, ..)) = func.const_fn_def()
174175
&& self.tcx.intrinsic(def_id).is_some()
175176
{
176177
// Don't give intrinsics the extra penalty for calls
177178
INSTR_COST
178179
} else {
179-
CALL_PENALTY
180+
let dest_ty = destination.ty(&self.callee_body.local_decls, self.tcx).ty;
181+
if dest_ty.is_never() {
182+
// Calling `-> !` things is cheaper since we don't have to
183+
// preserve registers and most often they're things like bounds
184+
// checks which we have a chance to optimize out.
185+
DIVERGING_CALL_PENALTY
186+
} else {
187+
CALL_PENALTY
188+
}
180189
};
190+
181191
if let UnwindAction::Cleanup(_) = unwind {
182192
self.penalty += LANDINGPAD_PENALTY;
183193
}
@@ -206,7 +216,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
206216
{
207217
INSTR_COST
208218
} else {
209-
CALL_PENALTY
219+
DIVERGING_CALL_PENALTY
210220
};
211221
if let UnwindAction::Cleanup(_) = unwind {
212222
self.penalty += LANDINGPAD_PENALTY;

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

+63-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,76 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range<usize>) -> &[u32] {
44
debug slice => _1;
55
debug index => _2;
66
let mut _0: &[u32];
7+
let mut _3: usize;
8+
let mut _4: usize;
79
scope 1 (inlined #[track_caller] core::slice::index::<impl Index<std::ops::Range<usize>> for [u32]>::index) {
10+
scope 2 (inlined #[track_caller] <std::ops::Range<usize> as SliceIndex<[u32]>>::index) {
11+
let mut _7: usize;
12+
let mut _8: bool;
13+
let mut _9: *const [u32];
14+
let _12: *const [u32];
15+
let _13: !;
16+
let mut _14: !;
17+
scope 3 {
18+
scope 5 (inlined core::slice::index::get_offset_len_noubcheck::<u32>) {
19+
let _11: *const u32;
20+
scope 6 {
21+
}
22+
scope 7 (inlined core::slice::index::get_noubcheck::<u32>) {
23+
let _10: *const u32;
24+
scope 8 {
25+
}
26+
}
27+
}
28+
}
29+
scope 4 (inlined core::num::<impl usize>::checked_sub) {
30+
let mut _5: bool;
31+
let mut _6: usize;
32+
}
33+
}
834
}
935

1036
bb0: {
11-
_0 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, move _1) -> [return: bb1, unwind unreachable];
37+
_3 = move (_2.0: usize);
38+
_4 = move (_2.1: usize);
39+
StorageLive(_7);
40+
StorageLive(_5);
41+
_5 = Lt(_4, _3);
42+
switchInt(move _5) -> [0: bb1, otherwise: bb4];
1243
}
1344

1445
bb1: {
46+
_6 = SubUnchecked(_4, _3);
47+
StorageDead(_5);
48+
StorageLive(_8);
49+
_7 = PtrMetadata(_1);
50+
_8 = Gt(_4, _7);
51+
switchInt(move _8) -> [0: bb2, otherwise: bb3];
52+
}
53+
54+
bb2: {
55+
StorageDead(_8);
56+
StorageLive(_9);
57+
_9 = &raw const (*_1);
58+
StorageLive(_11);
59+
StorageLive(_10);
60+
_10 = _9 as *const u32 (PtrToPtr);
61+
_11 = Offset(_10, _3);
62+
StorageDead(_10);
63+
_12 = *const [u32] from (_11, _6);
64+
StorageDead(_11);
65+
StorageDead(_9);
66+
StorageDead(_7);
67+
_0 = &(*_12);
1568
return;
1669
}
70+
71+
bb3: {
72+
_13 = core::slice::index::slice_end_index_len_fail(move _4, move _7) -> unwind unreachable;
73+
}
74+
75+
bb4: {
76+
StorageDead(_5);
77+
_14 = core::slice::index::slice_index_order_fail(move _3, move _4) -> unwind unreachable;
78+
}
1779
}

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

+63-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,76 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range<usize>) -> &[u32] {
44
debug slice => _1;
55
debug index => _2;
66
let mut _0: &[u32];
7+
let mut _3: usize;
8+
let mut _4: usize;
79
scope 1 (inlined #[track_caller] core::slice::index::<impl Index<std::ops::Range<usize>> for [u32]>::index) {
10+
scope 2 (inlined #[track_caller] <std::ops::Range<usize> as SliceIndex<[u32]>>::index) {
11+
let mut _7: usize;
12+
let mut _8: bool;
13+
let mut _9: *const [u32];
14+
let _12: *const [u32];
15+
let _13: !;
16+
let mut _14: !;
17+
scope 3 {
18+
scope 5 (inlined core::slice::index::get_offset_len_noubcheck::<u32>) {
19+
let _11: *const u32;
20+
scope 6 {
21+
}
22+
scope 7 (inlined core::slice::index::get_noubcheck::<u32>) {
23+
let _10: *const u32;
24+
scope 8 {
25+
}
26+
}
27+
}
28+
}
29+
scope 4 (inlined core::num::<impl usize>::checked_sub) {
30+
let mut _5: bool;
31+
let mut _6: usize;
32+
}
33+
}
834
}
935

1036
bb0: {
11-
_0 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, move _1) -> [return: bb1, unwind continue];
37+
_3 = move (_2.0: usize);
38+
_4 = move (_2.1: usize);
39+
StorageLive(_7);
40+
StorageLive(_5);
41+
_5 = Lt(_4, _3);
42+
switchInt(move _5) -> [0: bb1, otherwise: bb4];
1243
}
1344

1445
bb1: {
46+
_6 = SubUnchecked(_4, _3);
47+
StorageDead(_5);
48+
StorageLive(_8);
49+
_7 = PtrMetadata(_1);
50+
_8 = Gt(_4, _7);
51+
switchInt(move _8) -> [0: bb2, otherwise: bb3];
52+
}
53+
54+
bb2: {
55+
StorageDead(_8);
56+
StorageLive(_9);
57+
_9 = &raw const (*_1);
58+
StorageLive(_11);
59+
StorageLive(_10);
60+
_10 = _9 as *const u32 (PtrToPtr);
61+
_11 = Offset(_10, _3);
62+
StorageDead(_10);
63+
_12 = *const [u32] from (_11, _6);
64+
StorageDead(_11);
65+
StorageDead(_9);
66+
StorageDead(_7);
67+
_0 = &(*_12);
1568
return;
1669
}
70+
71+
bb3: {
72+
_13 = core::slice::index::slice_end_index_len_fail(move _4, move _7) -> unwind continue;
73+
}
74+
75+
bb4: {
76+
StorageDead(_5);
77+
_14 = core::slice::index::slice_index_order_fail(move _3, move _4) -> unwind continue;
78+
}
1779
}

0 commit comments

Comments
 (0)