Rollup merge of #157050 - bjorn3:lto_refactors19, r=lqd

Couple of changes to help with moving LTO to the link phase

Part of https://github.com/rust-lang/compiler-team/issues/908
This commit is contained in:
Jonathan Brouwer
2026-05-29 09:06:20 +02:00
committed by GitHub
7 changed files with 74 additions and 31 deletions
+5 -3
View File
@@ -339,9 +339,7 @@ fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> {
}
impl ExtraBackendMethods for GccCodegenBackend {
fn supports_parallel(&self) -> bool {
false
}
type Module = GccContext;
fn codegen_allocator(
&self,
@@ -424,6 +422,10 @@ impl WriteBackendMethods for GccCodegenBackend {
type ModuleBuffer = ModuleBuffer;
type ThinData = ();
fn supports_parallel(&self) -> bool {
false
}
fn target_machine_factory(
&self,
_sess: &Session,
+3
View File
@@ -93,6 +93,8 @@ impl Drop for TimeTraceProfiler {
}
impl ExtraBackendMethods for LlvmCodegenBackend {
type Module = ModuleLlvm;
fn codegen_allocator<'tcx>(
&self,
tcx: TyCtxt<'tcx>,
@@ -121,6 +123,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
type ModuleBuffer = back::lto::ModuleBuffer;
type TargetMachine = OwnedTargetMachine;
type ThinData = back::lto::ThinData;
fn thread_profiler() -> Box<dyn Any> {
Box::new(TimeTraceProfiler::new())
}
+5 -16
View File
@@ -352,7 +352,7 @@ pub struct CodegenContext {
pub incr_comp_session_dir: Option<PathBuf>,
/// `true` if the codegen should be run in parallel.
///
/// Depends on [`ExtraBackendMethods::supports_parallel()`] and `-Zno_parallel_backend`.
/// Depends on [`WriteBackendMethods::supports_parallel()`] and `-Zno_parallel_backend`.
pub parallel: bool,
}
@@ -416,7 +416,7 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
}
}
pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
pub(crate) fn start_async_codegen<B: WriteBackendMethods>(
backend: B,
tcx: TyCtxt<'_>,
allocator_module: Option<ModuleCodegen<B::Module>>,
@@ -1115,18 +1115,6 @@ fn do_thin_lto<B: WriteBackendMethods>(
compiled_modules
}
fn execute_thin_lto_work_item<B: WriteBackendMethods>(
cgcx: &CodegenContext,
prof: &SelfProfilerRef,
shared_emitter: SharedEmitter,
tm_factory: TargetMachineFactoryFn<B>,
module: lto::ThinModule<B>,
) -> CompiledModule {
let _timer = prof.generic_activity_with_arg("codegen_module_perform_lto", module.name());
B::optimize_and_codegen_thin(cgcx, prof, &shared_emitter, tm_factory, module)
}
/// Messages sent to the coordinator.
pub(crate) enum Message<B: WriteBackendMethods> {
/// A jobserver token has become available. Sent from the jobserver helper
@@ -1208,7 +1196,7 @@ enum MainThreadState {
Lending,
}
fn start_executing_work<B: ExtraBackendMethods>(
fn start_executing_work<B: WriteBackendMethods>(
backend: B,
tcx: TyCtxt<'_>,
shared_emitter: SharedEmitter,
@@ -1891,7 +1879,8 @@ fn spawn_thin_lto_work<B: WriteBackendMethods>(
execute_copy_from_cache_work_item(&cgcx, &prof, shared_emitter, m)
}
ThinLtoWorkItem::ThinLto(m) => {
execute_thin_lto_work_item(&cgcx, &prof, shared_emitter, tm_factory, m)
let _timer = prof.generic_activity_with_arg("codegen_module_perform_lto", m.name());
B::optimize_and_codegen_thin(&cgcx, &prof, &shared_emitter, tm_factory, m)
}
}));
+7 -1
View File
@@ -688,7 +688,13 @@ pub fn allocator_shim_contents(tcx: TyCtxt<'_>, kind: AllocatorKind) -> Vec<Allo
methods
}
pub fn codegen_crate<B: ExtraBackendMethods>(backend: B, tcx: TyCtxt<'_>) -> OngoingCodegen<B> {
pub fn codegen_crate<
B: ExtraBackendMethods<Module = M> + WriteBackendMethods<Module = M>,
M: Send,
>(
backend: B,
tcx: TyCtxt<'_>,
) -> OngoingCodegen<B> {
if tcx.sess.target.need_explicit_cpu && tcx.sess.opts.cg.target_cpu.is_none() {
// The target has no default cpu, but none is set explicitly
tcx.dcx().emit_fatal(errors::CpuRequired);
@@ -14,7 +14,6 @@ use rustc_session::config::{CrateType, OutputFilenames, PrintRequest};
use rustc_span::Symbol;
use super::CodegenObject;
use super::write::WriteBackendMethods;
use crate::back::archive::ArArchiveBuilderBuilder;
use crate::back::link::link_binary;
use crate::{CompiledModules, CrateInfo, ModuleCodegen, TargetConfig};
@@ -162,9 +161,9 @@ pub trait CodegenBackend {
}
}
pub trait ExtraBackendMethods:
WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync
{
pub trait ExtraBackendMethods: Send + Sync + DynSend + DynSync {
type Module;
fn codegen_allocator<'tcx>(
&self,
tcx: TyCtxt<'tcx>,
@@ -179,11 +178,4 @@ pub trait ExtraBackendMethods:
tcx: TyCtxt<'_>,
cgu_name: Symbol,
) -> (ModuleCodegen<Self::Module>, u64);
/// Returns `true` if this backend can be safely called from multiple threads.
///
/// Defaults to `true`.
fn supports_parallel(&self) -> bool {
true
}
}
@@ -1,4 +1,5 @@
use std::any::Any;
use std::convert::Infallible;
use std::path::PathBuf;
use rustc_data_structures::profiling::SelfProfilerRef;
@@ -18,6 +19,12 @@ pub trait WriteBackendMethods: Clone + 'static {
type ModuleBuffer: ModuleBufferMethods;
type ThinData: Send + Sync;
/// Returns `true` if this backend can be safely called from multiple threads.
///
/// Defaults to `true`.
fn supports_parallel(&self) -> bool {
true
}
fn thread_profiler() -> Box<dyn Any> {
Box::new(())
}
@@ -76,3 +83,9 @@ pub trait WriteBackendMethods: Clone + 'static {
pub trait ModuleBufferMethods: Send + Sync {
fn data(&self) -> &[u8];
}
impl ModuleBufferMethods for Infallible {
fn data(&self) -> &[u8] {
match *self {}
}
}
+38
View File
@@ -34,6 +34,7 @@ use derive_where::derive_where;
use rustc_data_structures::stable_hash::StableHashCtxt;
use rustc_data_structures::{AtomicRef, outline};
use rustc_macros::{Decodable, Encodable, StableHash};
use rustc_serialize::opaque::mem_encoder::MemEncoder;
use rustc_serialize::opaque::{FileEncoder, MemDecoder};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use tracing::debug;
@@ -1398,6 +1399,43 @@ impl SpanEncoder for FileEncoder {
}
}
impl SpanEncoder for MemEncoder {
fn encode_span(&mut self, span: Span) {
let span = span.data();
span.lo.encode(self);
span.hi.encode(self);
}
fn encode_symbol(&mut self, sym: Symbol) {
self.emit_str(sym.as_str());
}
fn encode_byte_symbol(&mut self, byte_sym: ByteSymbol) {
self.emit_byte_str(byte_sym.as_byte_str());
}
fn encode_expn_id(&mut self, _expn_id: ExpnId) {
panic!("cannot encode `ExpnId` with `FileEncoder`");
}
fn encode_syntax_context(&mut self, _syntax_context: SyntaxContext) {
panic!("cannot encode `SyntaxContext` with `FileEncoder`");
}
fn encode_crate_num(&mut self, crate_num: CrateNum) {
self.emit_u32(crate_num.as_u32());
}
fn encode_def_index(&mut self, _def_index: DefIndex) {
panic!("cannot encode `DefIndex` with `FileEncoder`");
}
fn encode_def_id(&mut self, def_id: DefId) {
def_id.krate.encode(self);
def_id.index.encode(self);
}
}
impl<E: SpanEncoder> Encodable<E> for Span {
fn encode(&self, s: &mut E) {
s.encode_span(*self);