diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index 3903e6ea3b1da..33b88d70d6f8d 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -33,14 +33,15 @@ fn create_jit_module( (jit_module, cx) } -pub(crate) fn run_jit(tcx: TyCtxt<'_>, crate_info: &CrateInfo, jit_args: Vec) -> ! { +pub(crate) fn run_jit(tcx: TyCtxt<'_>, target_cpu: String, jit_args: Vec) -> ! { if !tcx.crate_types().contains(&rustc_session::config::CrateType::Executable) { tcx.dcx().fatal("can't jit non-executable crate"); } let output_filenames = tcx.output_filenames(()); + let crate_info = CrateInfo::new(tcx, target_cpu); let should_write_ir = crate::pretty_clif::should_write_ir(tcx.sess); - let (mut jit_module, mut debug_context) = create_jit_module(tcx, crate_info); + let (mut jit_module, mut debug_context) = create_jit_module(tcx, &crate_info); let mut cached_context = Context::new(); let cgus = tcx.collect_and_partition_mono_items(()).codegen_units; diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index cbbb0ccbbc215..361f143d99913 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -209,12 +209,12 @@ impl CodegenBackend for CraneliftCodegenBackend { .to_owned() } - fn codegen_crate(&self, tcx: TyCtxt<'_>, _crate_info: &CrateInfo) -> Box { + fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { info!("codegen crate {}", tcx.crate_name(LOCAL_CRATE)); let config = self.config.get().unwrap(); if config.jit_mode { #[cfg(feature = "jit")] - driver::jit::run_jit(tcx, _crate_info, config.jit_args.clone()); + driver::jit::run_jit(tcx, self.target_cpu(tcx.sess), config.jit_args.clone()); #[cfg(not(feature = "jit"))] tcx.dcx().fatal("jit support was disabled when compiling rustc_codegen_cranelift"); @@ -228,6 +228,7 @@ impl CodegenBackend for CraneliftCodegenBackend { ongoing_codegen: Box, sess: &Session, outputs: &OutputFilenames, + _crate_info: &CrateInfo, ) -> (CompiledModules, FxIndexMap) { ongoing_codegen.downcast::().unwrap().join(sess, outputs) } diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 4be25b3fb0934..6ca2ef88ef291 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -291,8 +291,8 @@ impl CodegenBackend for GccCodegenBackend { target_cpu(sess).to_owned() } - fn codegen_crate(&self, tcx: TyCtxt<'_>, crate_info: &CrateInfo) -> Box { - Box::new(codegen_crate(self.clone(), tcx, crate_info)) + fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { + Box::new(codegen_crate(self.clone(), tcx)) } fn join_codegen( @@ -300,11 +300,12 @@ impl CodegenBackend for GccCodegenBackend { ongoing_codegen: Box, sess: &Session, _outputs: &OutputFilenames, + crate_info: &CrateInfo, ) -> (CompiledModules, FxIndexMap) { ongoing_codegen .downcast::>() .expect("Expected GccCodegenBackend's OngoingCodegen, found Box") - .join(sess) + .join(sess, crate_info) } fn target_config(&self, sess: &Session) -> TargetConfig { diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 575e37d0b171d..b273047b98fc6 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -333,8 +333,8 @@ impl CodegenBackend for LlvmCodegenBackend { crate::llvm_util::target_cpu(sess).to_string() } - fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>, crate_info: &CrateInfo) -> Box { - Box::new(rustc_codegen_ssa::base::codegen_crate(LlvmCodegenBackend(()), tcx, crate_info)) + fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box { + Box::new(rustc_codegen_ssa::base::codegen_crate(LlvmCodegenBackend(()), tcx)) } fn join_codegen( @@ -342,11 +342,12 @@ impl CodegenBackend for LlvmCodegenBackend { ongoing_codegen: Box, sess: &Session, outputs: &OutputFilenames, + crate_info: &CrateInfo, ) -> (CompiledModules, FxIndexMap) { let (compiled_modules, work_products) = ongoing_codegen .downcast::>() .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") - .join(sess); + .join(sess, crate_info); if sess.opts.unstable_opts.llvm_time_trace { sess.time("llvm_dump_timing_file", || { diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index ddfcd8a85f6b8..ed36fae3cdc4d 100644 --- a/compiler/rustc_codegen_ssa/src/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs @@ -85,7 +85,7 @@ fn crate_type_allows_lto(crate_type: CrateType) -> bool { } } -pub(super) fn exported_symbols_for_lto( +pub(crate) fn exported_symbols_for_lto( tcx: TyCtxt<'_>, each_linked_rlib_for_lto: &[CrateNum], ) -> Vec { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index c48e8a58b6964..01c60d843d051 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -34,7 +34,7 @@ use rustc_span::{FileName, InnerSpan, Span, SpanData}; use rustc_target::spec::{MergeFunctions, SanitizerSet}; use tracing::debug; -use crate::back::link::{self, ensure_removed}; +use crate::back::link::ensure_removed; use crate::back::lto::{self, SerializedModule, check_lto_allowed}; use crate::errors::ErrorCreatingRemarkDir; use crate::traits::*; @@ -389,18 +389,8 @@ fn generate_thin_lto_work( enum MaybeLtoModules { NoLto(CompiledModules), - FatLto { - cgcx: CodegenContext, - exported_symbols_for_lto: Arc>, - each_linked_rlib_file_for_lto: Vec, - needs_fat_lto: Vec>, - }, - ThinLto { - cgcx: CodegenContext, - exported_symbols_for_lto: Arc>, - each_linked_rlib_file_for_lto: Vec, - needs_thin_lto: Vec>, - }, + FatLto { cgcx: CodegenContext, needs_fat_lto: Vec> }, + ThinLto { cgcx: CodegenContext, needs_thin_lto: Vec> }, } fn need_bitcode_in_object(tcx: TyCtxt<'_>) -> bool { @@ -424,7 +414,6 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool { pub(crate) fn start_async_codegen( backend: B, tcx: TyCtxt<'_>, - crate_info: &CrateInfo, allocator_module: Option>, ) -> OngoingCodegen { let (coordinator_send, coordinator_receive) = channel(); @@ -440,7 +429,6 @@ pub(crate) fn start_async_codegen( let coordinator_thread = start_executing_work( backend.clone(), tcx, - crate_info, shared_emitter, codegen_worker_send, coordinator_receive, @@ -992,8 +980,8 @@ fn do_thin_lto( prof: &SelfProfilerRef, shared_emitter: SharedEmitter, tm_factory: TargetMachineFactoryFn, - exported_symbols_for_lto: Arc>, - each_linked_rlib_for_lto: Vec, + exported_symbols_for_lto: &[String], + each_linked_rlib_for_lto: &[PathBuf], needs_thin_lto: Vec>, ) -> Vec { let _timer = prof.verbose_generic_activity("LLVM_thinlto"); @@ -1231,7 +1219,6 @@ enum MainThreadState { fn start_executing_work( backend: B, tcx: TyCtxt<'_>, - crate_info: &CrateInfo, shared_emitter: SharedEmitter, codegen_worker_send: Sender, coordinator_receive: Receiver>, @@ -1243,22 +1230,9 @@ fn start_executing_work( let sess = tcx.sess; let prof = sess.prof.clone(); - let mut each_linked_rlib_for_lto = Vec::new(); - let mut each_linked_rlib_file_for_lto = Vec::new(); - if sess.lto() != Lto::No && sess.lto() != Lto::ThinLocal { - drop(link::each_linked_rlib(crate_info, None, &mut |cnum, path| { - if link::ignored_for_lto(sess, crate_info, cnum) { - return; - } - - each_linked_rlib_for_lto.push(cnum); - each_linked_rlib_file_for_lto.push(path.to_path_buf()); - })); - } - - // Compute the set of symbols we need to retain when doing LTO (if we need to) + // Compute the set of symbols we need to retain when doing thin local LTO (if we need to) let exported_symbols_for_lto = - Arc::new(lto::exported_symbols_for_lto(tcx, &each_linked_rlib_for_lto)); + if sess.lto() == Lto::ThinLocal { lto::exported_symbols_for_lto(tcx, &[]) } else { vec![] }; // First up, convert our jobserver into a helper thread so we can use normal // mpsc channels to manage our messages and such. @@ -1757,12 +1731,7 @@ fn start_executing_work( needs_fat_lto.push(FatLtoInput::Serialized { name: wp.cgu_name, bitcode_path }) } - return Ok(MaybeLtoModules::FatLto { - cgcx, - exported_symbols_for_lto, - each_linked_rlib_file_for_lto, - needs_fat_lto, - }); + return Ok(MaybeLtoModules::FatLto { cgcx, needs_fat_lto }); } else if !needs_thin_lto.is_empty() || !lto_import_only_modules.is_empty() { assert!(compiled_modules.is_empty()); assert!(needs_fat_lto.is_empty()); @@ -1777,8 +1746,8 @@ fn start_executing_work( &prof, shared_emitter.clone(), tm_factory, - exported_symbols_for_lto, - each_linked_rlib_file_for_lto, + &exported_symbols_for_lto, + &[], needs_thin_lto, )); } else { @@ -1790,12 +1759,7 @@ fn start_executing_work( }); } - return Ok(MaybeLtoModules::ThinLto { - cgcx, - exported_symbols_for_lto, - each_linked_rlib_file_for_lto, - needs_thin_lto, - }); + return Ok(MaybeLtoModules::ThinLto { cgcx, needs_thin_lto }); } } @@ -2139,7 +2103,11 @@ pub struct OngoingCodegen { } impl OngoingCodegen { - pub fn join(self, sess: &Session) -> (CompiledModules, FxIndexMap) { + pub fn join( + self, + sess: &Session, + crate_info: &CrateInfo, + ) -> (CompiledModules, FxIndexMap) { self.shared_emitter_main.check(sess, true); let maybe_lto_modules = sess.time("join_worker_thread", || match self.coordinator.join() { @@ -2163,12 +2131,7 @@ impl OngoingCodegen { drop(shared_emitter); compiled_modules } - MaybeLtoModules::FatLto { - cgcx, - exported_symbols_for_lto, - each_linked_rlib_file_for_lto, - needs_fat_lto, - } => { + MaybeLtoModules::FatLto { cgcx, needs_fat_lto } => { let tm_factory = self.backend.target_machine_factory( sess, cgcx.opt_level, @@ -2181,19 +2144,14 @@ impl OngoingCodegen { &cgcx, shared_emitter, tm_factory, - &exported_symbols_for_lto, - &each_linked_rlib_file_for_lto, + &crate_info.exported_symbols_for_lto, + &crate_info.each_linked_rlib_file_for_lto, needs_fat_lto, )], allocator_module: None, } } - MaybeLtoModules::ThinLto { - cgcx, - exported_symbols_for_lto, - each_linked_rlib_file_for_lto, - needs_thin_lto, - } => { + MaybeLtoModules::ThinLto { cgcx, needs_thin_lto } => { let tm_factory = self.backend.target_machine_factory( sess, cgcx.opt_level, @@ -2206,8 +2164,8 @@ impl OngoingCodegen { &sess.prof, shared_emitter, tm_factory, - exported_symbols_for_lto, - each_linked_rlib_file_for_lto, + &crate_info.exported_symbols_for_lto, + &crate_info.each_linked_rlib_file_for_lto, needs_thin_lto, ), allocator_module: None, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 4e2884c8cb63f..947475f8a0b22 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -686,11 +686,7 @@ pub fn allocator_shim_contents(tcx: TyCtxt<'_>, kind: AllocatorKind) -> Vec( - backend: B, - tcx: TyCtxt<'_>, - crate_info: &CrateInfo, -) -> OngoingCodegen { +pub fn codegen_crate(backend: B, tcx: TyCtxt<'_>) -> OngoingCodegen { if tcx.sess.target.need_explicit_cpu && tcx.sess.opts.cg.target_cpu.is_none() { // The target has no default cpu, but none is set explicitly tcx.dcx().emit_fatal(errors::CpuRequired); @@ -734,7 +730,7 @@ pub fn codegen_crate( None }; - let ongoing_codegen = start_async_codegen(backend.clone(), tcx, crate_info, allocator_module); + let ongoing_codegen = start_async_codegen(backend.clone(), tcx, allocator_module); // For better throughput during parallel processing by LLVM, we used to sort // CGUs largest to smallest. This would lead to better thread utilization @@ -959,6 +955,8 @@ impl CrateInfo { natvis_debugger_visualizers: Default::default(), lint_levels: CodegenLintLevels::from_tcx(tcx), metadata_symbol: exported_symbols::metadata_symbol_name(tcx), + each_linked_rlib_file_for_lto: Default::default(), + exported_symbols_for_lto: Default::default(), }; info.native_libraries.reserve(n_crates); @@ -1044,6 +1042,25 @@ impl CrateInfo { }); } + let mut each_linked_rlib_for_lto = Vec::new(); + let mut each_linked_rlib_file_for_lto = Vec::new(); + if tcx.sess.lto() != config::Lto::No && tcx.sess.lto() != config::Lto::ThinLocal { + drop(crate::back::link::each_linked_rlib(&info, None, &mut |cnum, path| { + if crate::back::link::ignored_for_lto(tcx.sess, &info, cnum) { + return; + } + + each_linked_rlib_for_lto.push(cnum); + each_linked_rlib_file_for_lto.push(path.to_path_buf()); + })); + } + info.each_linked_rlib_file_for_lto = each_linked_rlib_file_for_lto; + + // FIXME move to -Zlink-only half such that each_linked_rlib_file_for_lto can be moved there too + // Compute the set of symbols we need to retain when doing LTO (if we need to) + info.exported_symbols_for_lto = + crate::back::lto::exported_symbols_for_lto(tcx, &each_linked_rlib_for_lto); + let embed_visualizers = tcx.crate_types().iter().any(|&crate_type| match crate_type { CrateType::Executable | CrateType::Dylib | CrateType::Cdylib | CrateType::Sdylib => { // These are crate types for which we invoke the linker and can embed diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 1c266382d0279..a112c26684fff 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -230,6 +230,8 @@ pub struct CrateInfo { pub natvis_debugger_visualizers: BTreeSet, pub lint_levels: CodegenLintLevels, pub metadata_symbol: String, + pub each_linked_rlib_file_for_lto: Vec, + pub exported_symbols_for_lto: Vec, } /// Target-specific options that get set in `cfg(...)`. diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 7b95562ddda37..9898b67b91f78 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -104,7 +104,7 @@ pub trait CodegenBackend { fn target_cpu(&self, sess: &Session) -> String; - fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>, crate_info: &CrateInfo) -> Box; + fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box; /// This is called on the returned `Box` from [`codegen_crate`](Self::codegen_crate) /// @@ -116,6 +116,7 @@ pub trait CodegenBackend { ongoing_codegen: Box, sess: &Session, outputs: &OutputFilenames, + crate_info: &CrateInfo, ) -> (CompiledModules, FxIndexMap); fn print_pass_timings(&self) {} diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index cb41974af41b0..bcd1a52ce9dcd 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1305,8 +1305,6 @@ pub(crate) fn start_codegen<'tcx>( let metadata = rustc_metadata::fs::encode_and_write_metadata(tcx); - let crate_info = CrateInfo::new(tcx, codegen_backend.target_cpu(tcx.sess)); - let codegen = tcx.sess.time("codegen_crate", || { if tcx.sess.opts.unstable_opts.no_codegen || !tcx.sess.opts.output_types.should_codegen() { // Skip crate items and just output metadata in -Z no-codegen mode. @@ -1315,7 +1313,7 @@ pub(crate) fn start_codegen<'tcx>( // Linker::link will skip join_codegen in case of a CodegenResults Any value. Box::new(CompiledModules { modules: vec![], allocator_module: None }) } else { - codegen_backend.codegen_crate(tcx, &crate_info) + codegen_backend.codegen_crate(tcx) } }); @@ -1327,6 +1325,8 @@ pub(crate) fn start_codegen<'tcx>( tcx.sess.code_stats.print_type_sizes(); } + let crate_info = CrateInfo::new(tcx, codegen_backend.target_cpu(tcx.sess)); + (codegen, crate_info, metadata) } diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 63c7332893b81..fd1b5104fc6d3 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -53,9 +53,12 @@ impl Linker { // This was a check only build Ok(compiled_modules) => (*compiled_modules, IndexMap::default()), - Err(ongoing_codegen) => { - codegen_backend.join_codegen(ongoing_codegen, sess, &self.output_filenames) - } + Err(ongoing_codegen) => codegen_backend.join_codegen( + ongoing_codegen, + sess, + &self.output_filenames, + &self.crate_info, + ), } }); diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 24b23cc4199e9..3ff427a425b79 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -406,7 +406,7 @@ impl CodegenBackend for DummyCodegenBackend { String::new() } - fn codegen_crate<'tcx>(&self, _tcx: TyCtxt<'tcx>, _crate_info: &CrateInfo) -> Box { + fn codegen_crate<'tcx>(&self, _tcx: TyCtxt<'tcx>) -> Box { Box::new(CompiledModules { modules: vec![], allocator_module: None }) } @@ -415,6 +415,7 @@ impl CodegenBackend for DummyCodegenBackend { ongoing_codegen: Box, _sess: &Session, _outputs: &OutputFilenames, + _crate_info: &CrateInfo, ) -> (CompiledModules, FxIndexMap) { (*ongoing_codegen.downcast().unwrap(), FxIndexMap::default()) } diff --git a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs index 5dd11b0a016e3..8a7cacf20e2e4 100644 --- a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs +++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs @@ -37,7 +37,7 @@ impl CodegenBackend for TheBackend { "fake_target_cpu".to_owned() } - fn codegen_crate(&self, _tcx: TyCtxt<'_>, _crate_info: &CrateInfo) -> Box { + fn codegen_crate(&self, _tcx: TyCtxt<'_>) -> Box { Box::new(CompiledModules { modules: vec![], allocator_module: None }) } @@ -46,6 +46,7 @@ impl CodegenBackend for TheBackend { ongoing_codegen: Box, _sess: &Session, _outputs: &OutputFilenames, + _crate_info: &CrateInfo, ) -> (CompiledModules, FxIndexMap) { let codegen_results = ongoing_codegen .downcast::() diff --git a/tests/ui/rmeta/no_optimized_mir.rs b/tests/ui/rmeta/no_optimized_mir.rs index dbf612cd03cc7..c8ed00b039b23 100644 --- a/tests/ui/rmeta/no_optimized_mir.rs +++ b/tests/ui/rmeta/no_optimized_mir.rs @@ -10,5 +10,4 @@ fn main() { rmeta_meta::missing_optimized_mir(); } -//~? ERROR crate `rmeta_meta` required to be available in rlib format, but was not found in this form //~? ERROR missing optimized MIR for `missing_optimized_mir` in the crate `rmeta_meta` diff --git a/tests/ui/rmeta/no_optimized_mir.stderr b/tests/ui/rmeta/no_optimized_mir.stderr index 91aa98172fe56..254f100aa7b5e 100644 --- a/tests/ui/rmeta/no_optimized_mir.stderr +++ b/tests/ui/rmeta/no_optimized_mir.stderr @@ -1,5 +1,3 @@ -error: crate `rmeta_meta` required to be available in rlib format, but was not found in this form - error: missing optimized MIR for `missing_optimized_mir` in the crate `rmeta_meta` | note: missing optimized MIR for this item (was the crate `rmeta_meta` compiled with `--emit=metadata`?) @@ -8,5 +6,5 @@ note: missing optimized MIR for this item (was the crate `rmeta_meta` compiled w LL | pub fn missing_optimized_mir() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error