Skip to content

Commit 9bc8b00

Browse files
committed
Auto merge of #80718 - tmiasko:skip-opt-mir, r=oli-obk
Consistently avoid constructing optimized MIR when not doing codegen The optimized MIR for closures is being encoded unconditionally, while being unnecessary for cargo check. This turns out to be especially costly with MIR inlining enabled, since it triggers computation of optimized MIR for all callees that are being examined for inlining purposes #77307 (comment). Skip encoding of optimized MIR for closures, enum constructors, struct constructors, and trait fns when not doing codegen, like it is already done for other items since 49433.
2 parents fd2df74 + 1685731 commit 9bc8b00

File tree

1 file changed

+39
-32
lines changed

1 file changed

+39
-32
lines changed

compiler/rustc_metadata/src/rmeta/encoder.rs

+39-32
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ pub(super) struct EncodeContext<'a, 'tcx> {
6666
required_source_files: Option<GrowableBitSet<usize>>,
6767
is_proc_macro: bool,
6868
hygiene_ctxt: &'a HygieneEncodeContext,
69+
70+
// Determines if MIR used for code generation will be included in the crate
71+
// metadata. When emitting only metadata (e.g., cargo check), we can avoid
72+
// generating optimized MIR altogether.
73+
emit_codegen_mir: bool,
6974
}
7075

7176
/// If the current crate is a proc-macro, returns early with `Lazy:empty()`.
@@ -787,9 +792,11 @@ impl EncodeContext<'a, 'tcx> {
787792
self.encode_generics(def_id);
788793
self.encode_explicit_predicates(def_id);
789794
self.encode_inferred_outlives(def_id);
795+
let opt_mir = tcx.sess.opts.debugging_opts.always_encode_mir || self.emit_codegen_mir;
796+
if opt_mir {
797+
self.encode_optimized_mir(def_id.expect_local());
798+
}
790799
self.encode_mir_for_ctfe(def_id.expect_local());
791-
self.encode_optimized_mir(def_id.expect_local());
792-
self.encode_promoted_mir(def_id.expect_local());
793800
}
794801

795802
fn encode_info_for_mod(&mut self, id: hir::HirId, md: &hir::Mod<'_>, attrs: &[ast::Attribute]) {
@@ -895,9 +902,11 @@ impl EncodeContext<'a, 'tcx> {
895902
self.encode_generics(def_id);
896903
self.encode_explicit_predicates(def_id);
897904
self.encode_inferred_outlives(def_id);
898-
self.encode_optimized_mir(def_id.expect_local());
905+
let opt_mir = tcx.sess.opts.debugging_opts.always_encode_mir || self.emit_codegen_mir;
906+
if opt_mir {
907+
self.encode_optimized_mir(def_id.expect_local());
908+
}
899909
self.encode_mir_for_ctfe(def_id.expect_local());
900-
self.encode_promoted_mir(def_id.expect_local());
901910
}
902911

903912
fn encode_generics(&mut self, def_id: DefId) {
@@ -1024,17 +1033,23 @@ impl EncodeContext<'a, 'tcx> {
10241033
}
10251034
}
10261035
ty::AssocKind::Fn => {
1027-
if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id.expect_local()) {
1028-
self.encode_optimized_mir(def_id.expect_local());
1029-
self.encode_promoted_mir(def_id.expect_local());
1036+
let opt_mir =
1037+
tcx.sess.opts.debugging_opts.always_encode_mir || self.emit_codegen_mir;
1038+
if opt_mir {
1039+
if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id.expect_local()) {
1040+
self.encode_optimized_mir(def_id.expect_local());
1041+
self.encode_promoted_mir(def_id.expect_local());
1042+
}
10301043
}
10311044
}
10321045
}
10331046
}
10341047

