Skip to content

Commit 36de1f8

Browse files
Auto merge of #145893 - bjorn3:lto_less_copying, r=<try>
Avoid copying the bitcode out of rlibs
2 parents 5ab6924 + 53eed7c commit 36de1f8

File tree

4 files changed

+34
-34
lines changed

4 files changed

+34
-34
lines changed

compiler/rustc_codegen_gcc/src/back/lto.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,7 @@ fn fat_lto(
234234
.context
235235
.add_driver_option(module_buffer.0.to_str().expect("path"));
236236
}
237-
SerializedModule::FromRlib(_) => unimplemented!("from rlib"),
238-
SerializedModule::FromUncompressedFile(_) => {
239-
unimplemented!("from uncompressed file")
240-
}
237+
SerializedModule::FromFile(_) => unimplemented!("from file"),
241238
}
242239
}
243240
save_temp_bitcode(cgcx, &module, "lto.input");
@@ -417,10 +414,7 @@ fn thin_lto(
417414
.context
418415
.add_driver_option(module_buffer.0.to_str().expect("path"));*/
419416
}
420-
SerializedModule::FromRlib(_) => unimplemented!("from rlib"),
421-
SerializedModule::FromUncompressedFile(_) => {
422-
unimplemented!("from uncompressed file")
423-
}
417+
SerializedModule::FromFile(_) => unimplemented!("from file"),
424418
}
425419

426420
serialized.push(module);
@@ -554,10 +548,7 @@ pub fn optimize_thin_module(
554548
.context
555549
.add_driver_option(module_buffer.0.to_str().expect("path"));*/
556550
}
557-
SerializedModule::FromRlib(_) => unimplemented!("from rlib"),
558-
SerializedModule::FromUncompressedFile(_) => {
559-
unimplemented!("from uncompressed file")
560-
}
551+
SerializedModule::FromFile(_) => unimplemented!("from file"),
561552
}
562553
Arc::new(SyncContext::new(context))
563554
}

