Skip to content

Commit cd55aff

Browse files
committed
Auto merge of rust-lang#141055 - saethlin:attribute-overrides, r=<try>
Hack together inline-always-overrides `@cbiffle` pointed out to me that sometimes when size-optimizing, you really want a `#[inline(always)]` on some function in a dependency or the standard library and it's a chore to add that attribute in, and it would be neat to give the compiler an override. I don't think this is too hard to hack together, so here's a hack. I don't think the implementation can be more effective than this, so this draft will be useful to collect some information on whether this can even do the thing.
2 parents 1b9efcd + d2221bd commit cd55aff

File tree

10 files changed

+45
-14
lines changed

10 files changed

+45
-14
lines changed

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage {
5151
}
5252
}
5353

54-
fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
54+
fn codegen_fn_attrs_provider(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
5555
if cfg!(debug_assertions) {
5656
let def_kind = tcx.def_kind(did);
5757
assert!(
@@ -923,6 +923,20 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
923923
Some(AutoDiffAttrs { mode, width, ret_activity, input_activity: arg_activities })
924924
}
925925

926+
fn codegen_fn_attrs_overridden(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
927+
let mut attrs = tcx.codegen_fn_attrs_imp(did).clone();
928+
let overrides = tcx.sess.opts.unstable_opts.inline_always_overrides.as_ref().unwrap();
929+
if overrides.contains(&tcx.def_path_str(did)) {
930+
attrs.inline = InlineAttr::Always;
931+
}
932+
attrs
933+
}
934+
926935
pub(crate) fn provide(providers: &mut Providers) {
927-
*providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers };
936+
*providers = Providers {
937+
codegen_fn_attrs_imp: codegen_fn_attrs_provider,
938+
codegen_fn_attrs_overridden,
939+
should_inherit_track_caller,
940+
..*providers
941+
};
928942
}

compiler/rustc_const_eval/src/interpret/intern.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ fn intern_as_new_static<'tcx>(
131131
// These do not inherit the codegen attrs of the parent static allocation, since
132132
// it doesn't make sense for them to inherit their `#[no_mangle]` and `#[link_name = ..]`
133133
// and the like.
134-
feed.codegen_fn_attrs(CodegenFnAttrs::new());
134+
feed.codegen_fn_attrs_imp(CodegenFnAttrs::new());
135135

136136
feed.eval_static_initializer(Ok(alloc));
137137
feed.generics_of(tcx.generics_of(static_id).clone());

compiler/rustc_hir_analysis/src/collect.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
313313
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
314314
if let hir::ExprKind::Closure(closure) = expr.kind {
315315
self.tcx.ensure_ok().generics_of(closure.def_id);
316-
self.tcx.ensure_ok().codegen_fn_attrs(closure.def_id);
316+
self.tcx.ensure_ok().codegen_fn_attrs_imp(closure.def_id);
317317
// We do not call `type_of` for closures here as that
318318
// depends on typecheck and would therefore hide
319319
// any further errors in case one typeck fails.
@@ -691,11 +691,11 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
691691
}
692692
match item.kind {
693693
hir::ForeignItemKind::Fn(..) => {
694-
tcx.ensure_ok().codegen_fn_attrs(item.owner_id);
694+
tcx.ensure_ok().codegen_fn_attrs_imp(item.owner_id);
695695
tcx.ensure_ok().fn_sig(item.owner_id)
696696
}
697697
hir::ForeignItemKind::Static(..) => {
698-
tcx.ensure_ok().codegen_fn_attrs(item.owner_id);
698+
tcx.ensure_ok().codegen_fn_attrs_imp(item.owner_id);
699699
let mut visitor = HirPlaceholderCollector::default();
700700
visitor.visit_foreign_item(item);
701701
placeholder_type_error(
@@ -782,7 +782,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
782782
tcx.ensure_ok().type_of(def_id);
783783
tcx.ensure_ok().predicates_of(def_id);
784784
tcx.ensure_ok().fn_sig(def_id);
785-
tcx.ensure_ok().codegen_fn_attrs(def_id);
785+
tcx.ensure_ok().codegen_fn_attrs_imp(def_id);
786786
}
787787
}
788788
}
@@ -795,7 +795,7 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
795795

796796
match trait_item.kind {
797797
hir::TraitItemKind::Fn(..) => {
798-
tcx.ensure_ok().codegen_fn_attrs(def_id);
798+
tcx.ensure_ok().codegen_fn_attrs_imp(def_id);
799799
tcx.ensure_ok().type_of(def_id);
800800
tcx.ensure_ok().fn_sig(def_id);
801801
}
@@ -867,7 +867,7 @@ fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
867867
let icx = ItemCtxt::new(tcx, def_id.def_id);
868868
match impl_item.kind {
869869
hir::ImplItemKind::Fn(..) => {
870-
tcx.ensure_ok().codegen_fn_attrs(def_id);
870+
tcx.ensure_ok().codegen_fn_attrs_imp(def_id);
871871
tcx.ensure_ok().fn_sig(def_id);
872872
}
873873
hir::ImplItemKind::Type(_) => {

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ provide! { tcx, def_id, other, cdata,
251251
type_alias_is_lazy => { table_direct }
252252
variances_of => { table }
253253
fn_sig => { table }
254-
codegen_fn_attrs => { table }
254+
codegen_fn_attrs_imp => { table }
255255
impl_trait_header => { table }
256256
const_param_default => { table }
257257
object_lifetime_default => { table }

compiler/rustc_metadata/src/rmeta/encoder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1431,7 +1431,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14311431
record!(self.tables.def_ident_span[def_id] <- ident_span);
14321432
}
14331433
if def_kind.has_codegen_attrs() {
1434-
record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id));
1434+
record!(self.tables.codegen_fn_attrs_imp[def_id] <- self.tcx.codegen_fn_attrs(def_id));
14351435
}
14361436
if should_encode_visibility(def_kind) {
14371437
let vis =

compiler/rustc_metadata/src/rmeta/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ define_tables! {
431431
type_of: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, Ty<'static>>>>,
432432
variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
433433
fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::PolyFnSig<'static>>>>,
434-
codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
434+
codegen_fn_attrs_imp: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
435435
impl_trait_header: Table<DefIndex, LazyValue<ty::ImplTraitHeader<'static>>>,
436436
const_param_default: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, rustc_middle::ty::Const<'static>>>>,
437437
object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,

compiler/rustc_middle/src/query/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1443,14 +1443,19 @@ rustc_queries! {
14431443
separate_provide_extern
14441444
}
14451445

1446-
query codegen_fn_attrs(def_id: DefId) -> &'tcx CodegenFnAttrs {
1446+
query codegen_fn_attrs_imp(def_id: DefId) -> &'tcx CodegenFnAttrs {
14471447
desc { |tcx| "computing codegen attributes of `{}`", tcx.def_path_str(def_id) }
14481448
arena_cache
14491449
cache_on_disk_if { def_id.is_local() }
14501450
separate_provide_extern
14511451
feedable
14521452
}
14531453

1454+
query codegen_fn_attrs_overridden(def_id: DefId) -> &'tcx CodegenFnAttrs {
1455+
desc { |tcx| "computing codegen attributes of `{}` (with overrides)", tcx.def_path_str(def_id) }
1456+
arena_cache
1457+
}
1458+
14541459
query asm_target_features(def_id: DefId) -> &'tcx FxIndexSet<Symbol> {
14551460
desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) }
14561461
}

