Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f4b36c8

Browse files
Auto merge of #144483 - scottmcm:early-inline, r=<try>
EXPERIMENT: Use the force-inline pass for more stuff
2 parents 383b9c4 + a6adf2d commit f4b36c8

23 files changed

+256
-54
lines changed

‎compiler/rustc_attr_parsing/src/attributes/inline.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,16 @@ impl<S: Stage> SingleAttributeParser<S> for RustcForceInlineParser {
9393
))
9494
}
9595
}
96+
97+
pub(crate) struct RustcEarlyInlineParser;
98+
99+
impl<S: Stage> SingleAttributeParser<S> for RustcEarlyInlineParser {
100+
const PATH: &'static [Symbol] = &[sym::rustc_early_inline];
101+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
102+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
103+
const TEMPLATE: AttributeTemplate = template!(Word);
104+
105+
fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
106+
Some(AttributeKind::Inline(InlineAttr::Early, cx.attr_span))
107+
}
108+
}

‎compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::attributes::codegen_attrs::{
2323
use crate::attributes::confusables::ConfusablesParser;
2424
use crate::attributes::deprecation::DeprecationParser;
2525
use crate::attributes::dummy::DummyParser;
26-
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
26+
use crate::attributes::inline::{InlineParser, RustcEarlyInlineParser,RustcForceInlineParser};
2727
use crate::attributes::link_attrs::{
2828
ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkOrdinalParser,
2929
LinkSectionParser, StdInternalSymbolParser,
@@ -169,6 +169,7 @@ attribute_parsers!(
169169
Single<PathAttributeParser>,
170170
Single<ProcMacroDeriveParser>,
171171
Single<RustcBuiltinMacroParser>,
172+
Single<RustcEarlyInlineParser>,
172173
Single<RustcForceInlineParser>,
173174
Single<RustcLayoutScalarValidRangeEnd>,
174175
Single<RustcLayoutScalarValidRangeStart>,

‎compiler/rustc_codegen_gcc/src/attributes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ fn inline_attr<'gcc, 'tcx>(
6767
Some(FnAttribute::AlwaysInline)
6868
}
6969
}
70-
InlineAttr::Hint => Some(FnAttribute::Inline),
70+
InlineAttr::Hint | InlineAttr::Early=> Some(FnAttribute::Inline),
7171
InlineAttr::Force { .. } => Some(FnAttribute::AlwaysInline),
7272
InlineAttr::Never => {
7373
if cx.sess().target.arch != "amdgpu" {

‎compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll
5252
return Some(AttributeKind::NoInline.create_attr(cx.llcx));
5353
}
5454
match inline {
55-
InlineAttr::Hint => Some(AttributeKind::InlineHint.create_attr(cx.llcx)),
55+
InlineAttr::Hint | InlineAttr::Early => {
56+
Some(AttributeKind::InlineHint.create_attr(cx.llcx))
57+
}
5658
InlineAttr::Always | InlineAttr::Force { .. } => {
5759
Some(AttributeKind::AlwaysInline.create_attr(cx.llcx))
5860
}

‎compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ fn check_result(
473473

474474
// warn that inline has no effect when no_sanitize is present
475475
if !codegen_fn_attrs.no_sanitize.is_empty()
476-
&& codegen_fn_attrs.inline.always()
476+
&& codegen_fn_attrs.inline.always_in_codegen()
477477
&& let (Some(no_sanitize_span), Some(inline_span)) =
478478
(interesting_spans.no_sanitize, interesting_spans.inline)
479479
{

‎compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,11 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
11231123
rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes,
11241124
"`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen"
11251125
),
1126+
rustc_attr!(
1127+
rustc_early_inline, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes,
1128+
"`#[rustc_early_inline]` inlines non-generic calls to trivial methods even in debug, \
1129+
while still allowing them to be codegen'd for generic calls"
1130+
),
11261131
rustc_attr!(
11271132
rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes,
11281133
"`#[rustc_force_inline]` forces a free function to be inlined"

‎compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,20 @@ pub enum InlineAttr {
2424
attr_span: Span,
2525
reason: Option<Symbol>,
2626
},
27+
/// `#[rustc_early_inline]` will always inline calls to a known impl in MIR.
28+
///
29+
/// You can think of this as either
30+
/// - Force, but without the "do not codegen as a function ever" restriction.
31+
/// - Always, but only for MIR.
32+
Early,
2733
}
2834

2935
impl InlineAttr {
30-
pub fn always(&self) -> bool {
36+
pub fn always_in_codegen(&self) -> bool {
3137
match self {
32-
InlineAttr::Always | InlineAttr::Force { .. } => true,
33-
InlineAttr::None | InlineAttr::Hint | InlineAttr::Never => false,
38+
InlineAttr::Always => true,
39+
InlineAttr::None | InlineAttr::Hint | InlineAttr::Early | InlineAttr::Never => false,
40+
InlineAttr::Force { .. } => panic!("Shouldn't be codegen'ing {self:?}"),
3441
}
3542
}
3643
}
@@ -342,7 +349,7 @@ pub enum AttributeKind {
342349
reason: Option<Symbol>,
343350
},
344351

345-
/// Represents `#[inline]` and `#[rustc_force_inline]`.
352+
/// Represents `#[inline]` and `#[rustc_force_inline]` and `#[rustc_early_inline]`.
346353
Inline(InlineAttr, Span),
347354

348355
/// Represents `#[link_name]`.

‎compiler/rustc_middle/src/mir/mono.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ impl<'tcx> MonoItem<'tcx> {
205205

206206
// To ensure that #[inline(always)] can be inlined as much as possible, especially in unoptimized
207207
// builds, we always select LocalCopy.
208-
if codegen_fn_attrs.inline.always() {
208+
if codegen_fn_attrs.inline.always_in_codegen() {
209209
return InstantiationMode::LocalCopy;
210210
}
211211

‎compiler/rustc_mir_transform/src/cross_crate_inline.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
4646
// #[inline(never)] to force code generation.
4747
match codegen_fn_attrs.inline {
4848
InlineAttr::Never => return false,
49-
InlineAttr::Hint | InlineAttr::Always | InlineAttr::Force { .. } => return true,
50-
_ => {}
49+
InlineAttr::Hint | InlineAttr::Always | InlineAttr::Early | InlineAttr::Force { .. } => {
50+
return true;
51+
}
52+
InlineAttr::None => {}
5153
}
5254

5355
// If the crate is likely to be mostly unused, use cross-crate inlining to defer codegen until

‎compiler/rustc_mir_transform/src/inline.rs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub struct ForceInline;
7777

7878
impl ForceInline {
7979
pub fn should_run_pass_for_callee<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
80-
matches!(tcx.codegen_fn_attrs(def_id).inline, InlineAttr::Force { .. })
80+
matches!(tcx.codegen_fn_attrs(def_id).inline, InlineAttr::Force { .. } | InlineAttr::Early)
8181
}
8282
}
8383

@@ -195,7 +195,7 @@ impl<'tcx> Inliner<'tcx> for ForceInliner<'tcx> {
195195
&self,
196196
callee_attrs: &CodegenFnAttrs,
197197
) -> Result<(), &'static str> {
198-
debug_assert_matches!(callee_attrs.inline, InlineAttr::Force { .. });
198+
debug_assert_matches!(callee_attrs.inline, InlineAttr::Force { .. } | InlineAttr::Early);
199199
Ok(())
200200
}
201201

@@ -247,23 +247,26 @@ impl<'tcx> Inliner<'tcx> for ForceInliner<'tcx> {
247247

248248
fn on_inline_failure(&self, callsite: &CallSite<'tcx>, reason: &'static str) {
249249
let tcx = self.tcx();
250-
let InlineAttr::Force { attr_span, reason: justification } =
251-
tcx.codegen_fn_attrs(callsite.callee.def_id()).inline
252-
else {
253-
bug!("called on item without required inlining");
254-
};
255-
256-
let call_span = callsite.source_info.span;
257-
tcx.dcx().emit_err(crate::errors::ForceInlineFailure {
258-
call_span,
259-
attr_span,
260-
caller_span: tcx.def_span(self.def_id),
261-
caller: tcx.def_path_str(self.def_id),
262-
callee_span: tcx.def_span(callsite.callee.def_id()),
263-
callee: tcx.def_path_str(callsite.callee.def_id()),
264-
reason,
265-
justification: justification.map(|sym| crate::errors::ForceInlineJustification { sym }),
266-
});
250+
match tcx.codegen_fn_attrs(callsite.callee.def_id()).inline {
251+
InlineAttr::Early => {
252+
// Ok, we don't actually mind if this fails.
253+
}
254+
InlineAttr::Force { attr_span, reason: justification } => {
255+
let call_span = callsite.source_info.span;
256+
tcx.dcx().emit_err(crate::errors::ForceInlineFailure {
257+
call_span,
258+
attr_span,
259+
caller_span: tcx.def_span(self.def_id),
260+
caller: tcx.def_path_str(self.def_id),
261+
callee_span: tcx.def_span(callsite.callee.def_id()),
262+
callee: tcx.def_path_str(callsite.callee.def_id()),
263+
reason,
264+
justification: justification
265+
.map(|sym| crate::errors::ForceInlineJustification { sym }),
266+
});
267+
}
268+
_ => bug!("called on item without required inlining"),
269+
}
267270
}
268271
}
269272

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /