mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Move some thin local LTO handling to start_executing_work
By not pushing any crates to each_linked_rlib_for_lto when no cross-crate LTO is used, we can avoid special cases elsewhere.
This commit is contained in:
@@ -31,7 +31,6 @@
|
||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
||||
use rustc_errors::{DiagCtxt, DiagCtxtHandle};
|
||||
use rustc_log::tracing::info;
|
||||
use rustc_session::config::Lto;
|
||||
use tempfile::{TempDir, tempdir};
|
||||
|
||||
use crate::back::write::{codegen, save_temp_bitcode};
|
||||
@@ -45,11 +44,7 @@ struct LtoData {
|
||||
tmp_path: TempDir,
|
||||
}
|
||||
|
||||
fn prepare_lto(
|
||||
cgcx: &CodegenContext,
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
) -> LtoData {
|
||||
fn prepare_lto(each_linked_rlib_for_lto: &[PathBuf], dcx: DiagCtxtHandle<'_>) -> LtoData {
|
||||
let tmp_path = match tempdir() {
|
||||
Ok(tmp_path) => tmp_path,
|
||||
Err(error) => {
|
||||
@@ -64,32 +59,30 @@ fn prepare_lto(
|
||||
// We save off all the bytecode and GCC module file path for later processing
|
||||
// with either fat or thin LTO
|
||||
let mut upstream_modules = Vec::new();
|
||||
if cgcx.lto != Lto::ThinLocal {
|
||||
for path in each_linked_rlib_for_lto {
|
||||
let archive_data = unsafe {
|
||||
Mmap::map(File::open(path).expect("couldn't open rlib")).expect("couldn't map rlib")
|
||||
};
|
||||
let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib");
|
||||
let obj_files = archive
|
||||
.members()
|
||||
.filter_map(|child| {
|
||||
child.ok().and_then(|c| {
|
||||
std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c))
|
||||
})
|
||||
})
|
||||
.filter(|&(name, _)| looks_like_rust_object_file(name));
|
||||
for (name, child) in obj_files {
|
||||
info!("adding bitcode from {}", name);
|
||||
let path = tmp_path.path().join(name);
|
||||
match save_as_file(child.data(&*archive_data).expect("corrupt rlib"), &path) {
|
||||
Ok(()) => {
|
||||
let buffer = ModuleBuffer::new(path);
|
||||
let module = SerializedModule::Local(buffer);
|
||||
upstream_modules.push((module, CString::new(name).unwrap()));
|
||||
}
|
||||
Err(e) => {
|
||||
dcx.emit_fatal(e);
|
||||
}
|
||||
for path in each_linked_rlib_for_lto {
|
||||
let archive_data = unsafe {
|
||||
Mmap::map(File::open(path).expect("couldn't open rlib")).expect("couldn't map rlib")
|
||||
};
|
||||
let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib");
|
||||
let obj_files = archive
|
||||
.members()
|
||||
.filter_map(|child| {
|
||||
child
|
||||
.ok()
|
||||
.and_then(|c| std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c)))
|
||||
})
|
||||
.filter(|&(name, _)| looks_like_rust_object_file(name));
|
||||
for (name, child) in obj_files {
|
||||
info!("adding bitcode from {}", name);
|
||||
let path = tmp_path.path().join(name);
|
||||
match save_as_file(child.data(&*archive_data).expect("corrupt rlib"), &path) {
|
||||
Ok(()) => {
|
||||
let buffer = ModuleBuffer::new(path);
|
||||
let module = SerializedModule::Local(buffer);
|
||||
upstream_modules.push((module, CString::new(name).unwrap()));
|
||||
}
|
||||
Err(e) => {
|
||||
dcx.emit_fatal(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,7 +108,7 @@ pub(crate) fn run_fat(
|
||||
) -> CompiledModule {
|
||||
let dcx = DiagCtxt::new(Box::new(shared_emitter.clone()));
|
||||
let dcx = dcx.handle();
|
||||
let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx);
|
||||
let lto_data = prepare_lto(each_linked_rlib_for_lto, dcx);
|
||||
/*let symbols_below_threshold =
|
||||
lto_data.symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();*/
|
||||
fat_lto(
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
use rustc_hir::attrs::SanitizerSet;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::dep_graph::WorkProduct;
|
||||
use rustc_session::config::{self, Lto};
|
||||
use rustc_session::config;
|
||||
use tracing::{debug, info};
|
||||
|
||||
use crate::back::write::{
|
||||
@@ -90,33 +90,31 @@ fn prepare_lto(
|
||||
// We save off all the bytecode and LLVM module ids for later processing
|
||||
// with either fat or thin LTO
|
||||
let mut upstream_modules = Vec::new();
|
||||
if cgcx.lto != Lto::ThinLocal {
|
||||
for path in each_linked_rlib_for_lto {
|
||||
let archive_data = unsafe {
|
||||
Mmap::map(std::fs::File::open(&path).expect("couldn't open rlib"))
|
||||
.expect("couldn't map rlib")
|
||||
};
|
||||
let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib");
|
||||
let obj_files = archive
|
||||
.members()
|
||||
.filter_map(|child| {
|
||||
child.ok().and_then(|c| {
|
||||
std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c))
|
||||
})
|
||||
})
|
||||
.filter(|&(name, _)| looks_like_rust_object_file(name));
|
||||
for (name, child) in obj_files {
|
||||
info!("adding bitcode from {}", name);
|
||||
match get_bitcode_slice_from_object_data(
|
||||
child.data(&*archive_data).expect("corrupt rlib"),
|
||||
cgcx,
|
||||
) {
|
||||
Ok(data) => {
|
||||
let module = SerializedModule::FromRlib(data.to_vec());
|
||||
upstream_modules.push((module, CString::new(name).unwrap()));
|
||||
}
|
||||
Err(e) => dcx.emit_fatal(e),
|
||||
for path in each_linked_rlib_for_lto {
|
||||
let archive_data = unsafe {
|
||||
Mmap::map(std::fs::File::open(&path).expect("couldn't open rlib"))
|
||||
.expect("couldn't map rlib")
|
||||
};
|
||||
let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib");
|
||||
let obj_files = archive
|
||||
.members()
|
||||
.filter_map(|child| {
|
||||
child
|
||||
.ok()
|
||||
.and_then(|c| std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c)))
|
||||
})
|
||||
.filter(|&(name, _)| looks_like_rust_object_file(name));
|
||||
for (name, child) in obj_files {
|
||||
info!("adding bitcode from {}", name);
|
||||
match get_bitcode_slice_from_object_data(
|
||||
child.data(&*archive_data).expect("corrupt rlib"),
|
||||
cgcx,
|
||||
) {
|
||||
Ok(data) => {
|
||||
let module = SerializedModule::FromRlib(data.to_vec());
|
||||
upstream_modules.push((module, CString::new(name).unwrap()));
|
||||
}
|
||||
Err(e) => dcx.emit_fatal(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,11 +110,9 @@ pub(super) fn exported_symbols_for_lto(
|
||||
|
||||
// If we're performing LTO for the entire crate graph, then for each of our
|
||||
// upstream dependencies, include their exported symbols.
|
||||
if tcx.sess.lto() != Lto::ThinLocal {
|
||||
for &cnum in each_linked_rlib_for_lto {
|
||||
let _timer = tcx.prof.generic_activity("lto_generate_symbols_below_threshold");
|
||||
symbols_below_threshold.extend(copy_symbols(cnum));
|
||||
}
|
||||
for &cnum in each_linked_rlib_for_lto {
|
||||
let _timer = tcx.prof.generic_activity("lto_generate_symbols_below_threshold");
|
||||
symbols_below_threshold.extend(copy_symbols(cnum));
|
||||
}
|
||||
|
||||
// Mark allocator shim symbols as exported only if they were generated.
|
||||
|
||||
@@ -1264,13 +1264,16 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
||||
|
||||
let mut each_linked_rlib_for_lto = Vec::new();
|
||||
let mut each_linked_rlib_file_for_lto = Vec::new();
|
||||
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());
|
||||
}));
|
||||
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)
|
||||
let exported_symbols_for_lto =
|
||||
|
||||
Reference in New Issue
Block a user