compiler/rustc_middle/src/ty/context.rs

+9
Original file line numberDiff line numberDiff line change
@@ -3395,6 +3395,15 @@ impl<'tcx> TyCtxt<'tcx> {
33953395
pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
33963396
self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
33973397
}
3398+
3399+
pub fn codegen_fn_attrs(self, def_id: impl IntoQueryParam<DefId>) -> &'tcx CodegenFnAttrs {
3400+
let def_id = def_id.into_query_param();
3401+
if self.sess.opts.unstable_opts.inline_always_overrides.is_some() {
3402+
self.codegen_fn_attrs_overridden(def_id)
3403+
} else {
3404+
self.codegen_fn_attrs_imp(def_id)
3405+
}
3406+
}
33983407
}
33993408

34003409
/// Parameter attributes that can only be determined by examining the body of a function instead

compiler/rustc_mir_transform/src/coroutine/by_move_body.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>(
230230
// Feed HIR because we try to access this body's attrs in the inliner.
231231
body_def.feed_hir();
232232
// Inherited from the by-ref coroutine.
233-
body_def.codegen_fn_attrs(tcx.codegen_fn_attrs(coroutine_def_id).clone());
233+
body_def.codegen_fn_attrs_imp(tcx.codegen_fn_attrs(coroutine_def_id).clone());
234234
body_def.coverage_attr_on(tcx.coverage_attr_on(coroutine_def_id));
235235
body_def.constness(tcx.constness(coroutine_def_id));
236236
body_def.coroutine_kind(tcx.coroutine_kind(coroutine_def_id));

compiler/rustc_session/src/options.rs

+3
Original file line numberDiff line numberDiff line change
@@ -2249,6 +2249,9 @@ options! {
22492249
- hashes of green query instances
22502250
- hash collisions of query keys
22512251
- hash collisions when creating dep-nodes"),
2252+
inline_always_overrides: Option<Vec<String>> = (None, parse_opt_comma_list, [TRACKED],
2253+
"comma-separated list of full paths to functions to treat as if they are inline(always)"
2254+
),
22522255
inline_llvm: bool = (true, parse_bool, [TRACKED],
22532256
"enable LLVM inlining (default: yes)"),
22542257
inline_mir: Option<bool> = (None, parse_opt_bool, [TRACKED],

0 commit comments

Comments
 (0)