Only borrow EncodedMetadata in codegen_crate

And move passing it to the linker to the driver code.
This commit is contained in:
bjorn3 2025-05-30 11:55:06 +00:00
parent c68032fd4c
commit badabab01f
12 changed files with 90 additions and 91 deletions

View file

@ -62,7 +62,6 @@ pub(crate) struct OngoingCodegen {
modules: Vec<OngoingModuleCodegen>,
allocator_module: Option<CompiledModule>,
metadata_module: Option<CompiledModule>,
metadata: EncodedMetadata,
crate_info: CrateInfo,
concurrency_limiter: ConcurrencyLimiter,
}
@ -135,7 +134,6 @@ impl OngoingCodegen {
modules,
allocator_module: self.allocator_module,
metadata_module: self.metadata_module,
metadata: self.metadata,
crate_info: self.crate_info,
};
@ -706,11 +704,7 @@ fn emit_allocator_module(tcx: TyCtxt<'_>) -> Option<CompiledModule> {
}
}
pub(crate) fn run_aot(
tcx: TyCtxt<'_>,
metadata: EncodedMetadata,
need_metadata_module: bool,
) -> Box<OngoingCodegen> {
pub(crate) fn run_aot(tcx: TyCtxt<'_>, metadata: Option<&EncodedMetadata>) -> Box<OngoingCodegen> {
// FIXME handle `-Ctarget-cpu=native`
let target_cpu = match tcx.sess.opts.cg.target_cpu {
Some(ref name) => name,
@ -727,7 +721,6 @@ pub(crate) fn run_aot(
modules: vec![],
allocator_module: None,
metadata_module: None,
metadata,
crate_info: CrateInfo::new(tcx, target_cpu),
concurrency_limiter: ConcurrencyLimiter::new(0),
});
@ -787,14 +780,12 @@ pub(crate) fn run_aot(
let allocator_module = emit_allocator_module(tcx);
let metadata_module =
if need_metadata_module { Some(emit_metadata_module(tcx, &metadata)) } else { None };
let metadata_module = metadata.map(|metadata| emit_metadata_module(tcx, metadata));
Box::new(OngoingCodegen {
modules,
allocator_module,
metadata_module,
metadata,
crate_info: CrateInfo::new(tcx, target_cpu),
concurrency_limiter: concurrency_limiter.0,
})

View file

@ -238,12 +238,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
println!("Cranelift version: {}", cranelift_codegen::VERSION);
}
fn codegen_crate(
&self,
tcx: TyCtxt<'_>,
metadata: EncodedMetadata,
need_metadata_module: bool,
) -> Box<dyn Any> {
fn codegen_crate(&self, tcx: TyCtxt<'_>, metadata: Option<&EncodedMetadata>) -> Box<dyn Any> {
info!("codegen crate {}", tcx.crate_name(LOCAL_CRATE));
let config = self.config.clone().unwrap_or_else(|| {
BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args)
@ -256,7 +251,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
#[cfg(not(feature = "jit"))]
tcx.dcx().fatal("jit support was disabled when compiling rustc_codegen_cranelift");
} else {
driver::aot::run_aot(tcx, metadata, need_metadata_module)
driver::aot::run_aot(tcx, metadata)
}
}

View file

@ -230,20 +230,9 @@ impl CodegenBackend for GccCodegenBackend {
providers.global_backend_features = |tcx, ()| gcc_util::global_gcc_features(tcx.sess, true)
}
fn codegen_crate(
&self,
tcx: TyCtxt<'_>,
metadata: EncodedMetadata,
need_metadata_module: bool,
) -> Box<dyn Any> {
fn codegen_crate(&self, tcx: TyCtxt<'_>, metadata: Option<&EncodedMetadata>) -> Box<dyn Any> {
let target_cpu = target_cpu(tcx.sess);
let res = codegen_crate(
self.clone(),
tcx,
target_cpu.to_string(),
metadata,
need_metadata_module,
);
let res = codegen_crate(self.clone(), tcx, target_cpu.to_string(), metadata);
Box::new(res)
}

View file

@ -344,15 +344,13 @@ impl CodegenBackend for LlvmCodegenBackend {
fn codegen_crate<'tcx>(
&self,
tcx: TyCtxt<'tcx>,
metadata: EncodedMetadata,
need_metadata_module: bool,
metadata: Option<&EncodedMetadata>,
) -> Box<dyn Any> {
Box::new(rustc_codegen_ssa::base::codegen_crate(
LlvmCodegenBackend(()),
tcx,
crate::llvm_util::target_cpu(tcx.sess).to_string(),
metadata,
need_metadata_module,
))
}
@ -377,14 +375,20 @@ impl CodegenBackend for LlvmCodegenBackend {
(codegen_results, work_products)
}
fn link(&self, sess: &Session, codegen_results: CodegenResults, outputs: &OutputFilenames) {
fn link(
&self,
sess: &Session,
codegen_results: CodegenResults,
metadata: EncodedMetadata,
outputs: &OutputFilenames,
) {
use rustc_codegen_ssa::back::link::link_binary;
use crate::back::archive::LlvmArchiveBuilderBuilder;
// Run the linker on any artifacts that resulted from the LLVM run.
// This should produce either a finished executable or library.
link_binary(sess, &LlvmArchiveBuilderBuilder, codegen_results, outputs);
link_binary(sess, &LlvmArchiveBuilderBuilder, codegen_results, metadata, outputs);
}
}

View file

@ -23,7 +23,8 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_macros::LintDiagnostic;
use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file};
use rustc_metadata::{
NativeLibSearchFallback, find_native_static_library, walk_native_lib_search_dirs,
EncodedMetadata, NativeLibSearchFallback, find_native_static_library,
walk_native_lib_search_dirs,
};
use rustc_middle::bug;
use rustc_middle::lint::lint_level;
@ -91,6 +92,7 @@ pub fn link_binary(
sess: &Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: CodegenResults,
metadata: EncodedMetadata,
outputs: &OutputFilenames,
) {
let _timer = sess.timer("link_binary");
@ -142,6 +144,7 @@ pub fn link_binary(
sess,
archive_builder_builder,
&codegen_results,
&metadata,
RlibFlavor::Normal,
&path,
)
@ -152,6 +155,7 @@ pub fn link_binary(
sess,
archive_builder_builder,
&codegen_results,
&metadata,
&out_filename,
&path,
);
@ -312,6 +316,7 @@ fn link_rlib<'a>(
sess: &'a Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
metadata: &EncodedMetadata,
flavor: RlibFlavor,
tmpdir: &MaybeTempDir,
) -> Box<dyn ArchiveBuilder + 'a> {
@ -319,11 +324,8 @@ fn link_rlib<'a>(
let trailing_metadata = match flavor {
RlibFlavor::Normal => {
let (metadata, metadata_position) = create_wrapper_file(
sess,
".rmeta".to_string(),
codegen_results.metadata.stub_or_full(),
);
let (metadata, metadata_position) =
create_wrapper_file(sess, ".rmeta".to_string(), metadata.stub_or_full());
let metadata = emit_wrapper_file(sess, &metadata, tmpdir, METADATA_FILENAME);
match metadata_position {
MetadataPosition::First => {
@ -473,6 +475,7 @@ fn link_staticlib(
sess: &Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
metadata: &EncodedMetadata,
out_filename: &Path,
tempdir: &MaybeTempDir,
) {
@ -481,6 +484,7 @@ fn link_staticlib(
sess,
archive_builder_builder,
codegen_results,
metadata,
RlibFlavor::StaticlibBase,
tempdir,
);

View file

@ -24,7 +24,6 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_incremental::{
copy_cgu_workproduct_to_incr_comp_cache_dir, in_incr_comp_dir, in_incr_comp_dir_sess,
};
use rustc_metadata::EncodedMetadata;
use rustc_metadata::fs::copy_to_stdout;
use rustc_middle::bug;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
@ -474,7 +473,6 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
backend: B,
tcx: TyCtxt<'_>,
target_cpu: String,
metadata: EncodedMetadata,
metadata_module: Option<CompiledModule>,
) -> OngoingCodegen<B> {
let (coordinator_send, coordinator_receive) = channel();
@ -506,7 +504,6 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
OngoingCodegen {
backend,
metadata,
metadata_module,
crate_info,
@ -2055,7 +2052,6 @@ impl<B: ExtraBackendMethods> Drop for Coordinator<B> {
pub struct OngoingCodegen<B: ExtraBackendMethods> {
pub backend: B,
pub metadata: EncodedMetadata,
pub metadata_module: Option<CompiledModule>,
pub crate_info: CrateInfo,
pub codegen_worker_receive: Receiver<CguMessage>,
@ -2096,7 +2092,6 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
(
CodegenResults {
metadata: self.metadata,
crate_info: self.crate_info,
modules: compiled_modules.modules,

View file

@ -669,12 +669,11 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
backend: B,
tcx: TyCtxt<'_>,
target_cpu: String,
metadata: EncodedMetadata,
need_metadata_module: bool,
metadata: Option<&EncodedMetadata>,
) -> OngoingCodegen<B> {
// Skip crate items and just output metadata in -Z no-codegen mode.
if tcx.sess.opts.unstable_opts.no_codegen || !tcx.sess.opts.output_types.should_codegen() {
let ongoing_codegen = start_async_codegen(backend, tcx, target_cpu, metadata, None);
let ongoing_codegen = start_async_codegen(backend, tcx, target_cpu, None);
ongoing_codegen.codegen_finished(tcx);
@ -707,7 +706,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
}
}
let metadata_module = need_metadata_module.then(|| {
let metadata_module = if let Some(metadata) = metadata {
// Emit compressed metadata object.
let metadata_cgu_name =
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("metadata")).to_string();
@ -719,13 +718,13 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
);
let data = create_compressed_metadata_file(
tcx.sess,
&metadata,
metadata,
&exported_symbols::metadata_symbol_name(tcx),
);
if let Err(error) = std::fs::write(&file_name, data) {
tcx.dcx().emit_fatal(errors::MetadataObjectFileWrite { error });
}
CompiledModule {
Some(CompiledModule {
name: metadata_cgu_name,
kind: ModuleKind::Metadata,
object: Some(file_name),
@ -734,12 +733,13 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
assembly: None,
llvm_ir: None,
links_from_incr_cache: Vec::new(),
}
})
})
});
} else {
None
};
let ongoing_codegen =
start_async_codegen(backend.clone(), tcx, target_cpu, metadata, metadata_module);
let ongoing_codegen = start_async_codegen(backend.clone(), tcx, target_cpu, metadata_module);
// Codegen an allocator shim, if necessary.
if let Some(kind) = allocator_kind_for_codegen(tcx) {

View file

@ -31,6 +31,7 @@ use rustc_data_structures::unord::UnordMap;
use rustc_hir::CRATE_HIR_ID;
use rustc_hir::def_id::CrateNum;
use rustc_macros::{Decodable, Encodable, HashStable};
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::lint::LevelAndSource;
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
@ -258,7 +259,6 @@ pub struct CodegenResults {
pub modules: Vec<CompiledModule>,
pub allocator_module: Option<CompiledModule>,
pub metadata_module: Option<CompiledModule>,
pub metadata: rustc_metadata::EncodedMetadata,
pub crate_info: CrateInfo,
}
@ -303,6 +303,7 @@ impl CodegenResults {
sess: &Session,
rlink_file: &Path,
codegen_results: &CodegenResults,
metadata: &EncodedMetadata,
outputs: &OutputFilenames,
) -> Result<usize, io::Error> {
let mut encoder = FileEncoder::new(rlink_file)?;
@ -312,6 +313,7 @@ impl CodegenResults {
encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes());
encoder.emit_str(sess.cfg_version);
Encodable::encode(codegen_results, &mut encoder);
Encodable::encode(metadata, &mut encoder);
Encodable::encode(outputs, &mut encoder);
encoder.finish().map_err(|(_path, err)| err)
}
@ -319,7 +321,7 @@ impl CodegenResults {
pub fn deserialize_rlink(
sess: &Session,
data: Vec<u8>,
) -> Result<(Self, OutputFilenames), CodegenErrors> {
) -> Result<(Self, 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) {
@ -350,8 +352,9 @@ impl CodegenResults {
}
let codegen_results = CodegenResults::decode(&mut decoder);
let metadata = EncodedMetadata::decode(&mut decoder);
let outputs = OutputFilenames::decode(&mut decoder);
Ok((codegen_results, outputs))
Ok((codegen_results, metadata, outputs))
}
}

View file

@ -77,8 +77,7 @@ pub trait CodegenBackend {
fn codegen_crate<'tcx>(
&self,
tcx: TyCtxt<'tcx>,
metadata: EncodedMetadata,
need_metadata_module: bool,
metadata: Option<&EncodedMetadata>,
) -> Box<dyn Any>;
/// This is called on the returned `Box<dyn Any>` from [`codegen_crate`](Self::codegen_crate)
@ -94,8 +93,14 @@ pub trait CodegenBackend {
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>);
/// This is called on the returned [`CodegenResults`] from [`join_codegen`](Self::join_codegen).
fn link(&self, sess: &Session, codegen_results: CodegenResults, outputs: &OutputFilenames) {
link_binary(sess, &ArArchiveBuilderBuilder, codegen_results, outputs);
fn link(
&self,
sess: &Session,
codegen_results: CodegenResults,
metadata: EncodedMetadata,
outputs: &OutputFilenames,
) {
link_binary(sess, &ArArchiveBuilderBuilder, codegen_results, metadata, outputs);
}
}

View file

@ -557,27 +557,34 @@ 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, outputs) = match CodegenResults::deserialize_rlink(sess, rlink_data) {
Ok((codegen, outputs)) => (codegen, outputs),
Err(err) => {
match err {
CodegenErrors::WrongFileType => dcx.emit_fatal(RLinkWrongFileType),
CodegenErrors::EmptyVersionNumber => dcx.emit_fatal(RLinkEmptyVersionNumber),
CodegenErrors::EncodingVersionMismatch { version_array, rlink_version } => dcx
.emit_fatal(RLinkEncodingVersionMismatch { version_array, rlink_version }),
CodegenErrors::RustcVersionMismatch { rustc_version } => {
dcx.emit_fatal(RLinkRustcVersionMismatch {
rustc_version,
current_version: sess.cfg_version,
})
}
CodegenErrors::CorruptFile => {
dcx.emit_fatal(RlinkCorruptFile { file });
}
};
}
};
compiler.codegen_backend.link(sess, codegen_results, &outputs);
let (codegen_results, metadata, outputs) =
match CodegenResults::deserialize_rlink(sess, rlink_data) {
Ok((codegen, metadata, outputs)) => (codegen, metadata, outputs),
Err(err) => {
match err {
CodegenErrors::WrongFileType => dcx.emit_fatal(RLinkWrongFileType),
CodegenErrors::EmptyVersionNumber => {
dcx.emit_fatal(RLinkEmptyVersionNumber)
}
CodegenErrors::EncodingVersionMismatch { version_array, rlink_version } => {
dcx.emit_fatal(RLinkEncodingVersionMismatch {
version_array,
rlink_version,
})
}
CodegenErrors::RustcVersionMismatch { rustc_version } => {
dcx.emit_fatal(RLinkRustcVersionMismatch {
rustc_version,
current_version: sess.cfg_version,
})
}
CodegenErrors::CorruptFile => {
dcx.emit_fatal(RlinkCorruptFile { file });
}
};
}
};
compiler.codegen_backend.link(sess, codegen_results, metadata, &outputs);
} else {
dcx.emit_fatal(RlinkNotAFile {});
}

View file

@ -18,6 +18,7 @@ use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap};
use rustc_hir::definitions::Definitions;
use rustc_incremental::setup_dep_graph;
use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_store};
use rustc_metadata::EncodedMetadata;
use rustc_metadata::creader::CStore;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepsType;
@ -1112,7 +1113,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
pub(crate) fn start_codegen<'tcx>(
codegen_backend: &dyn CodegenBackend,
tcx: TyCtxt<'tcx>,
) -> Box<dyn Any> {
) -> (Box<dyn Any>, EncodedMetadata) {
// Hook for tests.
if let Some((def_id, _)) = tcx.entry_fn(())
&& tcx.has_attr(def_id, sym::rustc_delayed_bug_from_inside_query)
@ -1137,8 +1138,9 @@ pub(crate) fn start_codegen<'tcx>(
let (metadata, need_metadata_module) = rustc_metadata::fs::encode_and_write_metadata(tcx);
let codegen = tcx.sess.time("codegen_crate", move || {
codegen_backend.codegen_crate(tcx, metadata, need_metadata_module)
let codegen = tcx.sess.time("codegen_crate", || {
codegen_backend
.codegen_crate(tcx, if need_metadata_module { Some(&metadata) } else { None })
});
info!("Post-codegen\n{:?}", tcx.debug_stats());
@ -1149,7 +1151,7 @@ pub(crate) fn start_codegen<'tcx>(
tcx.sess.code_stats.print_type_sizes();
}
codegen
(codegen, metadata)
}
/// Compute and validate the crate name.

View file

@ -5,6 +5,7 @@ use rustc_codegen_ssa::CodegenResults;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::svh::Svh;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::DepGraph;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
@ -18,6 +19,7 @@ pub struct Linker {
output_filenames: Arc<OutputFilenames>,
// Only present when incr. comp. is enabled.
crate_hash: Option<Svh>,
metadata: EncodedMetadata,
ongoing_codegen: Box<dyn Any>,
}
@ -26,7 +28,7 @@ impl Linker {
tcx: TyCtxt<'_>,
codegen_backend: &dyn CodegenBackend,
) -> Linker {
let ongoing_codegen = passes::start_codegen(codegen_backend, tcx);
let (ongoing_codegen, metadata) = passes::start_codegen(codegen_backend, tcx);
Linker {
dep_graph: tcx.dep_graph.clone(),
@ -36,6 +38,7 @@ impl Linker {
} else {
None
},
metadata,
ongoing_codegen,
}
}
@ -75,6 +78,7 @@ impl Linker {
sess,
&rlink_file,
&codegen_results,
&self.metadata,
&*self.output_filenames,
)
.unwrap_or_else(|error| {
@ -84,6 +88,6 @@ impl Linker {
}
let _timer = sess.prof.verbose_generic_activity("link_crate");
codegen_backend.link(sess, codegen_results, &self.output_filenames)
codegen_backend.link(sess, codegen_results, self.metadata, &self.output_filenames)
}
}