Skip to content

Commit

Permalink
Auto merge of rust-lang#116583 - saethlin:inline-small-core-fns, r=<try>
Browse files Browse the repository at this point in the history
Add #[inline] to small functions in core

I'm adding a new case to the definition of cross-crate-inlinable; we know that making the definition too broad causes huge regressions in incremental builds. So implementing broader heuristics as a machine-applicable lint means that I can `x fix --stage 1 library/core` to apply the new heuristic just to the standard library. I expect that applying the broader heuristic just to the standard library will have a different effect than applying the change globally.
  • Loading branch information
bors committed Nov 4, 2023
2 parents f81d6f0 + 9c3c8ef commit d11ea83
Show file tree
Hide file tree
Showing 40 changed files with 162 additions and 6 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn expand_deriving_debug(
explicit_self: true,
nonself_args: vec![(fmtr, sym::f)],
ret_ty: Path(path_std!(fmt::Result)),
attributes: ast::AttrVec::new(),
attributes: thin_vec![cx.attr_word(sym::inline, span)],
fieldless_variants_strategy:
FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_mir_transform/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ mir_transform_requires_unsafe = {$details} is unsafe and requires unsafe {$op_in
}
.not_inherited = items do not inherit unsafety from separate enclosing items
mir_transform_small_fn_without_inline = this function looks small ({$statements}) but doesn't have #[inline], consider adding it
.suggestion = add the inline attribute
mir_transform_target_feature_call_label = call to function with `#[target_feature]`
mir_transform_target_feature_call_note = can only be called if the required target features are available
Expand Down
39 changes: 34 additions & 5 deletions compiler/rustc_mir_transform/src/cross_crate_inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,37 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
}

let mir = tcx.optimized_mir(def_id);
let mut checker =
CostChecker { tcx, callee_body: mir, calls: 0, statements: 0, landing_pads: 0, resumes: 0 };
let mut checker = CostChecker {
tcx,
callee_body: mir,
calls: 0,
statements: 0,
landing_pads: 0,
resumes: 0,
branches: 0,
asserts: 0,
};
checker.visit_body(mir);
checker.calls == 0
let is_leaf = checker.calls == 0
&& checker.resumes == 0
&& checker.landing_pads == 0
&& checker.statements
<= tcx.sess.opts.unstable_opts.cross_crate_inline_threshold.unwrap_or(100)
<= tcx.sess.opts.unstable_opts.cross_crate_inline_threshold.unwrap_or(100);

let is_trivial_wrapper = checker.calls == 1
&& checker.resumes == 0
&& checker.landing_pads == 0
&& mir.basic_blocks.len() == 2;

if is_trivial_wrapper {
let span = tcx.def_span(def_id);
tcx.sess.emit_warning(crate::errors::SuggestAddingInline {
place: span,
suggest_inline: span.with_hi(span.lo()),
statements: checker.statements,
});
}
is_leaf
}

struct CostChecker<'b, 'tcx> {
Expand All @@ -72,6 +95,8 @@ struct CostChecker<'b, 'tcx> {
statements: usize,
landing_pads: usize,
resumes: usize,
branches: usize,
asserts: usize,
}

impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
Expand Down Expand Up @@ -105,7 +130,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
}
}
TerminatorKind::Assert { unwind, .. } => {
self.calls += 1;
self.asserts += 1;
if let UnwindAction::Cleanup(_) = unwind {
self.landing_pads += 1;
}
Expand All @@ -117,6 +142,10 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
self.landing_pads += 1;
}
}
TerminatorKind::SwitchInt { .. } => {
self.statements += 1;
self.branches += 1;
}
TerminatorKind::Return => {}
_ => self.statements += 1,
}
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_mir_transform/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,13 @@ pub(crate) struct MustNotSuspendReason {
pub span: Span,
pub reason: String,
}

