Skip to content

Commit

Permalink
Auto merge of rust-lang#80718 - tmiasko:skip-opt-mir, r=oli-obk
Browse files Browse the repository at this point in the history
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 rust-lang#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.
  • Loading branch information
bors committed Jan 13, 2021
2 parents fd2df74 + 1685731 commit 9bc8b00
Showing 1 changed file with 39 additions and 32 deletions.
71 changes: 39 additions & 32 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ pub(super) struct EncodeContext<'a, 'tcx> {
required_source_files: Option<GrowableBitSet<usize>>,
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()`.
Expand Down Expand Up @@ -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]) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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),
};
Expand Down Expand Up @@ -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),
};
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 9bc8b00

Please sign in to comment.