1035-
fn metadata_output_only(&self) -> bool {
1036-
// MIR optimisation can be skipped when we're just interested in the metadata.
1037-
!self.tcx.sess.opts.output_types.should_codegen()
1048+
fn should_encode_fn_opt_mir(&self, def_id: DefId) -> bool {
1049+
self.tcx.sess.opts.debugging_opts.always_encode_mir
1050+
|| (self.emit_codegen_mir
1051+
&& (self.tcx.generics_of(def_id).requires_monomorphization(self.tcx)
1052+
|| self.tcx.codegen_fn_attrs(def_id).requests_inline()))
10381053
}
10391054

10401055
fn encode_info_for_impl_item(&mut self, def_id: DefId) {
@@ -1105,13 +1120,9 @@ impl EncodeContext<'a, 'tcx> {
11051120
let (mir, mir_const) = match ast_item.kind {
11061121
hir::ImplItemKind::Const(..) => (false, true),
11071122
hir::ImplItemKind::Fn(ref sig, _) => {
1108-
let generics = self.tcx.generics_of(def_id);
1109-
let needs_inline = (generics.requires_monomorphization(self.tcx)
1110-
|| tcx.codegen_fn_attrs(def_id).requests_inline())
1111-
&& !self.metadata_output_only();
1123+
let opt_mir = self.should_encode_fn_opt_mir(def_id);
11121124
let is_const_fn = sig.header.constness == hir::Constness::Const;
1113-
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
1114-
(needs_inline || always_encode_mir, is_const_fn)
1125+
(opt_mir, is_const_fn)
11151126
}
11161127
hir::ImplItemKind::TyAlias(..) => (false, false),
11171128
};
@@ -1433,16 +1444,10 @@ impl EncodeContext<'a, 'tcx> {
14331444
let (mir, const_mir) = match item.kind {
14341445
hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => (false, true),
14351446
hir::ItemKind::Fn(ref sig, ..) => {
1436-
let generics = tcx.generics_of(def_id);
1437-
let needs_inline = (generics.requires_monomorphization(tcx)
1438-
|| tcx.codegen_fn_attrs(def_id).requests_inline())
1439-
&& !self.metadata_output_only();
1440-
1447+
let opt_mir = self.should_encode_fn_opt_mir(def_id);
14411448
let is_const_fn = sig.header.constness == hir::Constness::Const;
1442-
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
1443-
let mir = needs_inline || always_encode_mir;
14441449
// We don't need the optimized MIR for const fns.
1445-
(mir, is_const_fn)
1450+
(opt_mir, is_const_fn)
14461451
}
14471452
_ => (false, false),
14481453
};
@@ -1502,8 +1507,11 @@ impl EncodeContext<'a, 'tcx> {
15021507
record!(self.tables.fn_sig[def_id] <- substs.as_closure().sig());
15031508
}
15041509
self.encode_generics(def_id.to_def_id());
1505-
self.encode_optimized_mir(def_id);
1506-
self.encode_promoted_mir(def_id);
1510+
let opt_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir || self.emit_codegen_mir;
1511+
if opt_mir {
1512+
self.encode_optimized_mir(def_id);
1513+
self.encode_promoted_mir(def_id);
1514+
}
15071515
}
15081516

15091517
fn encode_info_for_anon_const(&mut self, def_id: LocalDefId) {
@@ -2008,10 +2016,9 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> {
20082016
}
20092017
hir::ItemKind::Fn(ref sig, ..) => {
20102018
let def_id = tcx.hir().local_def_id(item.hir_id);
2011-
let generics = tcx.generics_of(def_id.to_def_id());
2012-
let needs_inline = generics.requires_monomorphization(tcx)
2019+
let opt_mir = tcx.generics_of(def_id.to_def_id()).requires_monomorphization(tcx)
20132020
|| tcx.codegen_fn_attrs(def_id.to_def_id()).requests_inline();
2014-
if needs_inline {
2021+
if opt_mir {
20152022
self.prefetch_mir(def_id)
20162023
}
20172024
if sig.header.constness == hir::Constness::Const {
@@ -2045,11 +2052,10 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> {
20452052
}
20462053
hir::ImplItemKind::Fn(ref sig, _) => {
20472054
let def_id = tcx.hir().local_def_id(impl_item.hir_id);
2048-
let generics = tcx.generics_of(def_id.to_def_id());
2049-
let needs_inline = generics.requires_monomorphization(tcx)
2055+
let opt_mir = tcx.generics_of(def_id.to_def_id()).requires_monomorphization(tcx)
20502056
|| tcx.codegen_fn_attrs(def_id.to_def_id()).requests_inline();
20512057
let is_const_fn = sig.header.constness == hir::Constness::Const;
2052-
if needs_inline {
2058+
if opt_mir {
20532059
self.prefetch_mir(def_id)
20542060
}
20552061
if is_const_fn {
@@ -2148,6 +2154,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
21482154
required_source_files,
21492155
is_proc_macro: tcx.sess.crate_types().contains(&CrateType::ProcMacro),
21502156
hygiene_ctxt: &hygiene_ctxt,
2157+
emit_codegen_mir: tcx.sess.opts.output_types.should_codegen(),
21512158
};
21522159

21532160
// Encode the rustc version string in a predictable location.

0 commit comments

Comments
 (0)