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 {
|
for module in modules {
|
||||||
match module {
|
match module {
|
||||||
FatLtoInput::InMemory(m) => in_memory.push(m),
|
FatLtoInput::InMemory(m) => in_memory.push(m),
|
||||||
FatLtoInput::Serialized { name, buffer } => {
|
FatLtoInput::Serialized { name, bitcode_path } => {
|
||||||
info!("pushing serialized module {:?}", name);
|
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 {
|
for module in modules {
|
||||||
match module {
|
match module {
|
||||||
FatLtoInput::InMemory(m) => in_memory.push(m),
|
FatLtoInput::InMemory(m) => in_memory.push(m),
|
||||||
FatLtoInput::Serialized { name, buffer } => {
|
FatLtoInput::Serialized { name, bitcode_path } => {
|
||||||
info!("pushing serialized module {:?}", name);
|
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() {
|
for (i, module) in modules.into_iter().enumerate() {
|
||||||
let (name, buffer) = match module {
|
let (name, buffer) = match module {
|
||||||
ThinLtoInput::Red { name, buffer } => (name, buffer),
|
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);
|
info!("local module: {} - {}", i, name);
|
||||||
let cname = CString::new(name.as_bytes()).unwrap();
|
let cname = CString::new(name.as_bytes()).unwrap();
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use rustc_data_structures::memmap::Mmap;
|
use rustc_data_structures::memmap::Mmap;
|
||||||
@@ -49,6 +51,19 @@ pub enum SerializedModule<M: ModuleBufferMethods> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<M: ModuleBufferMethods> SerializedModule<M> {
|
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] {
|
pub fn data(&self) -> &[u8] {
|
||||||
match *self {
|
match *self {
|
||||||
SerializedModule::Local(ref m) => m.data(),
|
SerializedModule::Local(ref m) => m.data(),
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
use rustc_abi::Size;
|
use rustc_abi::Size;
|
||||||
use rustc_data_structures::fx::FxIndexMap;
|
use rustc_data_structures::fx::FxIndexMap;
|
||||||
use rustc_data_structures::jobserver::{self, Acquired};
|
use rustc_data_structures::jobserver::{self, Acquired};
|
||||||
use rustc_data_structures::memmap::Mmap;
|
|
||||||
use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
|
use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
|
||||||
use rustc_errors::emitter::Emitter;
|
use rustc_errors::emitter::Emitter;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
@@ -35,9 +34,8 @@
|
|||||||
use rustc_target::spec::{MergeFunctions, SanitizerSet};
|
use rustc_target::spec::{MergeFunctions, SanitizerSet};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use super::link::{self, ensure_removed};
|
use crate::back::link::{self, ensure_removed};
|
||||||
use super::lto::{self, SerializedModule};
|
use crate::back::lto::{self, SerializedModule, check_lto_allowed};
|
||||||
use crate::back::lto::check_lto_allowed;
|
|
||||||
use crate::errors::ErrorCreatingRemarkDir;
|
use crate::errors::ErrorCreatingRemarkDir;
|
||||||
use crate::traits::*;
|
use crate::traits::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -774,13 +772,13 @@ pub(crate) enum WorkItemResult<B: WriteBackendMethods> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum FatLtoInput<B: WriteBackendMethods> {
|
pub enum FatLtoInput<B: WriteBackendMethods> {
|
||||||
Serialized { name: String, buffer: SerializedModule<B::ModuleBuffer> },
|
Serialized { name: String, bitcode_path: PathBuf },
|
||||||
InMemory(ModuleCodegen<B::Module>),
|
InMemory(ModuleCodegen<B::Module>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ThinLtoInput<B: WriteBackendMethods> {
|
pub enum ThinLtoInput<B: WriteBackendMethods> {
|
||||||
Red { name: String, buffer: SerializedModule<B::ModuleBuffer> },
|
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.
|
/// 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 {
|
WorkItemResult::NeedsFatLto(FatLtoInput::Serialized {
|
||||||
name: module.name,
|
name: module.name,
|
||||||
buffer: SerializedModule::Local(buffer),
|
bitcode_path: path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
None => WorkItemResult::NeedsFatLto(FatLtoInput::InMemory(module)),
|
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
|
/// Similar to `CodegenDone`, but for reusing a pre-LTO artifact
|
||||||
/// Sent from the main thread.
|
/// Sent from the main thread.
|
||||||
AddImportOnlyModule {
|
AddImportOnlyModule { bitcode_path: PathBuf, work_product: WorkProduct },
|
||||||
module_data: SerializedModule<B::ModuleBuffer>,
|
|
||||||
work_product: WorkProduct,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// The frontend has finished generating everything for all codegen units.
|
/// The frontend has finished generating everything for all codegen units.
|
||||||
/// Sent from the main thread.
|
/// 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!(codegen_state, Ongoing);
|
||||||
assert_eq!(main_thread_state, MainThreadState::Codegenning);
|
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;
|
main_thread_state = MainThreadState::Idle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1758,8 +1753,8 @@ enum CodegenState {
|
|||||||
needs_fat_lto.push(FatLtoInput::InMemory(allocator_module));
|
needs_fat_lto.push(FatLtoInput::InMemory(allocator_module));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (module, wp) in lto_import_only_modules {
|
for (bitcode_path, wp) in lto_import_only_modules {
|
||||||
needs_fat_lto.push(FatLtoInput::Serialized { name: wp.cgu_name, buffer: module })
|
needs_fat_lto.push(FatLtoInput::Serialized { name: wp.cgu_name, bitcode_path })
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(MaybeLtoModules::FatLto {
|
return Ok(MaybeLtoModules::FatLto {
|
||||||
@@ -1772,8 +1767,8 @@ enum CodegenState {
|
|||||||
assert!(compiled_modules.is_empty());
|
assert!(compiled_modules.is_empty());
|
||||||
assert!(needs_fat_lto.is_empty());
|
assert!(needs_fat_lto.is_empty());
|
||||||
|
|
||||||
for (buffer, wp) in lto_import_only_modules {
|
for (bitcode_path, wp) in lto_import_only_modules {
|
||||||
needs_thin_lto.push(ThinLtoInput::Green { wp, buffer })
|
needs_thin_lto.push(ThinLtoInput::Green { wp, bitcode_path })
|
||||||
}
|
}
|
||||||
|
|
||||||
if cgcx.lto == Lto::ThinLocal {
|
if cgcx.lto == Lto::ThinLocal {
|
||||||
@@ -2133,14 +2128,14 @@ fn drop(&mut self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct OngoingCodegen<B: WriteBackendMethods> {
|
pub struct OngoingCodegen<B: WriteBackendMethods> {
|
||||||
pub backend: B,
|
backend: B,
|
||||||
pub output_filenames: Arc<OutputFilenames>,
|
output_filenames: Arc<OutputFilenames>,
|
||||||
// Field order below is intended to terminate the coordinator thread before two fields below
|
// 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 and prematurely close channels used by coordinator thread. See `Coordinator`'s
|
||||||
// `Drop` implementation for more info.
|
// `Drop` implementation for more info.
|
||||||
pub coordinator: Coordinator<B>,
|
pub(crate) coordinator: Coordinator<B>,
|
||||||
pub codegen_worker_receive: Receiver<CguMessage>,
|
codegen_worker_receive: Receiver<CguMessage>,
|
||||||
pub shared_emitter_main: SharedEmitterMain,
|
shared_emitter_main: SharedEmitterMain,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: WriteBackendMethods> OngoingCodegen<B> {
|
impl<B: WriteBackendMethods> OngoingCodegen<B> {
|
||||||
@@ -2285,20 +2280,13 @@ pub(crate) fn submit_pre_lto_module_to_llvm<B: WriteBackendMethods>(
|
|||||||
module: CachedModuleCodegen,
|
module: CachedModuleCodegen,
|
||||||
) {
|
) {
|
||||||
let filename = pre_lto_bitcode_filename(&module.name);
|
let filename = pre_lto_bitcode_filename(&module.name);
|
||||||
let bc_path = in_incr_comp_dir_sess(tcx.sess, &filename);
|
let bitcode_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)
|
|
||||||
})
|
|
||||||
};
|
|
||||||
// Schedule the module to be loaded
|
// Schedule the module to be loaded
|
||||||
drop(coordinator.sender.send(Message::AddImportOnlyModule::<B> {
|
drop(
|
||||||
module_data: SerializedModule::FromUncompressedFile(mmap),
|
coordinator
|
||||||
work_product: module.source,
|
.sender
|
||||||
}));
|
.send(Message::AddImportOnlyModule::<B> { bitcode_path, work_product: module.source }),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pre_lto_bitcode_filename(module_name: &str) -> String {
|
fn pre_lto_bitcode_filename(module_name: &str) -> String {
|
||||||
|
|||||||
Reference in New Issue
Block a user