Rollup merge of #153184 - bjorn3:split_crate_info_out_of_codegen_results, r=nnethercote

Replace CodegenResults with CompiledModules

This is already CodegenResults without CrateInfo. The driver can calculate the CrateInfo and pass it by-ref to the backend. Using CompiledModules makes it a bit easier to move some other things out of the backend as will be necessary for moving LTO to the link phase.

Helps with https://github.com/rust-lang/compiler-team/issues/908
This commit is contained in:
Jonathan Brouwer
2026-03-03 13:08:44 +01:00
committed by GitHub
17 changed files with 291 additions and 302 deletions
@@ -10,9 +10,9 @@
use cranelift_object::{ObjectBuilder, ObjectModule};
use rustc_codegen_ssa::assert_module_sources::CguReuse;
use rustc_codegen_ssa::back::write::{CompiledModules, produce_final_output_artifacts};
use rustc_codegen_ssa::back::write::produce_final_output_artifacts;
use rustc_codegen_ssa::base::determine_cgu_reuse;
use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
use rustc_codegen_ssa::{CompiledModule, CompiledModules, ModuleKind};
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{IntoDynSyncSend, par_map};
@@ -54,7 +54,6 @@ fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) {
pub(crate) struct OngoingCodegen {
modules: Vec<OngoingModuleCodegen>,
allocator_module: Option<CompiledModule>,
crate_info: CrateInfo,
concurrency_limiter: ConcurrencyLimiter,
}
@@ -63,7 +62,7 @@ pub(crate) fn join(
self,
sess: &Session,
outputs: &OutputFilenames,
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
) -> (CompiledModules, FxIndexMap<WorkProductId, WorkProduct>) {
let mut work_products = FxIndexMap::default();
let mut modules = vec![];
let disable_incr_cache = disable_incr_cache();
@@ -126,15 +125,7 @@ pub(crate) fn join(
produce_final_output_artifacts(sess, &compiled_modules, outputs);
(
CodegenResults {
crate_info: self.crate_info,
modules: compiled_modules.modules,
allocator_module: compiled_modules.allocator_module,
},
work_products,
)
(compiled_modules, work_products)
}
}
@@ -483,13 +474,6 @@ fn emit_allocator_module(tcx: TyCtxt<'_>) -> Option<CompiledModule> {
}
pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box<OngoingCodegen> {
// FIXME handle `-Ctarget-cpu=native`
let target_cpu = match tcx.sess.opts.cg.target_cpu {
Some(ref name) => name,
None => tcx.sess.target.cpu.as_ref(),
}
.to_owned();
let cgus = tcx.collect_and_partition_mono_items(()).codegen_units;
if tcx.dep_graph.is_fully_enabled() {
@@ -549,7 +533,6 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box<OngoingCodegen> {
Box::new(OngoingCodegen {
modules,
allocator_module,
crate_info: CrateInfo::new(tcx, target_cpu),
concurrency_limiter: concurrency_limiter.0,
})
}
@@ -16,13 +16,14 @@
use crate::prelude::*;
use crate::unwind_module::UnwindModule;
fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule<JITModule>, Option<DebugContext>) {
let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string());
fn create_jit_module(
tcx: TyCtxt<'_>,
crate_info: &CrateInfo,
) -> (UnwindModule<JITModule>, Option<DebugContext>) {
let isa = crate::build_isa(tcx.sess, true);
let mut jit_builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
crate::compiler_builtins::register_functions_for_jit(&mut jit_builder);
jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info));
jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info.clone()));
let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false);
let cx = DebugContext::new(tcx, jit_module.isa(), false, "dummy_cgu_name");
@@ -32,14 +33,14 @@ fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule<JITModule>, Option<DebugC
(jit_module, cx)
}
pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec<String>) -> ! {
pub(crate) fn run_jit(tcx: TyCtxt<'_>, crate_info: &CrateInfo, jit_args: Vec<String>) -> ! {
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 should_write_ir = crate::pretty_clif::should_write_ir(tcx.sess);
let (mut jit_module, mut debug_context) = create_jit_module(tcx);
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;
+13 -4
View File
@@ -40,7 +40,7 @@
use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::settings::{self, Configurable};
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::{CodegenResults, TargetConfig};
use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig};
use rustc_log::tracing::info;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_session::Session;
@@ -200,12 +200,21 @@ fn print_version(&self) {
println!("Cranelift version: {}", cranelift_codegen::VERSION);
}
fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box<dyn Any> {
fn target_cpu(&self, sess: &Session) -> String {
// FIXME handle `-Ctarget-cpu=native`
match sess.opts.cg.target_cpu {
Some(ref name) => name,
None => sess.target.cpu.as_ref(),
}
.to_owned()
}
fn codegen_crate(&self, tcx: TyCtxt<'_>, _crate_info: &CrateInfo) -> Box<dyn Any> {
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, config.jit_args.clone());
driver::jit::run_jit(tcx, _crate_info, config.jit_args.clone());
#[cfg(not(feature = "jit"))]
tcx.dcx().fatal("jit support was disabled when compiling rustc_codegen_cranelift");
@@ -219,7 +228,7 @@ fn join_codegen(
ongoing_codegen: Box<dyn Any>,
sess: &Session,
outputs: &OutputFilenames,
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
) -> (CompiledModules, FxIndexMap<WorkProductId, WorkProduct>) {
ongoing_codegen.downcast::<driver::aot::OngoingCodegen>().unwrap().join(sess, outputs)
}
}
+7 -6
View File
@@ -88,7 +88,7 @@
use rustc_codegen_ssa::base::codegen_crate;
use rustc_codegen_ssa::target_features::cfg_target_feature;
use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods};
use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig};
use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::sync::IntoDynSyncSend;
@@ -287,11 +287,12 @@ fn provide(&self, providers: &mut Providers) {
|tcx, ()| gcc_util::global_gcc_features(tcx.sess)
}
fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box<dyn Any> {
let target_cpu = target_cpu(tcx.sess);
let res = codegen_crate(self.clone(), tcx, target_cpu.to_string());
fn target_cpu(&self, sess: &Session) -> String {
target_cpu(sess).to_owned()
}
Box::new(res)
fn codegen_crate(&self, tcx: TyCtxt<'_>, crate_info: &CrateInfo) -> Box<dyn Any> {
Box::new(codegen_crate(self.clone(), tcx, crate_info))
}
fn join_codegen(
@@ -299,7 +300,7 @@ fn join_codegen(
ongoing_codegen: Box<dyn Any>,
sess: &Session,
_outputs: &OutputFilenames,
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
) -> (CompiledModules, FxIndexMap<WorkProductId, WorkProduct>) {
ongoing_codegen
.downcast::<rustc_codegen_ssa::back::write::OngoingCodegen<GccCodegenBackend>>()
.expect("Expected GccCodegenBackend's OngoingCodegen, found Box<Any>")
+14 -12
View File
@@ -33,7 +33,7 @@
TargetMachineFactoryFn,
};
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig};
use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_errors::{DiagCtxt, DiagCtxtHandle};
@@ -360,12 +360,12 @@ fn replaced_intrinsics(&self) -> Vec<Symbol> {
will_not_use_fallback
}
fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any> {
Box::new(rustc_codegen_ssa::base::codegen_crate(
LlvmCodegenBackend(()),
tcx,
crate::llvm_util::target_cpu(tcx.sess).to_string(),
))
fn target_cpu(&self, sess: &Session) -> String {
crate::llvm_util::target_cpu(sess).to_string()
}
fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>, crate_info: &CrateInfo) -> Box<dyn Any> {
Box::new(rustc_codegen_ssa::base::codegen_crate(LlvmCodegenBackend(()), tcx, crate_info))
}
fn join_codegen(
@@ -373,8 +373,8 @@ fn join_codegen(
ongoing_codegen: Box<dyn Any>,
sess: &Session,
outputs: &OutputFilenames,
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
let (codegen_results, work_products) = ongoing_codegen
) -> (CompiledModules, FxIndexMap<WorkProductId, WorkProduct>) {
let (compiled_modules, work_products) = ongoing_codegen
.downcast::<rustc_codegen_ssa::back::write::OngoingCodegen<LlvmCodegenBackend>>()
.expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box<Any>")
.join(sess);
@@ -386,13 +386,14 @@ fn join_codegen(
});
}
(codegen_results, work_products)
(compiled_modules, work_products)
}
fn link(
&self,
sess: &Session,
codegen_results: CodegenResults,
compiled_modules: CompiledModules,
crate_info: CrateInfo,
metadata: EncodedMetadata,
outputs: &OutputFilenames,
) {
@@ -405,7 +406,8 @@ fn link(
link_binary(
sess,
&LlvmArchiveBuilderBuilder,
codegen_results,
compiled_modules,
crate_info,
metadata,
outputs,
self.name(),
+149 -155
View File
@@ -60,7 +60,7 @@
use super::{apple, versioned_llvm_target};
use crate::base::needs_allocator_shim_for_linking;
use crate::{
CodegenResults, CompiledModule, CrateInfo, NativeLib, errors, looks_like_rust_object_file,
CompiledModule, CompiledModules, CrateInfo, NativeLib, errors, looks_like_rust_object_file,
};
pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) {
@@ -76,7 +76,8 @@ pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) {
pub fn link_binary(
sess: &Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: CodegenResults,
compiled_modules: CompiledModules,
crate_info: CrateInfo,
metadata: EncodedMetadata,
outputs: &OutputFilenames,
codegen_backend: &'static str,
@@ -84,7 +85,7 @@ pub fn link_binary(
let _timer = sess.timer("link_binary");
let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
let mut tempfiles_for_stdout_output: Vec<PathBuf> = Vec::new();
for &crate_type in &codegen_results.crate_info.crate_types {
for &crate_type in &crate_info.crate_types {
// Ignore executable crates if we have -Z no-codegen, as they will error.
if (sess.opts.unstable_opts.no_codegen || !sess.opts.output_types.should_codegen())
&& !output_metadata
@@ -98,25 +99,20 @@ pub fn link_binary(
}
sess.time("link_binary_check_files_are_writeable", || {
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
for obj in compiled_modules.modules.iter().filter_map(|m| m.object.as_ref()) {
check_file_is_writeable(obj, sess);
}
});
if outputs.outputs.should_link() {
let output = out_filename(
sess,
crate_type,
outputs,
codegen_results.crate_info.local_crate_name,
);
let output = out_filename(sess, crate_type, outputs, crate_info.local_crate_name);
let tmpdir = TempDirBuilder::new()
.prefix("rustc")
.tempdir_in(output.parent().unwrap_or_else(|| Path::new(".")))
.unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error }));
let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps);
let crate_name = format!("{}", codegen_results.crate_info.local_crate_name);
let crate_name = format!("{}", crate_info.local_crate_name);
let out_filename = output.file_for_writing(
outputs,
OutputType::Exe,
@@ -130,7 +126,8 @@ pub fn link_binary(
link_rlib(
sess,
archive_builder_builder,
&codegen_results,
&compiled_modules,
&crate_info,
&metadata,
RlibFlavor::Normal,
&path,
@@ -141,7 +138,8 @@ pub fn link_binary(
link_staticlib(
sess,
archive_builder_builder,
&codegen_results,
&compiled_modules,
&crate_info,
&metadata,
&out_filename,
&path,
@@ -153,7 +151,8 @@ pub fn link_binary(
archive_builder_builder,
crate_type,
&out_filename,
&codegen_results,
&compiled_modules,
&crate_info,
&metadata,
path.as_ref(),
codegen_backend,
@@ -218,7 +217,7 @@ pub fn link_binary(
|module: &CompiledModule| maybe_remove_temps_from_module(false, false, module);
// Otherwise, always remove the allocator module temporaries.
if let Some(ref allocator_module) = codegen_results.allocator_module {
if let Some(ref allocator_module) = compiled_modules.allocator_module {
remove_temps_from_module(allocator_module);
}
@@ -237,7 +236,7 @@ pub fn link_binary(
let (preserve_objects, preserve_dwarf_objects) = preserve_objects_for_their_debuginfo(sess);
debug!(?preserve_objects, ?preserve_dwarf_objects);
for module in &codegen_results.modules {
for module in &compiled_modules.modules {
maybe_remove_temps_from_module(preserve_objects, preserve_dwarf_objects, module);
}
});
@@ -298,7 +297,8 @@ pub fn each_linked_rlib(
fn link_rlib<'a>(
sess: &'a Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
compiled_modules: &CompiledModules,
crate_info: &CrateInfo,
metadata: &EncodedMetadata,
flavor: RlibFlavor,
tmpdir: &MaybeTempDir,
@@ -327,7 +327,7 @@ fn link_rlib<'a>(
RlibFlavor::StaticlibBase => None,
};
for m in &codegen_results.modules {
for m in &compiled_modules.modules {
if let Some(obj) = m.object.as_ref() {
ab.add_file(obj);
}
@@ -340,7 +340,7 @@ fn link_rlib<'a>(
match flavor {
RlibFlavor::Normal => {}
RlibFlavor::StaticlibBase => {
let obj = codegen_results.allocator_module.as_ref().and_then(|m| m.object.as_ref());
let obj = compiled_modules.allocator_module.as_ref().and_then(|m| m.object.as_ref());
if let Some(obj) = obj {
ab.add_file(obj);
}
@@ -366,7 +366,7 @@ fn link_rlib<'a>(
// feature then we'll need to figure out how to record what objects were
// loaded from the libraries found here and then encode that into the
// metadata of the rlib we're generating somehow.
for lib in codegen_results.crate_info.used_libraries.iter() {
for lib in crate_info.used_libraries.iter() {
let NativeLibKind::Static { bundle: None | Some(true), .. } = lib.kind else {
continue;
};
@@ -394,7 +394,7 @@ fn link_rlib<'a>(
for output_path in raw_dylib::create_raw_dylib_dll_import_libs(
sess,
archive_builder_builder,
codegen_results.crate_info.used_libraries.iter(),
crate_info.used_libraries.iter(),
tmpdir.as_ref(),
true,
) {
@@ -457,7 +457,8 @@ fn link_rlib<'a>(
fn link_staticlib(
sess: &Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
compiled_modules: &CompiledModules,
crate_info: &CrateInfo,
metadata: &EncodedMetadata,
out_filename: &Path,
tempdir: &MaybeTempDir,
@@ -466,72 +467,67 @@ fn link_staticlib(
let mut ab = link_rlib(
sess,
archive_builder_builder,
codegen_results,
compiled_modules,
crate_info,
metadata,
RlibFlavor::StaticlibBase,
tempdir,
);
let mut all_native_libs = vec![];
let res = each_linked_rlib(
&codegen_results.crate_info,
Some(CrateType::StaticLib),
&mut |cnum, path| {
let lto = are_upstream_rust_objects_already_included(sess)
&& !ignored_for_lto(sess, &codegen_results.crate_info, cnum);
let res = each_linked_rlib(crate_info, Some(CrateType::StaticLib), &mut |cnum, path| {
let lto = are_upstream_rust_objects_already_included(sess)
&& !ignored_for_lto(sess, crate_info, cnum);
let native_libs = codegen_results.crate_info.native_libraries[&cnum].iter();
let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib));
let relevant_libs: FxIndexSet<_> = relevant.filter_map(|lib| lib.filename).collect();
let native_libs = crate_info.native_libraries[&cnum].iter();
let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib));
let relevant_libs: FxIndexSet<_> = relevant.filter_map(|lib| lib.filename).collect();
let bundled_libs: FxIndexSet<_> = native_libs.filter_map(|lib| lib.filename).collect();
ab.add_archive(
path,
Box::new(move |fname: &str| {
// Ignore metadata files, no matter the name.
if fname == METADATA_FILENAME {
return true;
}
let bundled_libs: FxIndexSet<_> = native_libs.filter_map(|lib| lib.filename).collect();
ab.add_archive(
path,
Box::new(move |fname: &str| {
// Ignore metadata files, no matter the name.
if fname == METADATA_FILENAME {
return true;
}
// Don't include Rust objects if LTO is enabled
if lto && looks_like_rust_object_file(fname) {
return true;
}
// Don't include Rust objects if LTO is enabled
if lto && looks_like_rust_object_file(fname) {
return true;
}
// Skip objects for bundled libs.
if bundled_libs.contains(&Symbol::intern(fname)) {
return true;
}
// Skip objects for bundled libs.
if bundled_libs.contains(&Symbol::intern(fname)) {
return true;
}
false
}),
)
.unwrap();
false
}),
)
.unwrap();
archive_builder_builder
.extract_bundled_libs(path, tempdir.as_ref(), &relevant_libs)
.unwrap_or_else(|e| sess.dcx().emit_fatal(e));
archive_builder_builder
.extract_bundled_libs(path, tempdir.as_ref(), &relevant_libs)
.unwrap_or_else(|e| sess.dcx().emit_fatal(e));
for filename in relevant_libs.iter() {
let joined = tempdir.as_ref().join(filename.as_str());
let path = joined.as_path();
ab.add_archive(path, Box::new(|_| false)).unwrap();
}
for filename in relevant_libs.iter() {
let joined = tempdir.as_ref().join(filename.as_str());
let path = joined.as_path();
ab.add_archive(path, Box::new(|_| false)).unwrap();
}
all_native_libs
.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
},
);
all_native_libs.extend(crate_info.native_libraries[&cnum].iter().cloned());
});
if let Err(e) = res {
sess.dcx().emit_fatal(e);
}
ab.build(out_filename);
let crates = codegen_results.crate_info.used_crates.iter();
let crates = crate_info.used_crates.iter();
let fmts = codegen_results
.crate_info
let fmts = crate_info
.dependency_formats
.get(&CrateType::StaticLib)
.expect("no dependency formats for staticlib");
@@ -541,8 +537,8 @@ fn link_staticlib(
let Some(Linkage::Dynamic) = fmts.get(cnum) else {
continue;
};
let crate_name = codegen_results.crate_info.crate_name[&cnum];
let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum];
let crate_name = crate_info.crate_name[&cnum];
let used_crate_source = &crate_info.used_crate_source[&cnum];
if let Some(path) = &used_crate_source.dylib {
all_rust_dylibs.push(&**path);
} else if used_crate_source.rmeta.is_some() {
@@ -552,7 +548,7 @@ fn link_staticlib(
}
}
all_native_libs.extend_from_slice(&codegen_results.crate_info.used_libraries);
all_native_libs.extend_from_slice(&crate_info.used_libraries);
for print in &sess.opts.prints {
if print.kind == PrintKind::NativeStaticLibs {
@@ -563,7 +559,12 @@ fn link_staticlib(
/// Use `thorin` (rust implementation of a dwarf packaging utility) to link DWARF objects into a
/// DWARF package.
fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out_filename: &Path) {
fn link_dwarf_object(
sess: &Session,
compiled_modules: &CompiledModules,
crate_info: &CrateInfo,
executable_out_filename: &Path,
) {
let mut dwp_out_filename = executable_out_filename.to_path_buf().into_os_string();
dwp_out_filename.push(".dwp");
debug!(?dwp_out_filename, ?executable_out_filename);
@@ -604,20 +605,21 @@ fn read_input(&self, path: &Path) -> std::io::Result<&[u8]> {
// Input objs contain .o/.dwo files from the current crate.
match sess.opts.unstable_opts.split_dwarf_kind {
SplitDwarfKind::Single => {
for input_obj in cg_results.modules.iter().filter_map(|m| m.object.as_ref()) {
for input_obj in compiled_modules.modules.iter().filter_map(|m| m.object.as_ref()) {
package.add_input_object(input_obj)?;
}
}
SplitDwarfKind::Split => {
for input_obj in cg_results.modules.iter().filter_map(|m| m.dwarf_object.as_ref()) {
for input_obj in
compiled_modules.modules.iter().filter_map(|m| m.dwarf_object.as_ref())
{
package.add_input_object(input_obj)?;
}
}
}
// Input rlibs contain .o/.dwo files from dependencies.
let input_rlibs = cg_results
.crate_info
let input_rlibs = crate_info
.used_crate_source
.items()
.filter_map(|(_, csource)| csource.rlib.as_ref())
@@ -679,7 +681,8 @@ fn link_natively(
archive_builder_builder: &dyn ArchiveBuilderBuilder,
crate_type: CrateType,
out_filename: &Path,
codegen_results: &CodegenResults,
compiled_modules: &CompiledModules,
crate_info: &CrateInfo,
metadata: &EncodedMetadata,
tmpdir: &Path,
codegen_backend: &'static str,
@@ -705,7 +708,8 @@ fn link_natively(
crate_type,
tmpdir,
temp_filename,
codegen_results,
compiled_modules,
crate_info,
metadata,
self_contained_components,
codegen_backend,
@@ -936,7 +940,7 @@ fn link_natively(
}
}
let level = codegen_results.crate_info.lint_levels.linker_messages;
let level = crate_info.lint_levels.linker_messages;
let lint = |msg| {
diag_lint_level(sess, LINKER_MESSAGES, level, None, LinkerOutput { inner: msg });
};
@@ -1013,7 +1017,9 @@ fn link_natively(
// We cannot rely on the .o paths in the executable because they may have been
// remapped by --remap-path-prefix and therefore invalid, so we need to provide
// the .o/.dwo paths explicitly.
SplitDebuginfo::Packed => link_dwarf_object(sess, codegen_results, out_filename),
SplitDebuginfo::Packed => {
link_dwarf_object(sess, compiled_modules, crate_info, out_filename)
}
}
let strip = sess.opts.cg.strip;
@@ -1908,11 +1914,11 @@ fn add_late_link_args(
sess: &Session,
flavor: LinkerFlavor,
crate_type: CrateType,
codegen_results: &CodegenResults,
crate_info: &CrateInfo,
) {
let any_dynamic_crate = crate_type == CrateType::Dylib
|| crate_type == CrateType::Sdylib
|| codegen_results.crate_info.dependency_formats.iter().any(|(ty, list)| {
|| crate_info.dependency_formats.iter().any(|(ty, list)| {
*ty == crate_type && list.iter().any(|&linkage| linkage == Linkage::Dynamic)
});
if any_dynamic_crate {
@@ -2074,8 +2080,8 @@ fn add_linked_symbol_object(
}
/// Add object files containing code from the current crate.
fn add_local_crate_regular_objects(cmd: &mut dyn Linker, codegen_results: &CodegenResults) {
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
fn add_local_crate_regular_objects(cmd: &mut dyn Linker, compiled_modules: &CompiledModules) {
for obj in compiled_modules.modules.iter().filter_map(|m| m.object.as_ref()) {
cmd.add_object(obj);
}
}
@@ -2083,12 +2089,13 @@ fn add_local_crate_regular_objects(cmd: &mut dyn Linker, codegen_results: &Codeg
/// Add object files for allocator code linked once for the whole crate tree.
fn add_local_crate_allocator_objects(
cmd: &mut dyn Linker,
codegen_results: &CodegenResults,
compiled_modules: &CompiledModules,
crate_info: &CrateInfo,
crate_type: CrateType,
) {
if needs_allocator_shim_for_linking(&codegen_results.crate_info.dependency_formats, crate_type)
{
if let Some(obj) = codegen_results.allocator_module.as_ref().and_then(|m| m.object.as_ref())
if needs_allocator_shim_for_linking(&crate_info.dependency_formats, crate_type) {
if let Some(obj) =
compiled_modules.allocator_module.as_ref().and_then(|m| m.object.as_ref())
{
cmd.add_object(obj);
}
@@ -2102,7 +2109,7 @@ fn add_local_crate_metadata_objects(
archive_builder_builder: &dyn ArchiveBuilderBuilder,
crate_type: CrateType,
tmpdir: &Path,
codegen_results: &CodegenResults,
crate_info: &CrateInfo,
metadata: &EncodedMetadata,
) {
// When linking a dynamic library, we put the metadata into a section of the
@@ -2112,7 +2119,7 @@ fn add_local_crate_metadata_objects(
let data = archive_builder_builder.create_dylib_metadata_wrapper(
sess,
&metadata,
&codegen_results.crate_info.metadata_symbol,
&crate_info.metadata_symbol,
);
let obj = emit_wrapper_file(sess, &data, tmpdir, "rmeta.o");
@@ -2157,7 +2164,7 @@ fn add_relro_args(cmd: &mut dyn Linker, sess: &Session) {
fn add_rpath_args(
cmd: &mut dyn Linker,
sess: &Session,
codegen_results: &CodegenResults,
crate_info: &CrateInfo,
out_filename: &Path,
) {
if !sess.target.has_rpath {
@@ -2168,11 +2175,10 @@ fn add_rpath_args(
// where extern libraries might live, based on the
// add_lib_search_paths
if sess.opts.cg.rpath {
let libs = codegen_results
.crate_info
let libs = crate_info
.used_crates
.iter()
.filter_map(|cnum| codegen_results.crate_info.used_crate_source[cnum].dylib.as_deref())
.filter_map(|cnum| crate_info.used_crate_source[cnum].dylib.as_deref())
.collect::<Vec<_>>();
let rpath_config = RPathConfig {
libs: &*libs,
@@ -2265,7 +2271,8 @@ fn linker_with_args(
crate_type: CrateType,
tmpdir: &Path,
out_filename: &Path,
codegen_results: &CodegenResults,
compiled_modules: &CompiledModules,
crate_info: &CrateInfo,
metadata: &EncodedMetadata,
self_contained_components: LinkSelfContainedComponents,
codegen_backend: &'static str,
@@ -2276,17 +2283,17 @@ fn linker_with_args(
path,
flavor,
self_contained_components.are_any_components_enabled(),
&codegen_results.crate_info.target_cpu,
&crate_info.target_cpu,
codegen_backend,
);
let link_output_kind = link_output_kind(sess, crate_type);
let mut export_symbols = codegen_results.crate_info.exported_symbols[&crate_type].clone();
let mut export_symbols = crate_info.exported_symbols[&crate_type].clone();
if crate_type == CrateType::Cdylib {
let mut seen = FxHashSet::default();
for lib in &codegen_results.crate_info.used_libraries {
for lib in &crate_info.used_libraries {
if let NativeLibKind::Static { export_symbols: Some(true), .. } = lib.kind
&& seen.insert((lib.name, lib.verbatim))
{
@@ -2320,12 +2327,7 @@ fn linker_with_args(
// Pre-link CRT objects.
add_pre_link_objects(cmd, sess, flavor, link_output_kind, self_contained_crt_objects);
add_linked_symbol_object(
cmd,
sess,
tmpdir,
&codegen_results.crate_info.linked_symbols[&crate_type],
);
add_linked_symbol_object(cmd, sess, tmpdir, &crate_info.linked_symbols[&crate_type]);
// Sanitizer libraries.
add_sanitizer_libraries(sess, flavor, crate_type, cmd);
@@ -2357,17 +2359,17 @@ fn linker_with_args(
// link line. And finally upstream native libraries can't depend on anything
// in this DAG so far because they can only depend on other native libraries
// and such dependencies are also required to be specified.
add_local_crate_regular_objects(cmd, codegen_results);
add_local_crate_regular_objects(cmd, compiled_modules);
add_local_crate_metadata_objects(
cmd,
sess,
archive_builder_builder,
crate_type,
tmpdir,
codegen_results,
crate_info,
metadata,
);
add_local_crate_allocator_objects(cmd, codegen_results, crate_type);
add_local_crate_allocator_objects(cmd, compiled_modules, crate_info, crate_type);
// Avoid linking to dynamic libraries unless they satisfy some undefined symbols
// at the point at which they are specified on the command line.
@@ -2384,7 +2386,7 @@ fn linker_with_args(
cmd,
sess,
archive_builder_builder,
codegen_results,
crate_info,
tmpdir,
link_output_kind,
);
@@ -2394,7 +2396,7 @@ fn linker_with_args(
cmd,
sess,
archive_builder_builder,
codegen_results,
crate_info,
crate_type,
tmpdir,
link_output_kind,
@@ -2405,7 +2407,7 @@ fn linker_with_args(
cmd,
sess,
archive_builder_builder,
codegen_results,
crate_info,
tmpdir,
link_output_kind,
);
@@ -2428,7 +2430,7 @@ fn linker_with_args(
for output_path in raw_dylib::create_raw_dylib_dll_import_libs(
sess,
archive_builder_builder,
codegen_results.crate_info.used_libraries.iter(),
crate_info.used_libraries.iter(),
tmpdir,
true,
) {
@@ -2437,7 +2439,7 @@ fn linker_with_args(
} else {
for (link_path, as_needed) in raw_dylib::create_raw_dylib_elf_stub_shared_objects(
sess,
codegen_results.crate_info.used_libraries.iter(),
crate_info.used_libraries.iter(),
&raw_dylib_dir,
) {
// Always use verbatim linkage, see comments in create_raw_dylib_elf_stub_shared_objects.
@@ -2448,16 +2450,14 @@ fn linker_with_args(
// they are used within inlined functions or instantiated generic functions. We do this *after*
// handling the raw-dylib symbols in the current crate to make sure that those are chosen first
// by the linker.
let dependency_linkage = codegen_results
.crate_info
let dependency_linkage = crate_info
.dependency_formats
.get(&crate_type)
.expect("failed to find crate type in dependency format list");
// We sort the libraries below
#[allow(rustc::potential_query_instability)]
let mut native_libraries_from_nonstatics = codegen_results
.crate_info
let mut native_libraries_from_nonstatics = crate_info
.native_libraries
.iter()
.filter_map(|(&cnum, libraries)| {
@@ -2499,7 +2499,7 @@ fn linker_with_args(
// FIXME: Built-in target specs occasionally use this for linking system libraries,
// eliminate all such uses by migrating them to `#[link]` attributes in `lib(std,c,unwind)`
// and remove the option.
add_late_link_args(cmd, sess, flavor, crate_type, codegen_results);
add_late_link_args(cmd, sess, flavor, crate_type, crate_info);
// ------------ Arbitrary order-independent options ------------
@@ -2512,7 +2512,7 @@ fn linker_with_args(
self_contained_components,
flavor,
crate_type,
codegen_results,
crate_info,
out_filename,
tmpdir,
);
@@ -2552,7 +2552,7 @@ fn add_order_independent_options(
self_contained_components: LinkSelfContainedComponents,
flavor: LinkerFlavor,
crate_type: CrateType,
codegen_results: &CodegenResults,
crate_info: &CrateInfo,
out_filename: &Path,
tmpdir: &Path,
) {
@@ -2597,18 +2597,15 @@ fn add_order_independent_options(
"--target",
&versioned_llvm_target(sess),
"--target-cpu",
&codegen_results.crate_info.target_cpu,
&crate_info.target_cpu,
]);
if codegen_results.crate_info.target_features.len() > 0 {
cmd.link_arg(&format!(
"--target-feature={}",
&codegen_results.crate_info.target_features.join(",")
));
if crate_info.target_features.len() > 0 {
cmd.link_arg(&format!("--target-feature={}", &crate_info.target_features.join(",")));
}
} else if flavor == LinkerFlavor::Ptx {
cmd.link_args(&["--fallback-arch", &codegen_results.crate_info.target_cpu]);
cmd.link_args(&["--fallback-arch", &crate_info.target_cpu]);
} else if flavor == LinkerFlavor::Bpf {
cmd.link_args(&["--cpu", &codegen_results.crate_info.target_cpu]);
cmd.link_args(&["--cpu", &crate_info.target_cpu]);
if let Some(feat) = [sess.opts.cg.target_feature.as_str(), &sess.target.options.features]
.into_iter()
.find(|feat| !feat.is_empty())
@@ -2625,7 +2622,7 @@ fn add_order_independent_options(
if crate_type == CrateType::Executable
&& sess.target.is_like_windows
&& let Some(s) = &codegen_results.crate_info.windows_subsystem
&& let Some(s) = &crate_info.windows_subsystem
{
cmd.windows_subsystem(*s);
}
@@ -2653,8 +2650,8 @@ fn add_order_independent_options(
let natvis_visualizers = collect_natvis_visualizers(
tmpdir,
sess,
&codegen_results.crate_info.local_crate_name,
&codegen_results.crate_info.natvis_debugger_visualizers,
&crate_info.local_crate_name,
&crate_info.natvis_debugger_visualizers,
);
// Pass debuginfo, NatVis debugger visualizers and strip flags down to the linker.
@@ -2679,7 +2676,7 @@ fn add_order_independent_options(
cmd.ehcont_guard();
}
add_rpath_args(cmd, sess, codegen_results, out_filename);
add_rpath_args(cmd, sess, crate_info, out_filename);
}
// Write the NatVis debugger visualizer files for each crate to the temp directory and gather the file paths.
@@ -2713,7 +2710,7 @@ fn add_native_libs_from_crate(
cmd: &mut dyn Linker,
sess: &Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
crate_info: &CrateInfo,
tmpdir: &Path,
bundled_libs: &FxIndexSet<Symbol>,
cnum: CrateNum,
@@ -2730,15 +2727,15 @@ fn add_native_libs_from_crate(
if link_static && cnum != LOCAL_CRATE && !bundled_libs.is_empty() {
// If rlib contains native libs as archives, unpack them to tmpdir.
let rlib = codegen_results.crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap();
let rlib = crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap();
archive_builder_builder
.extract_bundled_libs(rlib, tmpdir, bundled_libs)
.unwrap_or_else(|e| sess.dcx().emit_fatal(e));
}
let native_libs = match cnum {
LOCAL_CRATE => &codegen_results.crate_info.used_libraries,
_ => &codegen_results.crate_info.native_libraries[&cnum],
LOCAL_CRATE => &crate_info.used_libraries,
_ => &crate_info.native_libraries[&cnum],
};
let mut last = (None, NativeLibKind::Unspecified, false);
@@ -2814,7 +2811,7 @@ fn add_local_native_libraries(
cmd: &mut dyn Linker,
sess: &Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
crate_info: &CrateInfo,
tmpdir: &Path,
link_output_kind: LinkOutputKind,
) {
@@ -2825,7 +2822,7 @@ fn add_local_native_libraries(
cmd,
sess,
archive_builder_builder,
codegen_results,
crate_info,
tmpdir,
&Default::default(),
LOCAL_CRATE,
@@ -2839,7 +2836,7 @@ fn add_upstream_rust_crates(
cmd: &mut dyn Linker,
sess: &Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
crate_info: &CrateInfo,
crate_type: CrateType,
tmpdir: &Path,
link_output_kind: LinkOutputKind,
@@ -2851,8 +2848,7 @@ fn add_upstream_rust_crates(
// Linking to a rlib involves just passing it to the linker (the linker
// will slurp up the object files inside), and linking to a dynamic library
// involves just passing the right -l flag.
let data = codegen_results
.crate_info
let data = crate_info
.dependency_formats
.get(&crate_type)
.expect("failed to find crate type in dependency format list");
@@ -2866,7 +2862,7 @@ fn add_upstream_rust_crates(
cmd.link_or_cc_arg("-bnoipath");
}
for &cnum in &codegen_results.crate_info.used_crates {
for &cnum in &crate_info.used_crates {
// We may not pass all crates through to the linker. Some crates may appear statically in
// an existing dylib, meaning we'll pick up all the symbols from the dylib.
// We must always link crates `compiler_builtins` and `profiler_builtins` statically.
@@ -2875,14 +2871,14 @@ fn add_upstream_rust_crates(
let linkage = data[cnum];
let link_static_crate = linkage == Linkage::Static
|| linkage == Linkage::IncludedFromDylib
&& (codegen_results.crate_info.compiler_builtins == Some(cnum)
|| codegen_results.crate_info.profiler_runtime == Some(cnum));
&& (crate_info.compiler_builtins == Some(cnum)
|| crate_info.profiler_runtime == Some(cnum));
let mut bundled_libs = Default::default();
match linkage {
Linkage::Static | Linkage::IncludedFromDylib | Linkage::NotLinked => {
if link_static_crate {
bundled_libs = codegen_results.crate_info.native_libraries[&cnum]
bundled_libs = crate_info.native_libraries[&cnum]
.iter()
.filter_map(|lib| lib.filename)
.collect();
@@ -2890,7 +2886,7 @@ fn add_upstream_rust_crates(
cmd,
sess,
archive_builder_builder,
codegen_results,
crate_info,
tmpdir,
cnum,
&bundled_libs,
@@ -2898,7 +2894,7 @@ fn add_upstream_rust_crates(
}
}
Linkage::Dynamic => {
let src = &codegen_results.crate_info.used_crate_source[&cnum];
let src = &crate_info.used_crate_source[&cnum];
add_dynamic_crate(cmd, sess, src.dylib.as_ref().unwrap());
}
}
@@ -2918,7 +2914,7 @@ fn add_upstream_rust_crates(
cmd,
sess,
archive_builder_builder,
codegen_results,
crate_info,
tmpdir,
&bundled_libs,
cnum,
@@ -2933,11 +2929,11 @@ fn add_upstream_native_libraries(
cmd: &mut dyn Linker,
sess: &Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
crate_info: &CrateInfo,
tmpdir: &Path,
link_output_kind: LinkOutputKind,
) {
for &cnum in &codegen_results.crate_info.used_crates {
for &cnum in &crate_info.used_crates {
// Static libraries are not linked here, they are linked in `add_upstream_rust_crates`.
// FIXME: Merge this function to `add_upstream_rust_crates` so that all native libraries
// are linked together with their respective upstream crates, and in their originally
@@ -2956,7 +2952,7 @@ fn add_upstream_native_libraries(
cmd,
sess,
archive_builder_builder,
codegen_results,
crate_info,
tmpdir,
&Default::default(),
cnum,
@@ -3021,19 +3017,18 @@ fn add_static_crate(
cmd: &mut dyn Linker,
sess: &Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
crate_info: &CrateInfo,
tmpdir: &Path,
cnum: CrateNum,
bundled_lib_file_names: &FxIndexSet<Symbol>,
) {
let src = &codegen_results.crate_info.used_crate_source[&cnum];
let src = &crate_info.used_crate_source[&cnum];
let cratepath = src.rlib.as_ref().unwrap();
let mut link_upstream =
|path: &Path| cmd.link_staticlib_by_path(&rehome_lib_path(sess, path), false);
if !are_upstream_rust_objects_already_included(sess)
|| ignored_for_lto(sess, &codegen_results.crate_info, cnum)
if !are_upstream_rust_objects_already_included(sess) || ignored_for_lto(sess, crate_info, cnum)
{
link_upstream(cratepath);
return;
@@ -3048,8 +3043,7 @@ fn add_static_crate(
let canonical_name = name.replace('-', "_");
let upstream_rust_objects_already_included =
are_upstream_rust_objects_already_included(sess);
let is_builtins =
sess.target.no_builtins || !codegen_results.crate_info.is_no_builtins.contains(&cnum);
let is_builtins = sess.target.no_builtins || !crate_info.is_no_builtins.contains(&cnum);
let mut archive = archive_builder_builder.new_archive_builder(sess);
if let Err(error) = archive.add_archive(
+10 -30
View File
@@ -42,7 +42,7 @@
use crate::errors::ErrorCreatingRemarkDir;
use crate::traits::*;
use crate::{
CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind,
CachedModuleCodegen, CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, ModuleKind,
errors,
};
@@ -394,16 +394,8 @@ fn generate_thin_lto_work<B: ExtraBackendMethods>(
.collect()
}
pub struct CompiledModules {
pub modules: Vec<CompiledModule>,
pub allocator_module: Option<CompiledModule>,
}
enum MaybeLtoModules<B: WriteBackendMethods> {
NoLto {
modules: Vec<CompiledModule>,
allocator_module: Option<CompiledModule>,
},
NoLto(CompiledModules),
FatLto {
cgcx: CodegenContext,
exported_symbols_for_lto: Arc<Vec<String>>,
@@ -443,15 +435,13 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
backend: B,
tcx: TyCtxt<'_>,
target_cpu: String,
crate_info: &CrateInfo,
allocator_module: Option<ModuleCodegen<B::Module>>,
) -> OngoingCodegen<B> {
let (coordinator_send, coordinator_receive) = channel();
let no_builtins = find_attr!(tcx, crate, NoBuiltins);
let crate_info = CrateInfo::new(tcx, target_cpu);
let regular_config = ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins);
let allocator_config = ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins);
@@ -461,7 +451,7 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
let coordinator_thread = start_executing_work(
backend.clone(),
tcx,
&crate_info,
crate_info,
shared_emitter,
codegen_worker_send,
coordinator_receive,
@@ -473,7 +463,6 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
OngoingCodegen {
backend,
crate_info,
codegen_worker_receive,
shared_emitter_main,
@@ -1818,12 +1807,12 @@ enum CodegenState {
}
}
Ok(MaybeLtoModules::NoLto {
Ok(MaybeLtoModules::NoLto(CompiledModules {
modules: compiled_modules,
allocator_module: allocator_module.map(|allocator_module| {
B::codegen(&cgcx, &prof, &shared_emitter, allocator_module, &allocator_config)
}),
})
}))
})
.expect("failed to spawn coordinator thread");
@@ -2139,7 +2128,6 @@ fn drop(&mut self) {
pub struct OngoingCodegen<B: ExtraBackendMethods> {
pub backend: B,
pub crate_info: CrateInfo,
pub output_filenames: Arc<OutputFilenames>,
// Field order below is intended to terminate the coordinator thread before two fields below
// drop and prematurely close channels used by coordinator thread. See `Coordinator`'s
@@ -2150,7 +2138,7 @@ pub struct OngoingCodegen<B: ExtraBackendMethods> {
}
impl<B: ExtraBackendMethods> OngoingCodegen<B> {
pub fn join(self, sess: &Session) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
pub fn join(self, sess: &Session) -> (CompiledModules, FxIndexMap<WorkProductId, WorkProduct>) {
self.shared_emitter_main.check(sess, true);
let maybe_lto_modules = sess.time("join_worker_thread", || match self.coordinator.join() {
@@ -2170,9 +2158,9 @@ pub fn join(self, sess: &Session) -> (CodegenResults, FxIndexMap<WorkProductId,
// Catch fatal errors to ensure shared_emitter_main.check() can emit the actual diagnostics
let compiled_modules = catch_fatal_errors(|| match maybe_lto_modules {
MaybeLtoModules::NoLto { modules, allocator_module } => {
MaybeLtoModules::NoLto(compiled_modules) => {
drop(shared_emitter);
CompiledModules { modules, allocator_module }
compiled_modules
}
MaybeLtoModules::FatLto {
cgcx,
@@ -2256,15 +2244,7 @@ pub fn join(self, sess: &Session) -> (CodegenResults, FxIndexMap<WorkProductId,
self.backend.print_statistics()
}
(
CodegenResults {
crate_info: self.crate_info,
modules: compiled_modules.modules,
allocator_module: compiled_modules.allocator_module,
},
work_products,
)
(compiled_modules, work_products)
}
pub(crate) fn codegen_finished(&self, tcx: TyCtxt<'_>) {
+2 -2
View File
@@ -681,7 +681,7 @@ pub fn allocator_shim_contents(tcx: TyCtxt<'_>, kind: AllocatorKind) -> Vec<Allo
pub fn codegen_crate<B: ExtraBackendMethods>(
backend: B,
tcx: TyCtxt<'_>,
target_cpu: String,
crate_info: &CrateInfo,
) -> OngoingCodegen<B> {
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
@@ -719,7 +719,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
None
};
let ongoing_codegen = start_async_codegen(backend.clone(), tcx, target_cpu, allocator_module);
let ongoing_codegen = start_async_codegen(backend.clone(), tcx, crate_info, 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
+12 -9
View File
@@ -209,7 +209,8 @@ fn from(lib: &cstore::NativeLib) -> Self {
/// identifiers (`CrateNum`) to `CrateSource`. The other fields map `CrateNum` to the crate's own
/// additional properties, so that effectively we can retrieve each dependent crate's `CrateSource`
/// and the corresponding properties without referencing information outside of a `CrateInfo`.
#[derive(Debug, Encodable, Decodable)]
// rustc_codegen_cranelift needs a Clone impl for its jit mode, which isn't tested in rust CI
#[derive(Clone, Debug, Encodable, Decodable)]
pub struct CrateInfo {
pub target_cpu: String,
pub target_features: Vec<String>,
@@ -251,10 +252,9 @@ pub struct TargetConfig {
}
#[derive(Encodable, Decodable)]
pub struct CodegenResults {
pub struct CompiledModules {
pub modules: Vec<CompiledModule>,
pub allocator_module: Option<CompiledModule>,
pub crate_info: CrateInfo,
}
pub enum CodegenErrors {
@@ -293,11 +293,12 @@ pub fn looks_like_rust_object_file(filename: &str) -> bool {
const RLINK_VERSION: u32 = 1;
const RLINK_MAGIC: &[u8] = b"rustlink";
impl CodegenResults {
impl CompiledModules {
pub fn serialize_rlink(
sess: &Session,
rlink_file: &Path,
codegen_results: &CodegenResults,
compiled_modules: &CompiledModules,
crate_info: &CrateInfo,
metadata: &EncodedMetadata,
outputs: &OutputFilenames,
) -> Result<usize, io::Error> {
@@ -307,7 +308,8 @@ pub fn serialize_rlink(
// Encoder's inner representation of `u32`.
encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes());
encoder.emit_str(sess.cfg_version);
Encodable::encode(codegen_results, &mut encoder);
Encodable::encode(compiled_modules, &mut encoder);
Encodable::encode(crate_info, &mut encoder);
Encodable::encode(metadata, &mut encoder);
Encodable::encode(outputs, &mut encoder);
encoder.finish().map_err(|(_path, err)| err)
@@ -316,7 +318,7 @@ pub fn serialize_rlink(
pub fn deserialize_rlink(
sess: &Session,
data: Vec<u8>,
) -> Result<(Self, EncodedMetadata, OutputFilenames), CodegenErrors> {
) -> Result<(Self, CrateInfo, EncodedMetadata, OutputFilenames), CodegenErrors> {
// The Decodable machinery is not used here because it panics if the input data is invalid
// and because its internal representation may change.
if !data.starts_with(RLINK_MAGIC) {
@@ -346,10 +348,11 @@ pub fn deserialize_rlink(
});
}
let codegen_results = CodegenResults::decode(&mut decoder);
let compiled_modules = CompiledModules::decode(&mut decoder);
let crate_info = CrateInfo::decode(&mut decoder);
let metadata = EncodedMetadata::decode(&mut decoder);
let outputs = OutputFilenames::decode(&mut decoder);
Ok((codegen_results, metadata, outputs))
Ok((compiled_modules, crate_info, metadata, outputs))
}
}
@@ -18,7 +18,7 @@
use crate::back::archive::ArArchiveBuilderBuilder;
use crate::back::link::link_binary;
use crate::back::write::TargetMachineFactoryFn;
use crate::{CodegenResults, ModuleCodegen, TargetConfig};
use crate::{CompiledModules, CrateInfo, ModuleCodegen, TargetConfig};
pub trait BackendTypes {
type Function: CodegenObject;
@@ -103,7 +103,9 @@ fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
fn provide(&self, _providers: &mut Providers) {}
fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any>;
fn target_cpu(&self, sess: &Session) -> String;
fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>, crate_info: &CrateInfo) -> Box<dyn Any>;
/// This is called on the returned `Box<dyn Any>` from [`codegen_crate`](Self::codegen_crate)
///
@@ -115,20 +117,22 @@ fn join_codegen(
ongoing_codegen: Box<dyn Any>,
sess: &Session,
outputs: &OutputFilenames,
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>);
) -> (CompiledModules, FxIndexMap<WorkProductId, WorkProduct>);
/// This is called on the returned [`CodegenResults`] from [`join_codegen`](Self::join_codegen).
/// This is called on the returned [`CompiledModules`] from [`join_codegen`](Self::join_codegen).
fn link(
&self,
sess: &Session,
codegen_results: CodegenResults,
compiled_modules: CompiledModules,
crate_info: CrateInfo,
metadata: EncodedMetadata,
outputs: &OutputFilenames,
) {
link_binary(
sess,
&ArArchiveBuilderBuilder,
codegen_results,
compiled_modules,
crate_info,
metadata,
outputs,
self.name(),
+7 -5
View File
@@ -28,7 +28,7 @@
use rustc_ast as ast;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::{CodegenErrors, CodegenResults};
use rustc_codegen_ssa::{CodegenErrors, CompiledModules};
use rustc_data_structures::profiling::{
TimePassesFormat, get_resident_set_size, print_time_passes_entry,
};
@@ -556,9 +556,11 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
let rlink_data = fs::read(file).unwrap_or_else(|err| {
dcx.emit_fatal(RlinkUnableToRead { err });
});
let (codegen_results, metadata, outputs) =
match CodegenResults::deserialize_rlink(sess, rlink_data) {
Ok((codegen, metadata, outputs)) => (codegen, metadata, outputs),
let (compiled_modules, crate_info, metadata, outputs) =
match CompiledModules::deserialize_rlink(sess, rlink_data) {
Ok((codegen, crate_info, metadata, outputs)) => {
(codegen, crate_info, metadata, outputs)
}
Err(err) => {
match err {
CodegenErrors::WrongFileType => dcx.emit_fatal(RLinkWrongFileType),
@@ -583,7 +585,7 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
};
}
};
compiler.codegen_backend.link(sess, codegen_results, metadata, &outputs);
compiler.codegen_backend.link(sess, compiled_modules, crate_info, metadata, &outputs);
} else {
dcx.emit_fatal(RlinkNotAFile {});
}
+8 -10
View File
@@ -8,7 +8,7 @@
use rustc_ast::{self as ast, CRATE_NODE_ID};
use rustc_attr_parsing::{AttributeParser, Early, ShouldEmit};
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::{CodegenResults, CrateInfo};
use rustc_codegen_ssa::{CompiledModules, CrateInfo};
use rustc_data_structures::indexmap::IndexMap;
use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal, par_fns};
@@ -1194,7 +1194,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
pub(crate) fn start_codegen<'tcx>(
codegen_backend: &dyn CodegenBackend,
tcx: TyCtxt<'tcx>,
) -> (Box<dyn Any>, EncodedMetadata) {
) -> (Box<dyn Any>, CrateInfo, EncodedMetadata) {
tcx.sess.timings.start_section(tcx.sess.dcx(), TimingSection::Codegen);
// Hook for tests.
@@ -1221,19 +1221,17 @@ pub(crate) fn start_codegen<'tcx>(
let metadata = rustc_metadata::fs::encode_and_write_metadata(tcx);
let codegen = tcx.sess.time("codegen_crate", move || {
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.
tcx.sess.dcx().abort_if_errors();
// Linker::link will skip join_codegen in case of a CodegenResults Any value.
Box::new(CodegenResults {
modules: vec![],
allocator_module: None,
crate_info: CrateInfo::new(tcx, "<dummy cpu>".to_owned()),
})
Box::new(CompiledModules { modules: vec![], allocator_module: None })
} else {
codegen_backend.codegen_crate(tcx)
codegen_backend.codegen_crate(tcx, &crate_info)
}
});
@@ -1245,7 +1243,7 @@ pub(crate) fn start_codegen<'tcx>(
tcx.sess.code_stats.print_type_sizes();
}
(codegen, metadata)
(codegen, crate_info, metadata)
}
/// Compute and validate the crate name.
+17 -8
View File
@@ -1,8 +1,8 @@
use std::any::Any;
use std::sync::Arc;
use rustc_codegen_ssa::CodegenResults;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::{CompiledModules, CrateInfo};
use rustc_data_structures::indexmap::IndexMap;
use rustc_data_structures::svh::Svh;
use rustc_errors::timings::TimingSection;
@@ -21,6 +21,7 @@ pub struct Linker {
output_filenames: Arc<OutputFilenames>,
// Only present when incr. comp. is enabled.
crate_hash: Option<Svh>,
crate_info: CrateInfo,
metadata: EncodedMetadata,
ongoing_codegen: Box<dyn Any>,
}
@@ -30,7 +31,7 @@ pub fn codegen_and_build_linker(
tcx: TyCtxt<'_>,
codegen_backend: &dyn CodegenBackend,
) -> Linker {
let (ongoing_codegen, metadata) = passes::start_codegen(codegen_backend, tcx);
let (ongoing_codegen, crate_info, metadata) = passes::start_codegen(codegen_backend, tcx);
Linker {
dep_graph: tcx.dep_graph.clone(),
@@ -40,16 +41,17 @@ pub fn codegen_and_build_linker(
} else {
None
},
crate_info,
metadata,
ongoing_codegen,
}
}
pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) {
let (codegen_results, mut work_products) = sess.time("finish_ongoing_codegen", || {
match self.ongoing_codegen.downcast::<CodegenResults>() {
let (compiled_modules, mut work_products) = sess.time("finish_ongoing_codegen", || {
match self.ongoing_codegen.downcast::<CompiledModules>() {
// This was a check only build
Ok(codegen_results) => (*codegen_results, IndexMap::default()),
Ok(compiled_modules) => (*compiled_modules, IndexMap::default()),
Err(ongoing_codegen) => {
codegen_backend.join_codegen(ongoing_codegen, sess, &self.output_filenames)
@@ -97,10 +99,11 @@ pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) {
if sess.opts.unstable_opts.no_link {
let rlink_file = self.output_filenames.with_extension(config::RLINK_EXT);
CodegenResults::serialize_rlink(
CompiledModules::serialize_rlink(
sess,
&rlink_file,
&codegen_results,
&compiled_modules,
&self.crate_info,
&self.metadata,
&self.output_filenames,
)
@@ -112,6 +115,12 @@ pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) {
let _timer = sess.prof.verbose_generic_activity("link_crate");
let _timing = sess.timings.section_guard(sess.dcx(), TimingSection::Linking);
codegen_backend.link(sess, codegen_results, self.metadata, &self.output_filenames)
codegen_backend.link(
sess,
compiled_modules,
self.crate_info,
self.metadata,
&self.output_filenames,
)
}
}
+14 -15
View File
@@ -11,7 +11,7 @@
use rustc_codegen_ssa::back::link::link_binary;
use rustc_codegen_ssa::target_features::cfg_target_feature;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::{CodegenResults, CrateInfo, TargetConfig};
use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::jobserver::Proxy;
use rustc_data_structures::sync;
@@ -401,12 +401,12 @@ fn supported_crate_types(&self, _sess: &Session) -> Vec<CrateType> {
vec![CrateType::Rlib, CrateType::Executable]
}
fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any> {
Box::new(CodegenResults {
modules: vec![],
allocator_module: None,
crate_info: CrateInfo::new(tcx, String::new()),
})
fn target_cpu(&self, _sess: &Session) -> String {
String::new()
}
fn codegen_crate<'tcx>(&self, _tcx: TyCtxt<'tcx>, _crate_info: &CrateInfo) -> Box<dyn Any> {
Box::new(CompiledModules { modules: vec![], allocator_module: None })
}
fn join_codegen(
@@ -414,24 +414,22 @@ fn join_codegen(
ongoing_codegen: Box<dyn Any>,
_sess: &Session,
_outputs: &OutputFilenames,
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
) -> (CompiledModules, FxIndexMap<WorkProductId, WorkProduct>) {
(*ongoing_codegen.downcast().unwrap(), FxIndexMap::default())
}
fn link(
&self,
sess: &Session,
codegen_results: CodegenResults,
compiled_modules: CompiledModules,
crate_info: CrateInfo,
metadata: EncodedMetadata,
outputs: &OutputFilenames,
) {
// JUSTIFICATION: TyCtxt no longer available here
#[allow(rustc::bad_opt_access)]
if let Some(&crate_type) = codegen_results
.crate_info
.crate_types
.iter()
.find(|&&crate_type| crate_type != CrateType::Rlib)
if let Some(&crate_type) =
crate_info.crate_types.iter().find(|&&crate_type| crate_type != CrateType::Rlib)
&& outputs.outputs.should_link()
{
sess.dcx().fatal(format!(
@@ -442,7 +440,8 @@ fn link(
link_binary(
sess,
&DummyArchiveBuilderBuilder,
codegen_results,
compiled_modules,
crate_info,
metadata,
outputs,
self.name(),
@@ -18,7 +18,7 @@
use std::any::Any;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::{CodegenResults, CrateInfo};
use rustc_codegen_ssa::{CompiledModules, CrateInfo};
use rustc_data_structures::fx::FxIndexMap;
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
@@ -33,12 +33,12 @@ fn name(&self) -> &'static str {
"the-backend"
}
fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box<dyn Any> {
Box::new(CodegenResults {
modules: vec![],
allocator_module: None,
crate_info: CrateInfo::new(tcx, "fake_target_cpu".to_string()),
})
fn target_cpu(&self, _sess: &Session) -> String {
"fake_target_cpu".to_owned()
}
fn codegen_crate(&self, _tcx: TyCtxt<'_>, _crate_info: &CrateInfo) -> Box<dyn Any> {
Box::new(CompiledModules { modules: vec![], allocator_module: None })
}
fn join_codegen(
@@ -46,17 +46,18 @@ fn join_codegen(
ongoing_codegen: Box<dyn Any>,
_sess: &Session,
_outputs: &OutputFilenames,
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
) -> (CompiledModules, FxIndexMap<WorkProductId, WorkProduct>) {
let codegen_results = ongoing_codegen
.downcast::<CodegenResults>()
.expect("in join_codegen: ongoing_codegen is not a CodegenResults");
.downcast::<CompiledModules>()
.expect("in join_codegen: ongoing_codegen is not a CompiledModules");
(*codegen_results, FxIndexMap::default())
}
fn link(
&self,
sess: &Session,
codegen_results: CodegenResults,
_compiled_modules: CompiledModules,
crate_info: CrateInfo,
_metadata: EncodedMetadata,
outputs: &OutputFilenames,
) {
@@ -65,7 +66,7 @@ fn link(
use rustc_session::config::{CrateType, OutFileName};
use rustc_session::output::out_filename;
let crate_name = codegen_results.crate_info.local_crate_name;
let crate_name = crate_info.local_crate_name;
for &crate_type in sess.opts.crate_types.iter() {
if crate_type != CrateType::Rlib {
sess.dcx().fatal(format!("Crate type is {:?}", crate_type));
@@ -10,4 +10,5 @@ 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`
@@ -1,3 +1,5 @@
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`?)
@@ -6,5 +8,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 1 previous error
error: aborting due to 2 previous errors