Skip to content

Commit 1bb3a9f

Browse files
committed
Auto merge of #121309 - Nilstrieb:inline-all-the-fallbacks, r=oli-obk
Make intrinsic fallback bodies cross-crate inlineable This change was prompted by the stage1 compiler spending 4% of its time when compiling the polymorphic-recursion MIR opt test in `unlikely`. Intrinsic fallback bodies like `unlikely` should always be inlined, it's very silly if they are not. To do this, we enable the fallback bodies to be cross-crate inlineable. Not that this matters for our workloads since the compiler never actually _uses_ the "fallback bodies", it just uses whatever was cfg(bootstrap)ped, so I've also added `#[inline]` to those. See the comments for more information. r? oli-obk
2 parents 52dba5f + 0f4925e commit 1bb3a9f

File tree

4 files changed

+25
-0
lines changed

4 files changed

+25
-0
lines changed

compiler/rustc_mir_transform/src/cross_crate_inline.rs

+9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_middle::query::Providers;
99
use rustc_middle::ty::TyCtxt;
1010
use rustc_session::config::InliningThreshold;
1111
use rustc_session::config::OptLevel;
12+
use rustc_span::sym;
1213

1314
pub fn provide(providers: &mut Providers) {
1415
providers.cross_crate_inlinable = cross_crate_inlinable;
@@ -34,6 +35,14 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
3435
return true;
3536
}
3637

38+
if tcx.has_attr(def_id, sym::rustc_intrinsic) {
39+
// Intrinsic fallback bodies are always cross-crate inlineable.
40+
// To ensure that the MIR inliner doesn't cluelessly try to inline fallback
41+
// bodies even when the backend would implement something better, we stop
42+
// the MIR inliner from ever inlining an intrinsic.
43+
return true;
44+
}
45+
3746
// Obey source annotations first; this is important because it means we can use
3847
// #[inline(never)] to force code generation.
3948
match codegen_fn_attrs.inline {

compiler/rustc_mir_transform/src/inline.rs

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_middle::ty::TypeVisitableExt;
1313
use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
1414
use rustc_session::config::OptLevel;
1515
use rustc_span::source_map::Spanned;
16+
use rustc_span::sym;
1617
use rustc_target::abi::FieldIdx;
1718
use rustc_target::spec::abi::Abi;
1819

@@ -170,6 +171,13 @@ impl<'tcx> Inliner<'tcx> {
170171
let cross_crate_inlinable = self.tcx.cross_crate_inlinable(callsite.callee.def_id());
171172
self.check_codegen_attributes(callsite, callee_attrs, cross_crate_inlinable)?;
172173

174+
// Intrinsic fallback bodies are automatically made cross-crate inlineable,
175+
// but at this stage we don't know whether codegen knows the intrinsic,
176+
// so just conservatively don't inline it.
177+
if self.tcx.has_attr(callsite.callee.def_id(), sym::rustc_intrinsic) {
178+
return Err("Callee is an intrinsic, do not inline fallback bodies");
179+
}
180+
173181
let terminator = caller_body[callsite.block].terminator.as_ref().unwrap();
174182
let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() };
175183
let destination_ty = destination.ty(&caller_body.local_decls, self.tcx).ty;

library/core/src/intrinsics.rs

+6
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,7 @@ extern "rust-intrinsic" {
953953
#[rustc_nounwind]
954954
#[unstable(feature = "core_intrinsics", issue = "none")]
955955
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
956+
#[cfg_attr(bootstrap, inline)]
956957
pub const unsafe fn assume(b: bool) {
957958
if !b {
958959
// SAFETY: the caller must guarantee the argument is never `false`
@@ -975,6 +976,7 @@ pub const unsafe fn assume(b: bool) {
975976
#[unstable(feature = "core_intrinsics", issue = "none")]
976977
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
977978
#[rustc_nounwind]
979+
#[cfg_attr(bootstrap, inline)]
978980
pub const fn likely(b: bool) -> bool {
979981
b
980982
}
@@ -994,6 +996,7 @@ pub const fn likely(b: bool) -> bool {
994996
#[unstable(feature = "core_intrinsics", issue = "none")]
995997
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
996998
#[rustc_nounwind]
999+
#[cfg_attr(bootstrap, inline)]
9971000
pub const fn unlikely(b: bool) -> bool {
9981001
b
9991002
}
@@ -2596,6 +2599,7 @@ extern "rust-intrinsic" {
25962599
#[rustc_nounwind]
25972600
#[unstable(feature = "core_intrinsics", issue = "none")]
25982601
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
2602+
#[cfg_attr(bootstrap, inline)]
25992603
pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
26002604
false
26012605
}
@@ -2633,6 +2637,7 @@ pub(crate) const fn debug_assertions() -> bool {
26332637
#[unstable(feature = "core_intrinsics", issue = "none")]
26342638
#[rustc_nounwind]
26352639
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
2640+
#[cfg_attr(bootstrap, inline)]
26362641
pub const unsafe fn const_allocate(_size: usize, _align: usize) -> *mut u8 {
26372642
// const eval overrides this function, but runtime code should always just return null pointers.
26382643
crate::ptr::null_mut()
@@ -2652,6 +2657,7 @@ pub const unsafe fn const_allocate(_size: usize, _align: usize) -> *mut u8 {
26522657
#[unstable(feature = "core_intrinsics", issue = "none")]
26532658
#[rustc_nounwind]
26542659
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
2660+
#[cfg_attr(bootstrap, inline)]
26552661
pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
26562662

26572663
// Some functions are defined here because they accidentally got made

src/doc/unstable-book/src/language-features/intrinsics.md

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ the intrinsic directly when you can.
1414
Many intrinsics can be written in pure rust, albeit inefficiently or without supporting
1515
some features that only exist on some backends. Backends can simply not implement those
1616
intrinsics without causing any code miscompilations or failures to compile.
17+
All intrinsic fallback bodies are automatically made cross-crate inlineable (like `#[inline]`)
18+
by the codegen backend, but not the MIR inliner.
1719

1820
```rust
1921
#![feature(rustc_attrs, effects)]

0 commit comments

Comments
 (0)