#[derive(Diagnostic)]
#[diag(mir_transform_small_fn_without_inline)]
pub struct SuggestAddingInline {
#[primary_span]
pub place: Span,
#[suggestion(code = "#[inline]\n", applicability = "machine-applicable")]
pub suggest_inline: Span,
pub statements: usize,
}
1 change: 1 addition & 0 deletions library/core/src/alloc/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ impl Error for LayoutError {}
// (we need this for downstream impl of trait Error)
#[stable(feature = "alloc_layout", since = "1.28.0")]
impl fmt::Display for LayoutError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("invalid parameters to Layout::from_size_align")
}
Expand Down
1 change: 1 addition & 0 deletions library/core/src/alloc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl Error for AllocError {}
// (we need this for downstream impl of trait Error)
#[unstable(feature = "allocator_api", issue = "32838")]
impl fmt::Display for AllocError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("memory allocation failed")
}
Expand Down
1 change: 1 addition & 0 deletions library/core/src/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,7 @@ impl TypeId {
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
#[inline]
pub const fn of<T: ?Sized + 'static>() -> TypeId {
let t: u128 = intrinsics::type_id::<T>();
TypeId { t }
Expand Down
1 change: 1 addition & 0 deletions library/core/src/ascii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub struct EscapeDefault(escape::EscapeIterInner<4>);
/// assert_eq!(b'd', escaped.next().unwrap());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn escape_default(c: u8) -> EscapeDefault {
let mut data = [Char::Null; 4];
let range = escape::escape_ascii_into(&mut data, c);
Expand Down
1 change: 1 addition & 0 deletions library/core/src/ascii/ascii_char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ impl [AsciiChar] {

#[unstable(feature = "ascii_char", issue = "110998")]
impl fmt::Display for AsciiChar {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
<str as fmt::Display>::fmt(self.as_str(), f)
}
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ impl Debug for BorrowError {

#[stable(feature = "try_borrow", since = "1.13.0")]
impl Display for BorrowError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt("already mutably borrowed", f)
}
Expand Down Expand Up @@ -749,6 +750,7 @@ impl Debug for BorrowMutError {

#[stable(feature = "try_borrow", since = "1.13.0")]
impl Display for BorrowMutError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt("already borrowed", f)
}
Expand Down
1 change: 1 addition & 0 deletions library/core/src/char/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ pub struct CharTryFromError(());

#[stable(feature = "try_from", since = "1.34.0")]
impl fmt::Display for CharTryFromError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
"converted integer out of range for `char`".fmt(f)
}
Expand Down
12 changes: 12 additions & 0 deletions library/core/src/char/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
pub struct EscapeUnicode(escape::EscapeIterInner<10>);

impl EscapeUnicode {
#[inline]
fn new(chr: char) -> Self {
let mut data = [ascii::Char::Null; 10];
let range = escape::escape_unicode_into(&mut data, chr);
Expand Down Expand Up @@ -219,11 +220,13 @@ impl fmt::Display for EscapeUnicode {
pub struct EscapeDefault(escape::EscapeIterInner<10>);

impl EscapeDefault {
#[inline]
fn printable(chr: ascii::Char) -> Self {
let data = [chr];
Self(escape::EscapeIterInner::from_array(data))
}

#[inline]
fn backslash(chr: ascii::Char) -> Self {
let data = [ascii::Char::ReverseSolidus, chr];
Self(escape::EscapeIterInner::from_array(data))
Expand Down Expand Up @@ -308,6 +311,7 @@ impl EscapeDebug {
Self(EscapeDebugInner::Char(chr))
}

#[inline]
fn backslash(chr: ascii::Char) -> Self {
let data = [ascii::Char::ReverseSolidus, chr];
let iter = escape::EscapeIterInner::from_array(data);
Expand All @@ -318,6 +322,7 @@ impl EscapeDebug {
Self(EscapeDebugInner::Bytes(esc.0))
}

#[inline]
fn clear(&mut self) {
let bytes = escape::EscapeIterInner::from_array([]);
self.0 = EscapeDebugInner::Bytes(bytes);
Expand Down Expand Up @@ -386,6 +391,7 @@ pub struct ToLowercase(CaseMappingIter);
#[stable(feature = "rust1", since = "1.0.0")]
impl Iterator for ToLowercase {
type Item = char;
#[inline]
fn next(&mut self) -> Option<char> {
self.0.next()
}
Expand All @@ -396,6 +402,7 @@ impl Iterator for ToLowercase {

#[stable(feature = "case_mapping_double_ended", since = "1.59.0")]
impl DoubleEndedIterator for ToLowercase {
#[inline]
fn next_back(&mut self) -> Option<char> {
self.0.next_back()
}
Expand All @@ -420,6 +427,7 @@ pub struct ToUppercase(CaseMappingIter);
#[stable(feature = "rust1", since = "1.0.0")]
impl Iterator for ToUppercase {
type Item = char;
#[inline]
fn next(&mut self) -> Option<char> {
self.0.next()
}
Expand All @@ -430,6 +438,7 @@ impl Iterator for ToUppercase {

#[stable(feature = "case_mapping_double_ended", since = "1.59.0")]
impl DoubleEndedIterator for ToUppercase {
#[inline]
fn next_back(&mut self) -> Option<char> {
self.0.next_back()
}
Expand Down Expand Up @@ -534,13 +543,15 @@ impl fmt::Display for CaseMappingIter {

#[stable(feature = "char_struct_display", since = "1.16.0")]
impl fmt::Display for ToLowercase {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}

#[stable(feature = "char_struct_display", since = "1.16.0")]
impl fmt::Display for ToUppercase {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
Expand All @@ -553,6 +564,7 @@ pub struct TryFromCharError(pub(crate) ());

#[stable(feature = "u8_from_char", since = "1.59.0")]
impl fmt::Display for TryFromCharError {
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
"unicode code point out of range".fmt(fmt)
}
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/escape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,12 @@ impl<const N: usize> EscapeIterInner<N> {
Self::new(data, 0..M as u8)
}

#[inline]
pub fn as_ascii(&self) -> &[ascii::Char] {
&self.data[usize::from(self.alive.start)..usize::from(self.alive.end)]
}

#[inline]
pub fn as_str(&self) -> &str {
self.as_ascii().as_str()
}
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ pub struct FromBytesUntilNulError(());

#[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")]
impl fmt::Display for FromBytesUntilNulError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "data provided does not contain a nul")
}
Expand Down Expand Up @@ -623,6 +624,7 @@ impl CStr {
/// ```
#[stable(feature = "cstr_to_str", since = "1.4.0")]
#[rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0")]
#[inline]
pub const fn to_str(&self) -> Result<&str, str::Utf8Error> {
// N.B., when `CStr` is changed to perform the length check in `.to_bytes()`
// instead of in `from_ptr()`, it may be worth considering if this should
Expand Down
8 changes: 8 additions & 0 deletions library/core/src/fmt/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ impl Default for PadAdapterState {
}

impl<'buf, 'state> PadAdapter<'buf, 'state> {
#[inline]
fn wrap<'slot, 'fmt: 'buf + 'slot>(
fmt: &'fmt mut fmt::Formatter<'_>,
slot: &'slot mut Option<Self>,
Expand Down Expand Up @@ -91,6 +92,7 @@ pub struct DebugStruct<'a, 'b: 'a> {
has_fields: bool,
}

#[inline]
pub(super) fn debug_struct_new<'a, 'b>(
fmt: &'a mut fmt::Formatter<'b>,
name: &str,
Expand Down Expand Up @@ -281,6 +283,7 @@ pub struct DebugTuple<'a, 'b: 'a> {
empty_name: bool,
}

#[inline]
pub(super) fn debug_tuple_new<'a, 'b>(
fmt: &'a mut fmt::Formatter<'b>,
name: &str,
Expand Down Expand Up @@ -444,6 +447,7 @@ pub struct DebugSet<'a, 'b: 'a> {
inner: DebugInner<'a, 'b>,
}

#[inline]
pub(super) fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
let result = fmt.write_str("{");
DebugSet { inner: DebugInner { fmt, result, has_fields: false } }
Expand Down Expand Up @@ -474,6 +478,7 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
/// );
/// ```
#[stable(feature = "debug_builders", since = "1.2.0")]
#[inline]
pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {
self.inner.entry(entry);
self
Expand Down Expand Up @@ -574,6 +579,7 @@ pub struct DebugList<'a, 'b: 'a> {
inner: DebugInner<'a, 'b>,
}

#[inline]
pub(super) fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
let result = fmt.write_str("[");
DebugList { inner: DebugInner { fmt, result, has_fields: false } }
Expand Down Expand Up @@ -604,6 +610,7 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {
/// );
/// ```
#[stable(feature = "debug_builders", since = "1.2.0")]
#[inline]
pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {
self.inner.entry(entry);
self
Expand Down Expand Up @@ -709,6 +716,7 @@ pub struct DebugMap<'a, 'b: 'a> {
state: PadAdapterState,
}

#[inline]
pub(super) fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
let result = fmt.write_str("{");
DebugMap { fmt, result, has_fields: false, has_key: false, state: Default::default() }
Expand Down
4 changes: 4 additions & 0 deletions library/core/src/fmt/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,27 +198,31 @@ macro_rules! floating {
($ty:ident) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for $ty {
#[inline]
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
float_to_general_debug(fmt, self)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Display for $ty {
#[inline]
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
float_to_decimal_display(fmt, self)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl LowerExp for $ty {
#[inline]
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
float_to_exponential_common(fmt, self, false)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl UpperExp for $ty {
#[inline]
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
float_to_exponential_common(fmt, self, true)
}
Expand Down
Loading

0 comments on commit d11ea83

Please sign in to comment.