From e85e8d8dd2e526a5881dcd367bcb5c8e0a3b1f50 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 21 Sep 2024 18:19:27 -0400 Subject: [PATCH] Add inline(usually) --- compiler/rustc_attr/src/builtin.rs | 1 + compiler/rustc_codegen_llvm/src/attributes.rs | 3 +++ compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 2 ++ compiler/rustc_middle/src/mir/mono.rs | 2 +- .../rustc_mir_transform/src/cross_crate_inline.rs | 2 +- compiler/rustc_mir_transform/src/inline.rs | 2 +- compiler/rustc_span/src/symbol.rs | 1 + library/core/src/option.rs | 3 ++- library/core/src/result.rs | 3 ++- library/core/src/slice/index.rs | 15 ++++++++++----- 10 files changed, 24 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 309049b98f0e2..7803adb9e324d 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -46,6 +46,7 @@ pub enum InlineAttr { Hint, Always, Never, + Usually, } #[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)] diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 6df63eec51375..3297513ffa872 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -47,6 +47,9 @@ fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll } } InlineAttr::None => None, + InlineAttr::Usually => { + Some(llvm::CreateAttrStringValue(cx.llcx, "function-inline-cost", "0")) + } } } diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 137e481f08ccb..9989840ca53dc 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -546,6 +546,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { InlineAttr::Always } else if list_contains_name(items, sym::never) { InlineAttr::Never + } else if list_contains_name(items, sym::usually) { + InlineAttr::Usually } else { struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument") .with_help("valid inline arguments are `always` and `never`") diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 69b5e0a79c7fa..70b8f234ee249 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -138,7 +138,7 @@ impl<'tcx> MonoItem<'tcx> { // conflict with upstream crates as it could be an exported // symbol. match tcx.codegen_fn_attrs(instance.def_id()).inline { - InlineAttr::Always => InstantiationMode::LocalCopy, + InlineAttr::Always | InlineAttr::Usually => InstantiationMode::LocalCopy, _ => InstantiationMode::GloballyShared { may_conflict: true }, } } diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 42cbece32d8c9..71cb49fb2f57b 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -46,7 +46,7 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { // #[inline(never)] to force code generation. match codegen_fn_attrs.inline { InlineAttr::Never => return false, - InlineAttr::Hint | InlineAttr::Always => return true, + InlineAttr::Hint | InlineAttr::Always | InlineAttr::Usually => return true, _ => {} } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 2de75e2ef50fc..a9642a0396058 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -106,7 +106,7 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { changed: false, caller_is_inline_forwarder: matches!( codegen_fn_attrs.inline, - InlineAttr::Hint | InlineAttr::Always + InlineAttr::Hint | InlineAttr::Always | InlineAttr::Usually ) && body_is_forwarder(body), }; let blocks = START_BLOCK..body.basic_blocks.next_index(); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index de4532bcb9950..20b507bcdb449 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2101,6 +2101,7 @@ symbols! { usize_legacy_fn_max_value, usize_legacy_fn_min_value, usize_legacy_mod, + usually, va_arg, va_copy, va_end, diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 5ba13969605fc..f6aa15303c1c8 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -958,7 +958,8 @@ impl Option { /// let x: Option<&str> = None; /// assert_eq!(x.unwrap(), "air"); // fails /// ``` - #[inline(always)] + #[cfg_attr(bootstrap, inline(always))] + #[cfg_attr(not(bootstrap), inline(usually))] #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "option_unwrap")] diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 9edd58259ba0f..b7c54b3fb6836 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -1091,7 +1091,8 @@ impl Result { /// let x: Result = Err("emergency failure"); /// x.unwrap(); // panics with `emergency failure` /// ``` - #[inline(always)] + #[cfg_attr(bootstrap, inline(always))] + #[cfg_attr(not(bootstrap), inline(usually))] #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] pub fn unwrap(self) -> T diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index bc8571c8503e9..a0978f7a0fcbc 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -11,7 +11,8 @@ where { type Output = I::Output; - #[inline(always)] + #[cfg_attr(bootstrap, inline(always))] + #[cfg_attr(not(bootstrap), inline(usually))] fn index(&self, index: I) -> &I::Output { index.index(self) } @@ -22,7 +23,8 @@ impl ops::IndexMut for [T] where I: SliceIndex<[T]>, { - #[inline(always)] + #[cfg_attr(bootstrap, inline(always))] + #[cfg_attr(not(bootstrap), inline(usually))] fn index_mut(&mut self, index: I) -> &mut I::Output { index.index_mut(self) } @@ -455,7 +457,8 @@ unsafe impl SliceIndex<[T]> for ops::Range { } } - #[inline(always)] + #[cfg_attr(bootstrap, inline(always))] + #[cfg_attr(not(bootstrap), inline(usually))] fn index(self, slice: &[T]) -> &[T] { // Using checked_sub is a safe way to get `SubUnchecked` in MIR let Some(new_len) = usize::checked_sub(self.end, self.start) else { @@ -507,7 +510,8 @@ unsafe impl SliceIndex<[T]> for range::Range { unsafe { ops::Range::from(self).get_unchecked_mut(slice) } } - #[inline(always)] + #[cfg_attr(bootstrap, inline(always))] + #[cfg_attr(not(bootstrap), inline(usually))] fn index(self, slice: &[T]) -> &[T] { ops::Range::from(self).index(slice) } @@ -545,7 +549,8 @@ unsafe impl SliceIndex<[T]> for ops::RangeTo { unsafe { (0..self.end).get_unchecked_mut(slice) } } - #[inline(always)] + #[cfg_attr(bootstrap, inline(always))] + #[cfg_attr(not(bootstrap), inline(usually))] fn index(self, slice: &[T]) -> &[T] { (0..self.end).index(slice) }