Nothing Special   »   [go: up one dir, main page]

Skip to content

Commit

Permalink
Inline more when we do inline
Browse files Browse the repository at this point in the history
To offset the less inlining in simple forwarding functions.
  • Loading branch information
scottmcm committed Jun 29, 2024
1 parent 4cc9f86 commit 29e8c80
Show file tree
Hide file tree
Showing 17 changed files with 2,381 additions and 363 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ impl<'tcx> Inliner<'tcx> {
let mut threshold = if self.caller_is_inline_forwarder {
self.tcx.sess.opts.unstable_opts.inline_mir_forwarder_threshold.unwrap_or(30)
} else if cross_crate_inlinable {
self.tcx.sess.opts.unstable_opts.inline_mir_hint_threshold.unwrap_or(100)
self.tcx.sess.opts.unstable_opts.inline_mir_hint_threshold.unwrap_or(150)
} else {
self.tcx.sess.opts.unstable_opts.inline_mir_threshold.unwrap_or(50)
};
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1769,7 +1769,7 @@ options! {
inline_mir_forwarder_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
"inlining threshold when the caller is a simple forwarding function (default: 30)"),
inline_mir_hint_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
"inlining threshold for functions with inline hint (default: 100)"),
"inlining threshold for functions with inline hint (default: 150)"),
inline_mir_preserve_debug: Option<bool> = (None, parse_opt_bool, [TRACKED],
"when MIR inlining, whether to preserve debug info for callee variables \
(default: preserve for debuginfo != None, otherwise remove)"),
Expand Down
27 changes: 15 additions & 12 deletions tests/codegen/issues/issue-37945.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,35 @@

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

// Note that this is not about assumes or metadata, which are covered better by
// `slice-iter-nonnull.rs`, rather about being sure that it's not emitting
// a null check as part of computing the value, which we do by verifying that
// the only return is only from comparing the two pointers.

#![crate_type = "lib"]

use std::slice::Iter;

#[no_mangle]
pub fn is_empty_1(xs: Iter<f32>) -> bool {
// CHECK-LABEL: @is_empty_1(
// CHECK-NEXT: start:
// CHECK-NEXT: [[A:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null
// CHECK-NEXT: tail call void @llvm.assume(i1 [[A]])
// CHECK-LABEL: i1 @is_empty_1(
// CHECK-NOT: ret i1
// The order between %xs.0 and %xs.1 on the next line doesn't matter
// and different LLVM versions produce different order.
// CHECK-NEXT: [[B:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}}
// CHECK-NEXT: ret i1 [[B:%.*]]
// CHECK: [[B:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}}
// CHECK-NEXT: ret i1 [[B:%.*]]
// CHECK-NOT: ret i1
{ xs }.next().is_none()
}

