mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
Rollup merge of #155036 - bjorn3:lto_refactors16, r=TaKO8Ki
Store a PathBuf rather than SerializedModule for cached modules In cg_gcc `ModuleBuffer` already only contains a path anyway. And for moving LTO into `-Zlink-only` we will need to serialize `MaybeLtoModules`. By storing a path cached modules we avoid writing them to the disk a second time during serialization of `MaybeLtoModules`. Some further improvements will require changes to cg_gcc that I would prefer landing in the cg_gcc repo to actually test the LTO changes in CI. Part of https://github.com/rust-lang/compiler-team/issues/908
This commit is contained in:
@@ -144,9 +144,12 @@ fn fat_lto(
|
||||
for module in modules {
|
||||
match module {
|
||||
FatLtoInput::InMemory(m) => in_memory.push(m),
|
||||
FatLtoInput::Serialized { name, buffer } => {
|
||||
FatLtoInput::Serialized { name, bitcode_path } => {
|
||||
info!("pushing serialized module {:?}", name);
|
||||
serialized_modules.push((buffer, CString::new(name).unwrap()));
|
||||
serialized_modules.push((
|
||||
SerializedModule::from_file(&bitcode_path),
|
||||
CString::new(name).unwrap(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,9 +223,12 @@ fn fat_lto(
|
||||
for module in modules {
|
||||
match module {
|
||||
FatLtoInput::InMemory(m) => in_memory.push(m),
|
||||
FatLtoInput::Serialized { name, buffer } => {
|
||||
FatLtoInput::Serialized { name, bitcode_path } => {
|
||||
info!("pushing serialized module {:?}", name);
|
||||
serialized_modules.push((buffer, CString::new(name).unwrap()));
|
||||
serialized_modules.push((
|
||||
SerializedModule::from_file(&bitcode_path),
|
||||
CString::new(name).unwrap(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -396,7 +399,9 @@ fn thin_lto(
|
||||
for (i, module) in modules.into_iter().enumerate() {
|
||||
let (name, buffer) = match module {
|
||||
ThinLtoInput::Red { name, buffer } => (name, buffer),
|
||||
ThinLtoInput::Green { wp, buffer } => (wp.cgu_name, buffer),
|
||||
ThinLtoInput::Green { wp, bitcode_path } => {
|
||||
(wp.cgu_name, SerializedModule::from_file(&bitcode_path))
|
||||
}
|
||||
};
|
||||
info!("local module: {} - {}", i, name);
|
||||
let cname = CString::new(name.as_bytes()).unwrap();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
use std::ffi::CString;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
@@ -49,6 +51,19 @@ pub enum SerializedModule<M: ModuleBufferMethods> {
|
||||
}
|
||||
|
||||
impl<M: ModuleBufferMethods> SerializedModule<M> {
|
||||
pub fn from_file(bc_path: &Path) -> Self {
|
||||
let file = fs::File::open(&bc_path).unwrap_or_else(|e| {
|
||||
panic!("failed to open LTO bitcode file `{}`: {}", bc_path.display(), e)
|
||||
});
|
||||
|
||||
let mmap = unsafe {
|
||||
Mmap::map(file).unwrap_or_else(|e| {
|
||||
panic!("failed to mmap LTO bitcode file `{}`: {}", bc_path.display(), e)
|
||||
})
|
||||
};
|
||||
SerializedModule::FromUncompressedFile(mmap)
|
||||
}
|
||||
|
||||
pub fn data(&self) -> &[u8] {
|
||||
match *self {
|
||||
SerializedModule::Local(ref m) => m.data(),
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
use rustc_abi::Size;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::jobserver::{self, Acquired};
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
|
||||
use rustc_errors::emitter::Emitter;
|
||||
use rustc_errors::{
|
||||
@@ -35,9 +34,8 @@
|
||||
use rustc_target::spec::{MergeFunctions, SanitizerSet};
|
||||
use tracing::debug;
|
||||
|
||||
use super::link::{self, ensure_removed};
|
||||
use super::lto::{self, SerializedModule};
|
||||
use crate::back::lto::check_lto_allowed;
|
||||
use crate::back::link::{self, ensure_removed};
|
||||
use crate::back::lto::{self, SerializedModule, check_lto_allowed};
|
||||
use crate::errors::ErrorCreatingRemarkDir;
|
||||
use crate::traits::*;
|
||||
use crate::{
|
||||
@@ -774,13 +772,13 @@ pub(crate) enum WorkItemResult<B: WriteBackendMethods> {
|
||||
}
|
||||
|
||||
pub enum FatLtoInput<B: WriteBackendMethods> {
|
||||
Serialized { name: String, buffer: SerializedModule<B::ModuleBuffer> },
|
||||
Serialized { name: String, bitcode_path: PathBuf },
|
||||
InMemory(ModuleCodegen<B::Module>),
|
||||
}
|
||||
|
||||
pub enum ThinLtoInput<B: WriteBackendMethods> {
|
||||
Red { name: String, buffer: SerializedModule<B::ModuleBuffer> },
|
||||
Green { wp: WorkProduct, buffer: SerializedModule<B::ModuleBuffer> },
|
||||
Green { wp: WorkProduct, bitcode_path: PathBuf },
|
||||
}
|
||||
|
||||
/// Actual LTO type we end up choosing based on multiple factors.
|
||||
@@ -866,7 +864,7 @@ fn execute_optimize_work_item<B: WriteBackendMethods>(
|
||||
});
|
||||
WorkItemResult::NeedsFatLto(FatLtoInput::Serialized {
|
||||
name: module.name,
|
||||
buffer: SerializedModule::Local(buffer),
|
||||
bitcode_path: path,
|
||||
})
|
||||
}
|
||||
None => WorkItemResult::NeedsFatLto(FatLtoInput::InMemory(module)),
|
||||
@@ -1166,10 +1164,7 @@ pub(crate) enum Message<B: WriteBackendMethods> {
|
||||
|
||||
/// Similar to `CodegenDone`, but for reusing a pre-LTO artifact
|
||||
/// Sent from the main thread.
|
||||
AddImportOnlyModule {
|
||||
module_data: SerializedModule<B::ModuleBuffer>,
|
||||
work_product: WorkProduct,
|
||||
},
|
||||
AddImportOnlyModule { bitcode_path: PathBuf, work_product: WorkProduct },
|
||||
|
||||
/// The frontend has finished generating everything for all codegen units.
|
||||
/// Sent from the main thread.
|
||||
@@ -1729,10 +1724,10 @@ enum CodegenState {
|
||||
}
|
||||
}
|
||||
|
||||
Message::AddImportOnlyModule { module_data, work_product } => {
|
||||
Message::AddImportOnlyModule { bitcode_path, work_product } => {
|
||||
assert_eq!(codegen_state, Ongoing);
|
||||
assert_eq!(main_thread_state, MainThreadState::Codegenning);
|
||||
lto_import_only_modules.push((module_data, work_product));
|
||||
lto_import_only_modules.push((bitcode_path, work_product));
|
||||
main_thread_state = MainThreadState::Idle;
|
||||
}
|
||||
}
|
||||
@@ -1758,8 +1753,8 @@ enum CodegenState {
|
||||
needs_fat_lto.push(FatLtoInput::InMemory(allocator_module));
|
||||
}
|
||||
|
||||
for (module, wp) in lto_import_only_modules {
|
||||
needs_fat_lto.push(FatLtoInput::Serialized { name: wp.cgu_name, buffer: module })
|
||||
for (bitcode_path, wp) in lto_import_only_modules {
|
||||
needs_fat_lto.push(FatLtoInput::Serialized { name: wp.cgu_name, bitcode_path })
|
||||
}
|
||||
|
||||
return Ok(MaybeLtoModules::FatLto {
|
||||
@@ -1772,8 +1767,8 @@ enum CodegenState {
|
||||
assert!(compiled_modules.is_empty());
|
||||
assert!(needs_fat_lto.is_empty());
|
||||
|
||||
for (buffer, wp) in lto_import_only_modules {
|
||||
needs_thin_lto.push(ThinLtoInput::Green { wp, buffer })
|
||||
for (bitcode_path, wp) in lto_import_only_modules {
|
||||
needs_thin_lto.push(ThinLtoInput::Green { wp, bitcode_path })
|
||||
}
|
||||
|
||||
if cgcx.lto == Lto::ThinLocal {
|
||||
@@ -2133,14 +2128,14 @@ fn drop(&mut self) {
|
||||
}
|
||||
|
||||
pub struct OngoingCodegen<B: WriteBackendMethods> {
|
||||
pub backend: B,
|
||||
pub output_filenames: Arc<OutputFilenames>,
|
||||
backend: B,
|
||||
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
|
||||
// `Drop` implementation for more info.
|
||||
pub coordinator: Coordinator<B>,
|
||||
pub codegen_worker_receive: Receiver<CguMessage>,
|
||||
pub shared_emitter_main: SharedEmitterMain,
|
||||
pub(crate) coordinator: Coordinator<B>,
|
||||
codegen_worker_receive: Receiver<CguMessage>,
|
||||
shared_emitter_main: SharedEmitterMain,
|
||||
}
|
||||
|
||||
impl<B: WriteBackendMethods> OngoingCodegen<B> {
|
||||
@@ -2285,20 +2280,13 @@ pub(crate) fn submit_pre_lto_module_to_llvm<B: WriteBackendMethods>(
|
||||
module: CachedModuleCodegen,
|
||||
) {
|
||||
let filename = pre_lto_bitcode_filename(&module.name);
|
||||
let bc_path = in_incr_comp_dir_sess(tcx.sess, &filename);
|
||||
let file = fs::File::open(&bc_path)
|
||||
.unwrap_or_else(|e| panic!("failed to open bitcode file `{}`: {}", bc_path.display(), e));
|
||||
|
||||
let mmap = unsafe {
|
||||
Mmap::map(file).unwrap_or_else(|e| {
|
||||
panic!("failed to mmap bitcode file `{}`: {}", bc_path.display(), e)
|
||||
})
|
||||
};
|
||||
let bitcode_path = in_incr_comp_dir_sess(tcx.sess, &filename);
|
||||
// Schedule the module to be loaded
|
||||
drop(coordinator.sender.send(Message::AddImportOnlyModule::<B> {
|
||||
module_data: SerializedModule::FromUncompressedFile(mmap),
|
||||
work_product: module.source,
|
||||
}));
|
||||
drop(
|
||||
coordinator
|
||||
.sender
|
||||
.send(Message::AddImportOnlyModule::<B> { bitcode_path, work_product: module.source }),
|
||||
);
|
||||
}
|
||||
|
||||
fn pre_lto_bitcode_filename(module_name: &str) -> String {
|
||||
|
||||
Reference in New Issue
Block a user