compiler/rustc_codegen_llvm/src/back/lto.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_codegen_ssa::traits::*;
1414
use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file};
1515
use rustc_data_structures::fx::FxHashMap;
1616
use rustc_data_structures::memmap::Mmap;
17+
use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned};
1718
use rustc_errors::DiagCtxtHandle;
1819
use rustc_middle::bug;
1920
use rustc_middle::dep_graph::WorkProduct;
@@ -56,10 +57,13 @@ fn prepare_lto(
5657
let mut upstream_modules = Vec::new();
5758
if cgcx.lto != Lto::ThinLocal {
5859
for path in each_linked_rlib_for_lto {
59-
let archive_data = unsafe {
60-
Mmap::map(std::fs::File::open(&path).expect("couldn't open rlib"))
61-
.expect("couldn't map rlib")
62-
};
60+
let archive_data = slice_owned(
61+
unsafe {
62+
Mmap::map(std::fs::File::open(&path).expect("couldn't open rlib"))
63+
.expect("couldn't map rlib")
64+
},
65+
|data| &*data,
66+
);
6367
let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib");
6468
let obj_files = archive
6569
.members()
@@ -71,12 +75,14 @@ fn prepare_lto(
7175
.filter(|&(name, _)| looks_like_rust_object_file(name));
7276
for (name, child) in obj_files {
7377
info!("adding bitcode from {}", name);
74-
match get_bitcode_slice_from_object_data(
75-
child.data(&*archive_data).expect("corrupt rlib"),
76-
cgcx,
77-
) {
78+
let (offset, size) = child.file_range();
79+
let child_data = archive_data.clone().slice(|data| {
80+
data.get(offset as usize..offset as usize + size as usize)
81+
.expect("corrupt rlib")
82+
});
83+
match get_bitcode_slice_from_object_data(child_data, cgcx) {
7884
Ok(data) => {
79-
let module = SerializedModule::FromRlib(data.to_vec());
85+
let module = SerializedModule::FromFile(data);
8086
upstream_modules.push((module, CString::new(name).unwrap()));
8187
}
8288
Err(e) => dcx.emit_fatal(e),
@@ -88,29 +94,33 @@ fn prepare_lto(
8894
(symbols_below_threshold, upstream_modules)
8995
}
9096

91-
fn get_bitcode_slice_from_object_data<'a>(
92-
obj: &'a [u8],
97+
fn get_bitcode_slice_from_object_data(
98+
data: OwnedSlice,
9399
cgcx: &CodegenContext<LlvmCodegenBackend>,
94-
) -> Result<&'a [u8], LtoBitcodeFromRlib> {
100+
) -> Result<OwnedSlice, LtoBitcodeFromRlib> {
95101
// We're about to assume the data here is an object file with sections, but if it's raw LLVM IR
96102
// that won't work. Fortunately, if that's what we have we can just return the object directly,
97103
// so we sniff the relevant magic strings here and return.
98-
if obj.starts_with(b"\xDE\xC0\x17\x0B") || obj.starts_with(b"BC\xC0\xDE") {
99-
return Ok(obj);
104+
if data.starts_with(b"\xDE\xC0\x17\x0B") || data.starts_with(b"BC\xC0\xDE") {
105+
return Ok(data);
100106
}
101107
// We drop the "__LLVM," prefix here because on Apple platforms there's a notion of "segment
102108
// name" which in the public API for sections gets treated as part of the section name, but
103109
// internally in MachOObjectFile.cpp gets treated separately.
104110
let section_name = bitcode_section_name(cgcx).to_str().unwrap().trim_start_matches("__LLVM,");
105111

106112
let obj =
107-
object::File::parse(obj).map_err(|err| LtoBitcodeFromRlib { err: err.to_string() })?;
113+
object::File::parse(&*data).map_err(|err| LtoBitcodeFromRlib { err: err.to_string() })?;
108114

109115
let section = obj
110116
.section_by_name(section_name)
111117
.ok_or_else(|| LtoBitcodeFromRlib { err: format!("Can't find section {section_name}") })?;
112118

113-
section.data().map_err(|err| LtoBitcodeFromRlib { err: err.to_string() })
119+
if let Some((offset, size)) = section.file_range() {
120+
Ok(data.slice(|data| &data[offset as usize..offset as usize + size as usize]))
121+
} else {
122+
Err(LtoBitcodeFromRlib { err: format!("Section {section_name} doesn't have contents") })
123+
}
114124
}
115125

116126
/// Performs fat LTO by merging all modules into a single one and returning it

compiler/rustc_codegen_ssa/src/back/lto.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::ffi::CString;
22
use std::sync::Arc;
33

4-
use rustc_data_structures::memmap::Mmap;
4+
use rustc_data_structures::owned_slice::OwnedSlice;
55
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
66
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportLevel};
77
use rustc_middle::ty::TyCtxt;
@@ -47,16 +47,14 @@ pub struct ThinShared<B: WriteBackendMethods> {
4747

4848
pub enum SerializedModule<M: ModuleBufferMethods> {
4949
Local(M),
50-
FromRlib(Vec<u8>),
51-
FromUncompressedFile(Mmap),
50+
FromFile(OwnedSlice),
5251
}
5352

5453
impl<M: ModuleBufferMethods> SerializedModule<M> {
5554
pub fn data(&self) -> &[u8] {
5655
match *self {
5756
SerializedModule::Local(ref m) => m.data(),
58-
SerializedModule::FromRlib(ref m) => m,
59-
SerializedModule::FromUncompressedFile(ref m) => m,
57+
SerializedModule::FromFile(ref m) => m,
6058
}
6159
}
6260
}

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_ast::attr;
1111
use rustc_data_structures::fx::FxIndexMap;
1212
use rustc_data_structures::jobserver::{self, Acquired};
1313
use rustc_data_structures::memmap::Mmap;
14+
use rustc_data_structures::owned_slice::slice_owned;
1415
use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
1516
use rustc_errors::emitter::Emitter;
1617
use rustc_errors::translation::Translator;
@@ -2061,7 +2062,7 @@ pub(crate) fn submit_pre_lto_module_to_llvm<B: ExtraBackendMethods>(
20612062
};
20622063
// Schedule the module to be loaded
20632064
drop(coordinator.sender.send(Message::AddImportOnlyModule::<B> {
2064-
module_data: SerializedModule::FromUncompressedFile(mmap),
2065+
module_data: SerializedModule::FromFile(slice_owned(mmap, |mmap| &*mmap)),
20652066
work_product: module.source,
20662067
}));
20672068
}

0 commit comments

Comments
 (0)