Skip to content

Commit a4404b1

Browse files
committed
Auto merge of #152670 - bjorn3:lto_refactors12, r=<try>
Simplify ThinLTO handling
2 parents eeb94be + 3decb52 commit a4404b1

12 files changed

Lines changed: 95 additions & 205 deletions

File tree

compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,7 @@ use rustc_codegen_ssa::back::write::{
8686
};
8787
use rustc_codegen_ssa::base::codegen_crate;
8888
use rustc_codegen_ssa::target_features::cfg_target_feature;
89-
use rustc_codegen_ssa::traits::{
90-
CodegenBackend, ExtraBackendMethods, ThinBufferMethods, WriteBackendMethods,
91-
};
89+
use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods};
9290
use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig};
9391
use rustc_data_structures::fx::FxIndexMap;
9492
use rustc_data_structures::profiling::SelfProfilerRef;
@@ -423,20 +421,11 @@ unsafe impl Send for SyncContext {}
423421
// FIXME(antoyo): that shouldn't be Sync. Parallel compilation is currently disabled with "CodegenBackend::supports_parallel()".
424422
unsafe impl Sync for SyncContext {}
425423

426-
pub struct ThinBuffer;
427-
428-
impl ThinBufferMethods for ThinBuffer {
429-
fn data(&self) -> &[u8] {
430-
&[]
431-
}
432-
}
433-
434424
impl WriteBackendMethods for GccCodegenBackend {
435425
type Module = GccContext;
436426
type TargetMachine = ();
437427
type ModuleBuffer = ModuleBuffer;
438428
type ThinData = ();
439-
type ThinBuffer = ThinBuffer;
440429

441430
fn run_and_optimize_fat_lto(
442431
cgcx: &CodegenContext,
@@ -458,7 +447,7 @@ impl WriteBackendMethods for GccCodegenBackend {
458447
// FIXME(bjorn3): Limit LTO exports to these symbols
459448
_exported_symbols_for_lto: &[String],
460449
_each_linked_rlib_for_lto: &[PathBuf],
461-
_modules: Vec<(String, Self::ThinBuffer)>,
450+
_modules: Vec<(String, Self::ModuleBuffer)>,
462451
_cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
463452
) -> (Vec<ThinModule<Self>>, Vec<WorkProduct>) {
464453
unreachable!()
@@ -502,11 +491,7 @@ impl WriteBackendMethods for GccCodegenBackend {
502491
back::write::codegen(cgcx, prof, shared_emitter, module, config)
503492
}
504493

505-
fn prepare_thin(_module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer) {
506-
unreachable!()
507-
}
508-
509-
fn serialize_module(_module: ModuleCodegen<Self::Module>) -> (String, Self::ModuleBuffer) {
494+
fn serialize_module(_module: Self::Module, _is_thin: bool) -> Self::ModuleBuffer {
510495
unimplemented!();
511496
}
512497
}

compiler/rustc_codegen_llvm/src/back/lto.rs

Lines changed: 26 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use std::collections::BTreeMap;
22
use std::ffi::{CStr, CString};
33
use std::fs::File;
44
use std::path::{Path, PathBuf};
5-
use std::ptr::NonNull;
65
use std::sync::Arc;
76
use std::{io, iter, slice};
87

@@ -187,7 +186,7 @@ pub(crate) fn run_thin(
187186
dcx: DiagCtxtHandle<'_>,
188187
exported_symbols_for_lto: &[String],
189188
each_linked_rlib_for_lto: &[PathBuf],
190-
modules: Vec<(String, ThinBuffer)>,
189+
modules: Vec<(String, ModuleBuffer)>,
191190
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
192191
) -> (Vec<ThinModule<LlvmCodegenBackend>>, Vec<WorkProduct>) {
193192
let (symbols_below_threshold, upstream_modules) =
@@ -203,12 +202,6 @@ pub(crate) fn run_thin(
203202
thin_lto(cgcx, prof, dcx, modules, upstream_modules, cached_modules, &symbols_below_threshold)
204203
}
205204

206-
pub(crate) fn prepare_thin(module: ModuleCodegen<ModuleLlvm>) -> (String, ThinBuffer) {
207-
let name = module.name;
208-
let buffer = ThinBuffer::new(module.module_llvm.llmod(), true);
209-
(name, buffer)
210-
}
211-
212205
fn fat_lto(
213206
cgcx: &CodegenContext,
214207
prof: &SelfProfilerRef,
@@ -297,7 +290,7 @@ fn fat_lto(
297290
// way we know of to do that is to serialize them to a string and them parse
298291
// them later. Not great but hey, that's why it's "fat" LTO, right?
299292
for module in in_memory {
300-
let buffer = ModuleBuffer::new(module.module_llvm.llmod());
293+
let buffer = ModuleBuffer::new(module.module_llvm.llmod(), false);
301294
let llmod_id = CString::new(&module.name[..]).unwrap();
302295
serialized_modules.push((SerializedModule::Local(buffer), llmod_id));
303296
}
@@ -400,7 +393,7 @@ fn thin_lto(
400393
cgcx: &CodegenContext,
401394
prof: &SelfProfilerRef,
402395
dcx: DiagCtxtHandle<'_>,
403-
modules: Vec<(String, ThinBuffer)>,
396+
modules: Vec<(String, ModuleBuffer)>,
404397
serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
405398
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
406399
symbols_below_threshold: &[*const libc::c_char],
@@ -634,7 +627,9 @@ pub(crate) fn run_pass_manager(
634627
};
635628

636629
unsafe {
637-
write::llvm_optimize(cgcx, prof, dcx, module, None, config, opt_level, opt_stage, stage);
630+
write::llvm_optimize(
631+
cgcx, prof, dcx, module, None, None, config, opt_level, opt_stage, stage,
632+
);
638633
}
639634

640635
if cfg!(feature = "llvm_enzyme") && enable_ad && !thin {
@@ -643,7 +638,7 @@ pub(crate) fn run_pass_manager(
643638
if !config.autodiff.contains(&config::AutoDiff::NoPostopt) {
644639
unsafe {
645640
write::llvm_optimize(
646-
cgcx, prof, dcx, module, None, config, opt_level, opt_stage, stage,
641+
cgcx, prof, dcx, module, None, None, config, opt_level, opt_stage, stage,
647642
);
648643
}
649644
}
@@ -658,31 +653,26 @@ pub(crate) fn run_pass_manager(
658653
debug!("lto done");
659654
}
660655

661-
pub struct ModuleBuffer(&'static mut llvm::ModuleBuffer);
662-
663-
unsafe impl Send for ModuleBuffer {}
664-
unsafe impl Sync for ModuleBuffer {}
656+
#[repr(transparent)]
657+
pub(crate) struct Buffer(&'static mut llvm::Buffer);
665658

666-
impl ModuleBuffer {
667-
pub(crate) fn new(m: &llvm::Module) -> ModuleBuffer {
668-
ModuleBuffer(unsafe { llvm::LLVMRustModuleBufferCreate(m) })
669-
}
670-
}
659+
unsafe impl Send for Buffer {}
660+
unsafe impl Sync for Buffer {}
671661

672-
impl ModuleBufferMethods for ModuleBuffer {
673-
fn data(&self) -> &[u8] {
662+
impl Buffer {
663+
pub(crate) fn data(&self) -> &[u8] {
674664
unsafe {
675-
let ptr = llvm::LLVMRustModuleBufferPtr(self.0);
676-
let len = llvm::LLVMRustModuleBufferLen(self.0);
665+
let ptr = llvm::LLVMRustBufferPtr(self.0);
666+
let len = llvm::LLVMRustBufferLen(self.0);
677667
slice::from_raw_parts(ptr, len)
678668
}
679669
}
680670
}
681671

682-
impl Drop for ModuleBuffer {
672+
impl Drop for Buffer {
683673
fn drop(&mut self) {
684674
unsafe {
685-
llvm::LLVMRustModuleBufferFree(&mut *(self.0 as *mut _));
675+
llvm::LLVMRustBufferFree(&mut *(self.0 as *mut _));
686676
}
687677
}
688678
}
@@ -700,48 +690,22 @@ impl Drop for ThinData {
700690
}
701691
}
702692

703-
pub struct ThinBuffer(&'static mut llvm::ThinLTOBuffer);
704-
705-
unsafe impl Send for ThinBuffer {}
706-
unsafe impl Sync for ThinBuffer {}
707-
708-
impl ThinBuffer {
709-
pub(crate) fn new(m: &llvm::Module, is_thin: bool) -> ThinBuffer {
710-
unsafe {
711-
let buffer = llvm::LLVMRustThinLTOBufferCreate(m, is_thin);
712-
ThinBuffer(buffer)
713-
}
714-
}
715-
716-
pub(crate) unsafe fn from_raw_ptr(ptr: *mut llvm::ThinLTOBuffer) -> ThinBuffer {
717-
let mut ptr = NonNull::new(ptr).unwrap();
718-
ThinBuffer(unsafe { ptr.as_mut() })
719-
}
720-
721-
pub(crate) fn thin_link_data(&self) -> &[u8] {
722-
unsafe {
723-
let ptr = llvm::LLVMRustThinLTOBufferThinLinkDataPtr(self.0) as *const _;
724-
let len = llvm::LLVMRustThinLTOBufferThinLinkDataLen(self.0);
725-
slice::from_raw_parts(ptr, len)
726-
}
727-
}
693+
pub struct ModuleBuffer {
694+
data: Buffer,
728695
}
729696

730-
impl ThinBufferMethods for ThinBuffer {
731-
fn data(&self) -> &[u8] {
697+
impl ModuleBuffer {
698+
pub(crate) fn new(m: &llvm::Module, is_thin: bool) -> ModuleBuffer {
732699
unsafe {
733-
let ptr = llvm::LLVMRustThinLTOBufferPtr(self.0) as *const _;
734-
let len = llvm::LLVMRustThinLTOBufferLen(self.0);
735-
slice::from_raw_parts(ptr, len)
700+
let buffer = llvm::LLVMRustModuleSerialize(m, is_thin);
701+
ModuleBuffer { data: Buffer(buffer) }
736702
}
737703
}
738704
}
739705

740-
impl Drop for ThinBuffer {
741-
fn drop(&mut self) {
742-
unsafe {
743-
llvm::LLVMRustThinLTOBufferFree(&mut *(self.0 as *mut _));
744-
}
706+
impl ModuleBufferMethods for ModuleBuffer {
707+
fn data(&self) -> &[u8] {
708+
self.data.data()
745709
}
746710
}
747711

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::ffi::{CStr, CString};
22
use std::io::{self, Write};
33
use std::path::{Path, PathBuf};
4-
use std::ptr::null_mut;
54
use std::sync::Arc;
65
use std::{fs, slice, str};
76

@@ -29,7 +28,7 @@ use rustc_target::spec::{
2928
};
3029
use tracing::{debug, trace};
3130

32-
use crate::back::lto::ThinBuffer;
31+
use crate::back::lto::{Buffer, ModuleBuffer};
3332
use crate::back::owned_target_machine::OwnedTargetMachine;
3433
use crate::back::profiling::{
3534
LlvmSelfProfiler, selfprofile_after_pass_callback, selfprofile_before_pass_callback,
@@ -563,7 +562,8 @@ pub(crate) unsafe fn llvm_optimize(
563562
prof: &SelfProfilerRef,
564563
dcx: DiagCtxtHandle<'_>,
565564
module: &ModuleCodegen<ModuleLlvm>,
566-
thin_lto_buffer: Option<&mut *mut llvm::ThinLTOBuffer>,
565+
thin_lto_buffer: Option<&mut Option<Buffer>>,
566+
thin_lto_summary_buffer: Option<&mut Option<Buffer>>,
567567
config: &ModuleConfig,
568568
opt_level: config::OptLevel,
569569
opt_stage: llvm::OptStage,
@@ -786,7 +786,7 @@ pub(crate) unsafe fn llvm_optimize(
786786
config.verify_llvm_ir,
787787
config.lint_llvm_ir,
788788
thin_lto_buffer,
789-
config.emit_thin_lto_summary,
789+
thin_lto_summary_buffer,
790790
merge_functions,
791791
unroll_loops,
792792
vectorize_slp,
@@ -932,13 +932,14 @@ pub(crate) fn optimize(
932932
// The bitcode obtained during the `codegen` phase is no longer suitable for performing LTO.
933933
// It may have undergone LTO due to ThinLocal, so we need to obtain the embedded bitcode at
934934
// this point.
935-
let mut thin_lto_buffer = if (module.kind == ModuleKind::Regular
935+
let (mut thin_lto_buffer, mut thin_lto_summary_buffer) = if (module.kind
936+
== ModuleKind::Regular
936937
&& config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full))
937938
|| config.emit_thin_lto_summary
938939
{
939-
Some(null_mut())
940+
(Some(None), config.emit_thin_lto_summary.then_some(None))
940941
} else {
941-
None
942+
(None, None)
942943
};
943944
unsafe {
944945
llvm_optimize(
@@ -947,24 +948,26 @@ pub(crate) fn optimize(
947948
dcx,
948949
module,
949950
thin_lto_buffer.as_mut(),
951+
thin_lto_summary_buffer.as_mut(),
950952
config,
951953
opt_level,
952954
opt_stage,
953955
autodiff_stage,
954956
)
955957
};
956958
if let Some(thin_lto_buffer) = thin_lto_buffer {
957-
let thin_lto_buffer = unsafe { ThinBuffer::from_raw_ptr(thin_lto_buffer) };
959+
let thin_lto_buffer = thin_lto_buffer.unwrap();
958960
module.thin_lto_buffer = Some(thin_lto_buffer.data().to_vec());
959961
let bc_summary_out = cgcx.output_filenames.temp_path_for_cgu(
960962
OutputType::ThinLinkBitcode,
961963
&module.name,
962964
cgcx.invocation_temp.as_deref(),
963965
);
964-
if config.emit_thin_lto_summary
966+
if let Some(thin_lto_summary_buffer) = thin_lto_summary_buffer
965967
&& let Some(thin_link_bitcode_filename) = bc_summary_out.file_name()
966968
{
967-
let summary_data = thin_lto_buffer.thin_link_data();
969+
let thin_lto_summary_buffer = thin_lto_summary_buffer.unwrap();
970+
let summary_data = thin_lto_summary_buffer.data();
968971
prof.artifact_size(
969972
"llvm_bitcode_summary",
970973
thin_link_bitcode_filename.to_string_lossy(),
@@ -1032,7 +1035,7 @@ pub(crate) fn codegen(
10321035
"LLVM_module_codegen_make_bitcode",
10331036
&*module.name,
10341037
);
1035-
ThinBuffer::new(llmod, cgcx.lto != Lto::Fat)
1038+
ModuleBuffer::new(llmod, cgcx.lto != Lto::Fat)
10361039
};
10371040
let data = thin.data();
10381041
let _timer = prof

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ impl WriteBackendMethods for LlvmCodegenBackend {
153153
type ModuleBuffer = back::lto::ModuleBuffer;
154154
type TargetMachine = OwnedTargetMachine;
155155
type ThinData = back::lto::ThinData;
156-
type ThinBuffer = back::lto::ThinBuffer;
157156
fn print_pass_timings(&self) {
158157
let timings = llvm::build_string(|s| unsafe { llvm::LLVMRustPrintPassTimings(s) }).unwrap();
159158
print!("{timings}");
@@ -193,7 +192,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
193192
dcx: DiagCtxtHandle<'_>,
194193
exported_symbols_for_lto: &[String],
195194
each_linked_rlib_for_lto: &[PathBuf],
196-
modules: Vec<(String, Self::ThinBuffer)>,
195+
modules: Vec<(String, Self::ModuleBuffer)>,
197196
cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
198197
) -> (Vec<ThinModule<Self>>, Vec<WorkProduct>) {
199198
back::lto::run_thin(
@@ -233,11 +232,8 @@ impl WriteBackendMethods for LlvmCodegenBackend {
233232
) -> CompiledModule {
234233
back::write::codegen(cgcx, prof, shared_emitter, module, config)
235234
}
236-
fn prepare_thin(module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer) {
237-
back::lto::prepare_thin(module)
238-
}
239-
fn serialize_module(module: ModuleCodegen<Self::Module>) -> (String, Self::ModuleBuffer) {
240-
(module.name, back::lto::ModuleBuffer::new(module.module_llvm.llmod()))
235+
fn serialize_module(module: Self::Module, is_thin: bool) -> Self::ModuleBuffer {
236+
back::lto::ModuleBuffer::new(module.llmod(), is_thin)
241237
}
242238
}
243239

0 commit comments

Comments
 (0)