#[no_mangle]
pub fn is_empty_2(xs: Iter<f32>) -> bool {
// CHECK-LABEL: @is_empty_2
// CHECK-NEXT: start:
// CHECK-NEXT: [[C:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null
// CHECK-NEXT: tail call void @llvm.assume(i1 [[C]])
// CHECK-LABEL: i1 @is_empty_2
// CHECK-NOT: ret i1
// The order between %xs.0 and %xs.1 on the next line doesn't matter
// and different LLVM versions produce different order.
// CHECK-NEXT: [[D:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}}
// CHECK-NEXT: ret i1 [[D:%.*]]
// CHECK: [[B:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}}
// CHECK-NEXT: ret i1 [[B:%.*]]
// CHECK-NOT: ret i1
xs.map(|&x| x).next().is_none()
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,83 @@
fn num_to_digit(_1: char) -> u32 {
debug num => _1;
let mut _0: u32;
let mut _4: std::option::Option<u32>;
let mut _8: std::option::Option<u32>;
scope 1 (inlined char::methods::<impl char>::is_digit) {
let _2: std::option::Option<u32>;
scope 2 (inlined Option::<u32>::is_some) {
let mut _3: isize;
scope 2 (inlined char::methods::<impl char>::to_digit) {
let mut _2: u32;
let mut _3: u32;
let mut _4: bool;
scope 3 {
scope 5 (inlined Arguments::<'_>::new_const::<1>) {
}
scope 6 (inlined core::num::<impl u32>::wrapping_sub) {
}
scope 7 (inlined core::num::<impl u32>::saturating_add) {
}
}
scope 4 (inlined core::num::<impl u32>::wrapping_sub) {
}
}
scope 8 (inlined Option::<u32>::is_some) {
}
}
scope 3 (inlined #[track_caller] Option::<u32>::unwrap) {
let mut _5: isize;
let mut _6: !;
scope 4 {
scope 9 (inlined char::methods::<impl char>::to_digit) {
let mut _5: u32;
let mut _6: bool;
scope 10 {
scope 12 (inlined Arguments::<'_>::new_const::<1>) {
}
scope 13 (inlined core::num::<impl u32>::wrapping_sub) {
}
scope 14 (inlined core::num::<impl u32>::saturating_add) {
}
}
scope 11 (inlined core::num::<impl u32>::wrapping_sub) {
}
}
scope 15 (inlined #[track_caller] Option::<u32>::unwrap) {
let mut _7: !;
scope 16 {
}
}

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

bb1: {
StorageLive(_3);
_3 = discriminant(_2);
switchInt(move _3) -> [1: bb2, 0: bb6, otherwise: bb8];
StorageDead(_4);
_0 = const 0_u32;
goto -> bb5;
}

bb2: {
StorageDead(_3);
StorageDead(_2);
StorageLive(_4);
_4 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind unreachable];
StorageDead(_4);
StorageLive(_8);
_5 = Sub(_2, const 48_u32);
StorageLive(_6);
_6 = Lt(_5, const 8_u32);
switchInt(move _6) -> [0: bb3, otherwise: bb4];
}

bb3: {
StorageLive(_5);
_5 = discriminant(_4);
switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb8];
StorageDead(_6);
_7 = option::unwrap_failed() -> unwind unreachable;
}

bb4: {
_6 = option::unwrap_failed() -> unwind unreachable;
_8 = Option::<u32>::Some(_5);
StorageDead(_6);
_0 = move ((_8 as Some).0: u32);
StorageDead(_8);
goto -> bb5;
}

bb5: {
_0 = move ((_4 as Some).0: u32);
StorageDead(_5);
StorageDead(_4);
goto -> bb7;
}

bb6: {
StorageDead(_3);
StorageDead(_2);
_0 = const 0_u32;
goto -> bb7;
}

bb7: {
return;
}

bb8: {
unreachable;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,83 @@
fn num_to_digit(_1: char) -> u32 {
debug num => _1;
let mut _0: u32;
let mut _4: std::option::Option<u32>;
let mut _8: std::option::Option<u32>;
scope 1 (inlined char::methods::<impl char>::is_digit) {
let _2: std::option::Option<u32>;
scope 2 (inlined Option::<u32>::is_some) {
let mut _3: isize;
scope 2 (inlined char::methods::<impl char>::to_digit) {
let mut _2: u32;
let mut _3: u32;
let mut _4: bool;
scope 3 {
scope 5 (inlined Arguments::<'_>::new_const::<1>) {
}
scope 6 (inlined core::num::<impl u32>::wrapping_sub) {
}
scope 7 (inlined core::num::<impl u32>::saturating_add) {
}
}
scope 4 (inlined core::num::<impl u32>::wrapping_sub) {
}
}
scope 8 (inlined Option::<u32>::is_some) {
}
}
scope 3 (inlined #[track_caller] Option::<u32>::unwrap) {
let mut _5: isize;
let mut _6: !;
scope 4 {
scope 9 (inlined char::methods::<impl char>::to_digit) {
let mut _5: u32;
let mut _6: bool;
scope 10 {
scope 12 (inlined Arguments::<'_>::new_const::<1>) {
}
scope 13 (inlined core::num::<impl u32>::wrapping_sub) {
}
scope 14 (inlined core::num::<impl u32>::saturating_add) {
}
}
scope 11 (inlined core::num::<impl u32>::wrapping_sub) {
}
}
scope 15 (inlined #[track_caller] Option::<u32>::unwrap) {
let mut _7: !;
scope 16 {
}
}

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

bb1: {
StorageLive(_3);
_3 = discriminant(_2);
switchInt(move _3) -> [1: bb2, 0: bb6, otherwise: bb8];
StorageDead(_4);
_0 = const 0_u32;
goto -> bb5;
}

bb2: {
StorageDead(_3);
StorageDead(_2);
StorageLive(_4);
_4 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind continue];
StorageDead(_4);
StorageLive(_8);
_5 = Sub(_2, const 48_u32);
StorageLive(_6);
_6 = Lt(_5, const 8_u32);
switchInt(move _6) -> [0: bb3, otherwise: bb4];
}

bb3: {
StorageLive(_5);
_5 = discriminant(_4);
switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb8];
StorageDead(_6);
_7 = option::unwrap_failed() -> unwind continue;
}

bb4: {
_6 = option::unwrap_failed() -> unwind continue;
_8 = Option::<u32>::Some(_5);
StorageDead(_6);
_0 = move ((_8 as Some).0: u32);
StorageDead(_8);
goto -> bb5;
}

bb5: {
_0 = move ((_4 as Some).0: u32);
StorageDead(_5);
StorageDead(_4);
goto -> bb7;
}

bb6: {
StorageDead(_3);
StorageDead(_2);
_0 = const 0_u32;
goto -> bb7;
}

bb7: {
return;
}

bb8: {
unreachable;
}
}
Loading

0 comments on commit 29e8c80

Please sign in to comment.