diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index ccaee8608b618..6bf3336bd2f9f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -66,6 +66,11 @@ pub(super) struct EncodeContext<'a, 'tcx> { required_source_files: Option>, is_proc_macro: bool, hygiene_ctxt: &'a HygieneEncodeContext, + + // Determines if MIR used for code generation will be included in the crate + // metadata. When emitting only metadata (e.g., cargo check), we can avoid + // generating optimized MIR altogether. + emit_codegen_mir: bool, } /// If the current crate is a proc-macro, returns early with `Lazy:empty()`. @@ -787,9 +792,11 @@ impl EncodeContext<'a, 'tcx> { self.encode_generics(def_id); self.encode_explicit_predicates(def_id); self.encode_inferred_outlives(def_id); + let opt_mir = tcx.sess.opts.debugging_opts.always_encode_mir || self.emit_codegen_mir; + if opt_mir { + self.encode_optimized_mir(def_id.expect_local()); + } self.encode_mir_for_ctfe(def_id.expect_local()); - self.encode_optimized_mir(def_id.expect_local()); - self.encode_promoted_mir(def_id.expect_local()); } fn encode_info_for_mod(&mut self, id: hir::HirId, md: &hir::Mod<'_>, attrs: &[ast::Attribute]) { @@ -895,9 +902,11 @@ impl EncodeContext<'a, 'tcx> { self.encode_generics(def_id); self.encode_explicit_predicates(def_id); self.encode_inferred_outlives(def_id); - self.encode_optimized_mir(def_id.expect_local()); + let opt_mir = tcx.sess.opts.debugging_opts.always_encode_mir || self.emit_codegen_mir; + if opt_mir { + self.encode_optimized_mir(def_id.expect_local()); + } self.encode_mir_for_ctfe(def_id.expect_local()); - self.encode_promoted_mir(def_id.expect_local()); } fn encode_generics(&mut self, def_id: DefId) { @@ -1024,17 +1033,23 @@ impl EncodeContext<'a, 'tcx> { } } ty::AssocKind::Fn => { - if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id.expect_local()) { - self.encode_optimized_mir(def_id.expect_local()); - self.encode_promoted_mir(def_id.expect_local()); + let opt_mir = + tcx.sess.opts.debugging_opts.always_encode_mir || self.emit_codegen_mir; + if opt_mir { + if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id.expect_local()) { + self.encode_optimized_mir(def_id.expect_local()); + self.encode_promoted_mir(def_id.expect_local()); + } } } } } - fn metadata_output_only(&self) -> bool { - // MIR optimisation can be skipped when we're just interested in the metadata. - !self.tcx.sess.opts.output_types.should_codegen() + fn should_encode_fn_opt_mir(&self, def_id: DefId) -> bool { + self.tcx.sess.opts.debugging_opts.always_encode_mir + || (self.emit_codegen_mir + && (self.tcx.generics_of(def_id).requires_monomorphization(self.tcx) + || self.tcx.codegen_fn_attrs(def_id).requests_inline())) } fn encode_info_for_impl_item(&mut self, def_id: DefId) { @@ -1105,13 +1120,9 @@ impl EncodeContext<'a, 'tcx> { let (mir, mir_const) = match ast_item.kind { hir::ImplItemKind::Const(..) => (false, true), hir::ImplItemKind::Fn(ref sig, _) => { - let generics = self.tcx.generics_of(def_id); - let needs_inline = (generics.requires_monomorphization(self.tcx) - || tcx.codegen_fn_attrs(def_id).requests_inline()) - && !self.metadata_output_only(); + let opt_mir = self.should_encode_fn_opt_mir(def_id); let is_const_fn = sig.header.constness == hir::Constness::Const; - let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir; - (needs_inline || always_encode_mir, is_const_fn) + (opt_mir, is_const_fn) } hir::ImplItemKind::TyAlias(..) => (false, false), }; @@ -1433,16 +1444,10 @@ impl EncodeContext<'a, 'tcx> { let (mir, const_mir) = match item.kind { hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => (false, true), hir::ItemKind::Fn(ref sig, ..) => { - let generics = tcx.generics_of(def_id); - let needs_inline = (generics.requires_monomorphization(tcx) - || tcx.codegen_fn_attrs(def_id).requests_inline()) - && !self.metadata_output_only(); - + let opt_mir = self.should_encode_fn_opt_mir(def_id); let is_const_fn = sig.header.constness == hir::Constness::Const; - let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir; - let mir = needs_inline || always_encode_mir; // We don't need the optimized MIR for const fns. - (mir, is_const_fn) + (opt_mir, is_const_fn) } _ => (false, false), }; @@ -1502,8 +1507,11 @@ impl EncodeContext<'a, 'tcx> { record!(self.tables.fn_sig[def_id] <- substs.as_closure().sig()); } self.encode_generics(def_id.to_def_id()); - self.encode_optimized_mir(def_id); - self.encode_promoted_mir(def_id); + let opt_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir || self.emit_codegen_mir; + if opt_mir { + self.encode_optimized_mir(def_id); + self.encode_promoted_mir(def_id); + } } fn encode_info_for_anon_const(&mut self, def_id: LocalDefId) { @@ -2008,10 +2016,9 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> { } hir::ItemKind::Fn(ref sig, ..) => { let def_id = tcx.hir().local_def_id(item.hir_id); - let generics = tcx.generics_of(def_id.to_def_id()); - let needs_inline = generics.requires_monomorphization(tcx) + let opt_mir = tcx.generics_of(def_id.to_def_id()).requires_monomorphization(tcx) || tcx.codegen_fn_attrs(def_id.to_def_id()).requests_inline(); - if needs_inline { + if opt_mir { self.prefetch_mir(def_id) } if sig.header.constness == hir::Constness::Const { @@ -2045,11 +2052,10 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> { } hir::ImplItemKind::Fn(ref sig, _) => { let def_id = tcx.hir().local_def_id(impl_item.hir_id); - let generics = tcx.generics_of(def_id.to_def_id()); - let needs_inline = generics.requires_monomorphization(tcx) + let opt_mir = tcx.generics_of(def_id.to_def_id()).requires_monomorphization(tcx) || tcx.codegen_fn_attrs(def_id.to_def_id()).requests_inline(); let is_const_fn = sig.header.constness == hir::Constness::Const; - if needs_inline { + if opt_mir { self.prefetch_mir(def_id) } if is_const_fn { @@ -2148,6 +2154,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata { required_source_files, is_proc_macro: tcx.sess.crate_types().contains(&CrateType::ProcMacro), hygiene_ctxt: &hygiene_ctxt, + emit_codegen_mir: tcx.sess.opts.output_types.should_codegen(), }; // Encode the rustc version string in a predictable location.