Skip to content

Commit cb645d4

Browse files
committed
Auto merge of rust-lang#121114 - Nilstrieb:no-inline!, r=saethlin
Add `#[rustc_no_mir_inline]` for standard library UB checks should help with rust-lang#121110 and also with rust-lang#120848 Because the MIR inliner cannot know whether the checks are enabled or not, so inlining is an unnecessary compile time pessimization when debug assertions are disabled. LLVM knows whether they are enabled or not, so it can optimize accordingly without wasting time. r? `@saethlin`
2 parents df6c197 + 84e435a commit cb645d4

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

core/src/intrinsics.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,13 +2706,25 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize)
27062706
macro_rules! assert_unsafe_precondition {
27072707
($message:expr, ($($name:ident:$ty:ty = $arg:expr),*$(,)?) => $e:expr $(,)?) => {
27082708
{
2709+
// #[cfg(bootstrap)] (this comment)
27092710
// When the standard library is compiled with debug assertions, we want the check to inline for better performance.
27102711
// This is important when working on the compiler, which is compiled with debug assertions locally.
27112712
// When not compiled with debug assertions (so the precompiled std) we outline the check to minimize the compile
27122713
// time impact when debug assertions are disabled.
2713-
// It is not clear whether that is the best solution, see #120848.
2714-
#[cfg_attr(debug_assertions, inline(always))]
2715-
#[cfg_attr(not(debug_assertions), inline(never))]
2714+
// The proper solution to this is the `#[rustc_no_mir_inline]` below, but we still want decent performance for cfg(bootstrap).
2715+
#[cfg_attr(all(debug_assertions, bootstrap), inline(always))]
2716+
#[cfg_attr(all(not(debug_assertions), bootstrap), inline(never))]
2717+
2718+
// This check is inlineable, but not by the MIR inliner.
2719+
// The reason for this is that the MIR inliner is in an exceptionally bad position
2720+
// to think about whether or not to inline this. In MIR, this call is gated behind `debug_assertions`,
2721+
// which will codegen to `false` in release builds. Inlining the check would be wasted work in that case and
2722+
// would be bad for compile times.
2723+
//
2724+
// LLVM on the other hand sees the constant branch, so if it's `false`, it can immediately delete it without
2725+
// inlining the check. If it's `true`, it can inline it and get significantly better performance.
2726+
#[cfg_attr(not(bootstrap), rustc_no_mir_inline)]
2727+
#[cfg_attr(not(bootstrap), inline)]
27162728
#[rustc_nounwind]
27172729
fn precondition_check($($name:$ty),*) {
27182730
if !$e {

0 commit comments

Comments
 (0)