From 1fae0e31f2944e00f4cfbf2cf0b590819d5e6c93 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 May 2026 14:22:12 +0000 Subject: [PATCH 1/4] Implement SpanEncoder for MemEncoder This seems like it was an oversight. It will be necessary in a future PR to serialize MaybeLtoModules as necessary to move LTO to the link phase. --- compiler/rustc_span/src/lib.rs | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 3f427ea09610..2371bf15756d 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -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 Encodable for Span { fn encode(&self, s: &mut E) { s.encode_span(*self); From 9f8820be2953f74d7335d9ff39713df92bd73ed2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 28 May 2026 09:00:36 +0000 Subject: [PATCH 2/4] Support implementing ExtraBackendMethods and WriteBackendMethods independently --- compiler/rustc_codegen_gcc/src/lib.rs | 8 +++++--- compiler/rustc_codegen_llvm/src/lib.rs | 3 +++ compiler/rustc_codegen_ssa/src/back/write.rs | 6 +++--- compiler/rustc_codegen_ssa/src/base.rs | 8 +++++++- compiler/rustc_codegen_ssa/src/traits/backend.rs | 14 +++----------- compiler/rustc_codegen_ssa/src/traits/write.rs | 7 +++++++ 6 files changed, 28 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 6ca2ef88ef29..50f10947c6ae 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -335,9 +335,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, @@ -420,6 +418,10 @@ impl WriteBackendMethods for GccCodegenBackend { type ModuleBuffer = ModuleBuffer; type ThinData = (); + fn supports_parallel(&self) -> bool { + false + } + fn target_machine_factory( &self, _sess: &Session, diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index a697f8fe70bb..b2a2e1349f98 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -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 { Box::new(TimeTraceProfiler::new()) } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 7b22ac231df1..63f773cf7ecb 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -352,7 +352,7 @@ pub struct CodegenContext { pub incr_comp_session_dir: Option, /// `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( +pub(crate) fn start_async_codegen( backend: B, tcx: TyCtxt<'_>, allocator_module: Option>, @@ -1208,7 +1208,7 @@ enum MainThreadState { Lending, } -fn start_executing_work( +fn start_executing_work( backend: B, tcx: TyCtxt<'_>, shared_emitter: SharedEmitter, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index b0ce3833446d..78bc07869895 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -688,7 +688,13 @@ pub fn allocator_shim_contents(tcx: TyCtxt<'_>, kind: AllocatorKind) -> Vec(backend: B, tcx: TyCtxt<'_>) -> OngoingCodegen { +pub fn codegen_crate< + B: ExtraBackendMethods + WriteBackendMethods, + M: Send, +>( + backend: B, + tcx: TyCtxt<'_>, +) -> OngoingCodegen { 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); diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index cbb75836f979..0e227ecb1308 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -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}; @@ -156,9 +155,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>, @@ -173,11 +172,4 @@ pub trait ExtraBackendMethods: tcx: TyCtxt<'_>, cgu_name: Symbol, ) -> (ModuleCodegen, u64); - - /// Returns `true` if this backend can be safely called from multiple threads. - /// - /// Defaults to `true`. - fn supports_parallel(&self) -> bool { - true - } } diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs index 9b8bf138e7a1..d4f35ea7da1b 100644 --- a/compiler/rustc_codegen_ssa/src/traits/write.rs +++ b/compiler/rustc_codegen_ssa/src/traits/write.rs @@ -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 { Box::new(()) } From 3ef68399305c26a0a4ce3904f4c1ff2d8a9874e5 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 28 May 2026 09:08:25 +0000 Subject: [PATCH 3/4] Inline a small function --- compiler/rustc_codegen_ssa/src/back/write.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 63f773cf7ecb..96c632081d46 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1115,18 +1115,6 @@ fn do_thin_lto( compiled_modules } -fn execute_thin_lto_work_item( - cgcx: &CodegenContext, - prof: &SelfProfilerRef, - shared_emitter: SharedEmitter, - tm_factory: TargetMachineFactoryFn, - module: lto::ThinModule, -) -> 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 { /// A jobserver token has become available. Sent from the jobserver helper @@ -1891,7 +1879,8 @@ fn spawn_thin_lto_work( 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) } })); From 32b61075f54f185baa624461ab8ad82ec472df2a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 28 May 2026 09:09:20 +0000 Subject: [PATCH 4/4] Implement ModuleBufferMethods for Infallible This would be useful for codegen backends that don't support LTO, yet do want to implement WriteBackendMethods. --- compiler/rustc_codegen_ssa/src/traits/write.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs index d4f35ea7da1b..5bd5b272754b 100644 --- a/compiler/rustc_codegen_ssa/src/traits/write.rs +++ b/compiler/rustc_codegen_ssa/src/traits/write.rs @@ -83,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 {} + } +}