Skip to content

Commit 29e8c80

Browse files
committed
Inline more when we do inline
To offset the less inlining in simple forwarding functions.
1 parent 4cc9f86 commit 29e8c80

17 files changed

+2381
-363
lines changed

compiler/rustc_mir_transform/src/inline.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ impl<'tcx> Inliner<'tcx> {
486486
let mut threshold = if self.caller_is_inline_forwarder {
487487
self.tcx.sess.opts.unstable_opts.inline_mir_forwarder_threshold.unwrap_or(30)
488488
} else if cross_crate_inlinable {
489-
self.tcx.sess.opts.unstable_opts.inline_mir_hint_threshold.unwrap_or(100)
489+
self.tcx.sess.opts.unstable_opts.inline_mir_hint_threshold.unwrap_or(150)
490490
} else {
491491
self.tcx.sess.opts.unstable_opts.inline_mir_threshold.unwrap_or(50)
492492
};

compiler/rustc_session/src/options.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1769,7 +1769,7 @@ options! {
17691769
inline_mir_forwarder_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
17701770
"inlining threshold when the caller is a simple forwarding function (default: 30)"),
17711771
inline_mir_hint_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
1772-
"inlining threshold for functions with inline hint (default: 100)"),
1772+
"inlining threshold for functions with inline hint (default: 150)"),
17731773
inline_mir_preserve_debug: Option<bool> = (None, parse_opt_bool, [TRACKED],
17741774
"when MIR inlining, whether to preserve debug info for callee variables \
17751775
(default: preserve for debuginfo != None, otherwise remove)"),

tests/codegen/issues/issue-37945.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,35 @@
33

44
// Check that LLVM understands that `Iter` pointer is not null. Issue #37945.
55

6+
// Note that this is not about assumes or metadata, which are covered better by
7+
// `slice-iter-nonnull.rs`, rather about being sure that it's not emitting
8+
// a null check as part of computing the value, which we do by verifying that
9+
// the only return is only from comparing the two pointers.
10+
611
#![crate_type = "lib"]
712

813
use std::slice::Iter;
914

1015
#[no_mangle]
1116
pub fn is_empty_1(xs: Iter<f32>) -> bool {
12-
// CHECK-LABEL: @is_empty_1(
13-
// CHECK-NEXT: start:
14-
// CHECK-NEXT: [[A:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null
15-
// CHECK-NEXT: tail call void @llvm.assume(i1 [[A]])
17+
// CHECK-LABEL: i1 @is_empty_1(
18+
// CHECK-NOT: ret i1
1619
// The order between %xs.0 and %xs.1 on the next line doesn't matter
1720
// and different LLVM versions produce different order.
18-
// CHECK-NEXT: [[B:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}}
19-
// CHECK-NEXT: ret i1 [[B:%.*]]
21+
// CHECK: [[B:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}}
22+
// CHECK-NEXT: ret i1 [[B:%.*]]
23+
// CHECK-NOT: ret i1
2024
{ xs }.next().is_none()
2125
}
2226

2327
#[no_mangle]
2428
pub fn is_empty_2(xs: Iter<f32>) -> bool {
25-
// CHECK-LABEL: @is_empty_2
26-
// CHECK-NEXT: start:
27-
// CHECK-NEXT: [[C:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null
28-
// CHECK-NEXT: tail call void @llvm.assume(i1 [[C]])
29+
// CHECK-LABEL: i1 @is_empty_2
30+
// CHECK-NOT: ret i1
2931
// The order between %xs.0 and %xs.1 on the next line doesn't matter
3032
// and different LLVM versions produce different order.
31-
// CHECK-NEXT: [[D:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}}
32-
// CHECK-NEXT: ret i1 [[D:%.*]]
33+
// CHECK: [[B:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}}
34+
// CHECK-NEXT: ret i1 [[B:%.*]]
35+
// CHECK-NOT: ret i1
3336
xs.map(|&x| x).next().is_none()
3437
}

tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir

+55-39
Original file line numberDiff line numberDiff line change
@@ -3,67 +3,83 @@
33
fn num_to_digit(_1: char) -> u32 {
44
debug num => _1;
55
let mut _0: u32;
6-
let mut _4: std::option::Option<u32>;
6+
let mut _8: std::option::Option<u32>;
77
scope 1 (inlined char::methods::<impl char>::is_digit) {
8-
let _2: std::option::Option<u32>;
9-
scope 2 (inlined Option::<u32>::is_some) {
10-
let mut _3: isize;
8+
scope 2 (inlined char::methods::<impl char>::to_digit) {
9+
let mut _2: u32;
10+
let mut _3: u32;
11+
let mut _4: bool;
12+
scope 3 {
13+
scope 5 (inlined Arguments::<'_>::new_const::<1>) {
14+
}
15+
scope 6 (inlined core::num::<impl u32>::wrapping_sub) {
16+
}
17+
scope 7 (inlined core::num::<impl u32>::saturating_add) {
18+
}
19+
}
20+
scope 4 (inlined core::num::<impl u32>::wrapping_sub) {
21+
}
22+
}
23+
scope 8 (inlined Option::<u32>::is_some) {
1124
}
1225
}
13-
scope 3 (inlined #[track_caller] Option::<u32>::unwrap) {
14-
let mut _5: isize;
15-
let mut _6: !;
16-
scope 4 {
26+
scope 9 (inlined char::methods::<impl char>::to_digit) {
27+
let mut _5: u32;
28+
let mut _6: bool;
29+
scope 10 {
30+
scope 12 (inlined Arguments::<'_>::new_const::<1>) {
31+
}
32+
scope 13 (inlined core::num::<impl u32>::wrapping_sub) {
33+
}
34+
scope 14 (inlined core::num::<impl u32>::saturating_add) {
35+
}
36+
}
37+
scope 11 (inlined core::num::<impl u32>::wrapping_sub) {
38+
}
39+
}
40+
scope 15 (inlined #[track_caller] Option::<u32>::unwrap) {
41+
let mut _7: !;
42+
scope 16 {
1743
}
1844
}
1945

2046
bb0: {
21-
StorageLive(_2);
22-
_2 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> [return: bb1, unwind unreachable];
47+
_2 = _1 as u32 (IntToInt);
48+
_3 = Sub(_2, const 48_u32);
49+
StorageLive(_4);
50+
_4 = Lt(_3, const 8_u32);
51+
switchInt(move _4) -> [0: bb1, otherwise: bb2];
2352
}
2453

2554
bb1: {
26-
StorageLive(_3);
27-
_3 = discriminant(_2);
28-
switchInt(move _3) -> [1: bb2, 0: bb6, otherwise: bb8];
55+
StorageDead(_4);
56+
_0 = const 0_u32;
57+
goto -> bb5;
2958
}
3059

3160
bb2: {
32-
StorageDead(_3);
33-
StorageDead(_2);
34-
StorageLive(_4);
35-
_4 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind unreachable];
61+
StorageDead(_4);
62+
StorageLive(_8);
63+
_5 = Sub(_2, const 48_u32);
64+
StorageLive(_6);
65+
_6 = Lt(_5, const 8_u32);
66+
switchInt(move _6) -> [0: bb3, otherwise: bb4];
3667
}
3768

3869
bb3: {
39-
StorageLive(_5);
40-
_5 = discriminant(_4);
41-
switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb8];
70+
StorageDead(_6);
71+
_7 = option::unwrap_failed() -> unwind unreachable;
4272
}
4373

4474
bb4: {
45-
_6 = option::unwrap_failed() -> unwind unreachable;
75+
_8 = Option::<u32>::Some(_5);
76+
StorageDead(_6);
77+
_0 = move ((_8 as Some).0: u32);
78+
StorageDead(_8);
79+
goto -> bb5;
4680
}
4781

4882
bb5: {
49-
_0 = move ((_4 as Some).0: u32);
50-
StorageDead(_5);
51-
StorageDead(_4);
52-
goto -> bb7;
53-
}
54-
55-
bb6: {
56-
StorageDead(_3);
57-
StorageDead(_2);
58-
_0 = const 0_u32;
59-
goto -> bb7;
60-
}
61-
62-
bb7: {
6383
return;
6484
}
65-
66-
bb8: {
67-
unreachable;
68-
}
6985
}

tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir

+55-39
Original file line numberDiff line numberDiff line change
@@ -3,67 +3,83 @@
33
fn num_to_digit(_1: char) -> u32 {
44
debug num => _1;
55
let mut _0: u32;
6-
let mut _4: std::option::Option<u32>;
6+
let mut _8: std::option::Option<u32>;
77
scope 1 (inlined char::methods::<impl char>::is_digit) {
8-
let _2: std::option::Option<u32>;
9-
scope 2 (inlined Option::<u32>::is_some) {
10-
let mut _3: isize;
8+
scope 2 (inlined char::methods::<impl char>::to_digit) {
9+
let mut _2: u32;
10+
let mut _3: u32;
11+
let mut _4: bool;
12+
scope 3 {
13+
scope 5 (inlined Arguments::<'_>::new_const::<1>) {
14+
}
15+
scope 6 (inlined core::num::<impl u32>::wrapping_sub) {
16+
}
17+
scope 7 (inlined core::num::<impl u32>::saturating_add) {
18+
}
19+
}
20+
scope 4 (inlined core::num::<impl u32>::wrapping_sub) {
21+
}
22+
}
23+
scope 8 (inlined Option::<u32>::is_some) {
1124
}
1225
}
13-
scope 3 (inlined #[track_caller] Option::<u32>::unwrap) {
14-
let mut _5: isize;
15-
let mut _6: !;
16-
scope 4 {
26+
scope 9 (inlined char::methods::<impl char>::to_digit) {
27+
let mut _5: u32;
28+
let mut _6: bool;
29+
scope 10 {
30+
scope 12 (inlined Arguments::<'_>::new_const::<1>) {
31+
}
32+
scope 13 (inlined core::num::<impl u32>::wrapping_sub) {
33+
}
34+
scope 14 (inlined core::num::<impl u32>::saturating_add) {
35+
}
36+
}
37+
scope 11 (inlined core::num::<impl u32>::wrapping_sub) {
38+
}
39+
}
40+
scope 15 (inlined #[track_caller] Option::<u32>::unwrap) {
41+
let mut _7: !;
42+
scope 16 {
1743
}
1844
}
1945

2046
bb0: {
21-
StorageLive(_2);
22-
_2 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> [return: bb1, unwind continue];
47+
_2 = _1 as u32 (IntToInt);
48+
_3 = Sub(_2, const 48_u32);
49+
StorageLive(_4);
50+
_4 = Lt(_3, const 8_u32);
51+
switchInt(move _4) -> [0: bb1, otherwise: bb2];
2352
}
2453

2554
bb1: {
26-
StorageLive(_3);
27-
_3 = discriminant(_2);
28-
switchInt(move _3) -> [1: bb2, 0: bb6, otherwise: bb8];
55+
StorageDead(_4);
56+
_0 = const 0_u32;
57+
goto -> bb5;
2958
}
3059

3160
bb2: {
32-
StorageDead(_3);
33-
StorageDead(_2);
34-
StorageLive(_4);
35-
_4 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind continue];
61+
StorageDead(_4);
62+
StorageLive(_8);
63+
_5 = Sub(_2, const 48_u32);
64+
StorageLive(_6);
65+
_6 = Lt(_5, const 8_u32);
66+
switchInt(move _6) -> [0: bb3, otherwise: bb4];
3667
}
3768

3869
bb3: {
39-
StorageLive(_5);
40-
_5 = discriminant(_4);
41-
switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb8];
70+
StorageDead(_6);
71+
_7 = option::unwrap_failed() -> unwind continue;
4272
}
4373

4474
bb4: {
45-
_6 = option::unwrap_failed() -> unwind continue;
75+
_8 = Option::<u32>::Some(_5);
76+
StorageDead(_6);
77+
_0 = move ((_8 as Some).0: u32);
78+
StorageDead(_8);
79+
goto -> bb5;
4680
}
4781

4882
bb5: {
49-
_0 = move ((_4 as Some).0: u32);
50-
StorageDead(_5);
51-
StorageDead(_4);
52-
goto -> bb7;
53-
}
54-
55-
bb6: {
56-
StorageDead(_3);
57-
StorageDead(_2);
58-
_0 = const 0_u32;
59-
goto -> bb7;
60-
}
61-
62-
bb7: {
6383
return;
6484
}
65-
66-
bb8: {
67-
unreachable;
68-
}
6985
}

0 commit comments

Comments
 (0)