diff options
| author | Laurențiu Nicola <lnicola@dend.ro> | 2025-02-10 07:49:43 +0200 |
|---|---|---|
| committer | Laurențiu Nicola <lnicola@dend.ro> | 2025-02-10 07:49:43 +0200 |
| commit | 15cd1f011c4f854f7a7cfbe2e727cc4b02b1d254 (patch) | |
| tree | bdd9d79bd54ffe237db9c987d6c1e2ab12349e16 /compiler/rustc_codegen_ssa/src/back | |
| parent | 879dc387cde7ac4b85aa5a185158c9c3c488c5e7 (diff) | |
| parent | d9a4a47b8b3dc0bdff83360cea2013200d60d49c (diff) | |
| download | rust-15cd1f011c4f854f7a7cfbe2e727cc4b02b1d254.tar.gz rust-15cd1f011c4f854f7a7cfbe2e727cc4b02b1d254.zip | |
Merge from rust-lang/rust
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/back')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/archive.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/command.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/link.rs | 77 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/linker/tests.rs | 35 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/lto.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/metadata.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/symbol_export.rs | 145 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/write.rs | 38 |
8 files changed, 235 insertions, 107 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 58eb137c068..60af462b6b6 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -414,10 +414,10 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> { let member_path = archive_path.parent().unwrap().join(Path::new(&file_name)); self.entries.push((file_name.into_bytes(), ArchiveEntry::File(member_path))); } else { - self.entries.push((file_name.into_bytes(), ArchiveEntry::FromArchive { - archive_index, - file_range: entry.file_range(), - })); + self.entries.push(( + file_name.into_bytes(), + ArchiveEntry::FromArchive { archive_index, file_range: entry.file_range() }, + )); } } } diff --git a/compiler/rustc_codegen_ssa/src/back/command.rs b/compiler/rustc_codegen_ssa/src/back/command.rs index b3c5b86ccf4..63023fdba20 100644 --- a/compiler/rustc_codegen_ssa/src/back/command.rs +++ b/compiler/rustc_codegen_ssa/src/back/command.rs @@ -13,6 +13,7 @@ pub(crate) struct Command { args: Vec<OsString>, env: Vec<(OsString, OsString)>, env_remove: Vec<OsString>, + env_clear: bool, } #[derive(Clone)] @@ -36,7 +37,13 @@ impl Command { } fn _new(program: Program) -> Command { - Command { program, args: Vec::new(), env: Vec::new(), env_remove: Vec::new() } + Command { + program, + args: Vec::new(), + env: Vec::new(), + env_remove: Vec::new(), + env_clear: false, + } } pub(crate) fn arg<P: AsRef<OsStr>>(&mut self, arg: P) -> &mut Command { @@ -79,6 +86,11 @@ impl Command { self } + pub(crate) fn env_clear(&mut self) -> &mut Command { + self.env_clear = true; + self + } + fn _env_remove(&mut self, key: &OsStr) { self.env_remove.push(key.to_owned()); } @@ -106,6 +118,9 @@ impl Command { for k in &self.env_remove { ret.env_remove(k); } + if self.env_clear { + ret.env_clear(); + } ret } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index df35b5e8426..105a4cb81f0 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -15,12 +15,14 @@ use rustc_ast::CRATE_NODE_ID; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; -use rustc_errors::DiagCtxtHandle; +use rustc_errors::{DiagCtxtHandle, LintDiagnostic}; use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize}; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; +use rustc_macros::LintDiagnostic; use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file}; use rustc_metadata::{find_native_static_library, walk_native_lib_search_dirs}; use rustc_middle::bug; +use rustc_middle::lint::lint_level; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::SymbolExportKind; @@ -29,6 +31,7 @@ use rustc_session::config::{ OutputType, PrintKind, SplitDwarfKind, Strip, }; use rustc_session::cstore::DllImport; +use rustc_session::lint::builtin::LINKER_MESSAGES; use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename}; use rustc_session::search_paths::PathKind; use rustc_session::utils::NativeLibKind; @@ -749,6 +752,14 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out } } +#[derive(LintDiagnostic)] +#[diag(codegen_ssa_linker_output)] +/// Translating this is kind of useless. We don't pass translation flags to the linker, so we'd just +/// end up with inconsistent languages within the same diagnostic. +struct LinkerOutput { + inner: String, +} + /// Create a dynamic library or executable. /// /// This will invoke the system linker/cc to create the resulting file. This links to all upstream @@ -981,6 +992,11 @@ fn link_natively( match prog { Ok(prog) => { + let is_msvc_link_exe = sess.target.is_like_msvc + && flavor == LinkerFlavor::Msvc(Lld::No) + // Match exactly "link.exe" + && linker_path.to_str() == Some("link.exe"); + if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); @@ -991,22 +1007,16 @@ fn link_natively( command: cmd, escaped_output, verbose: sess.opts.verbose, + sysroot_dir: sess.sysroot.clone(), }; sess.dcx().emit_err(err); // If MSVC's `link.exe` was expected but the return code // is not a Microsoft LNK error then suggest a way to fix or // install the Visual Studio build tools. if let Some(code) = prog.status.code() { - if sess.target.is_like_msvc - && flavor == LinkerFlavor::Msvc(Lld::No) - // Respect the command line override - && sess.opts.cg.linker.is_none() - // Match exactly "link.exe" - && linker_path.to_str() == Some("link.exe") - // All Microsoft `link.exe` linking error codes are - // four digit numbers in the range 1000 to 9999 inclusive - && (code < 1000 || code > 9999) - { + // All Microsoft `link.exe` linking ror codes are + // four digit numbers in the range 1000 to 9999 inclusive + if is_msvc_link_exe && (code < 1000 || code > 9999) { let is_vs_installed = windows_registry::find_vs_version().is_ok(); let has_linker = windows_registry::find_tool(&sess.target.arch, "link.exe").is_some(); @@ -1028,8 +1038,49 @@ fn link_natively( sess.dcx().abort_if_errors(); } - info!("linker stderr:\n{}", escape_string(&prog.stderr)); - info!("linker stdout:\n{}", escape_string(&prog.stdout)); + + let stderr = escape_string(&prog.stderr); + let mut stdout = escape_string(&prog.stdout); + info!("linker stderr:\n{}", &stderr); + info!("linker stdout:\n{}", &stdout); + + // Hide some progress messages from link.exe that we don't care about. + // See https://github.com/chromium/chromium/blob/bfa41e41145ffc85f041384280caf2949bb7bd72/build/toolchain/win/tool_wrapper.py#L144-L146 + if is_msvc_link_exe { + if let Ok(str) = str::from_utf8(&prog.stdout) { + let mut output = String::with_capacity(str.len()); + for line in stdout.lines() { + if line.starts_with(" Creating library") + || line.starts_with("Generating code") + || line.starts_with("Finished generating code") + { + continue; + } + output += line; + output += "\r\n" + } + stdout = escape_string(output.trim().as_bytes()) + } + } + + let (level, src) = codegen_results.crate_info.lint_levels.linker_messages; + let lint = |msg| { + lint_level(sess, LINKER_MESSAGES, level, src, None, |diag| { + LinkerOutput { inner: msg }.decorate_lint(diag) + }) + }; + + if !prog.stderr.is_empty() { + // We already print `warning:` at the start of the diagnostic. Remove it from the linker output if present. + let stderr = stderr + .strip_prefix("warning: ") + .unwrap_or(&stderr) + .replace(": warning: ", ": "); + lint(format!("linker stderr: {stderr}")); + } + if !stdout.is_empty() { + lint(format!("linker stdout: {}", stdout)) + } } Err(e) => { let linker_not_found = e.kind() == io::ErrorKind::NotFound; diff --git a/compiler/rustc_codegen_ssa/src/back/linker/tests.rs b/compiler/rustc_codegen_ssa/src/back/linker/tests.rs index bf3e8c90200..143df085dbf 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker/tests.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker/tests.rs @@ -10,23 +10,22 @@ fn test_rpaths_to_args() { #[test] fn test_xlinker() { let mut cmd = Command::new("foo"); - convert_link_args_to_cc_args(&mut cmd, &[ - "arg1", - "arg2", - "arg3,with,comma", - "arg4,with,comma", - "arg5", - "arg6,with,comma", - ]); + convert_link_args_to_cc_args( + &mut cmd, + &["arg1", "arg2", "arg3,with,comma", "arg4,with,comma", "arg5", "arg6,with,comma"], + ); - assert_eq!(cmd.get_args(), [ - OsStr::new("-Wl,arg1,arg2"), - OsStr::new("-Xlinker"), - OsStr::new("arg3,with,comma"), - OsStr::new("-Xlinker"), - OsStr::new("arg4,with,comma"), - OsStr::new("-Wl,arg5"), - OsStr::new("-Xlinker"), - OsStr::new("arg6,with,comma"), - ]); + assert_eq!( + cmd.get_args(), + [ + OsStr::new("-Wl,arg1,arg2"), + OsStr::new("-Xlinker"), + OsStr::new("arg3,with,comma"), + OsStr::new("-Xlinker"), + OsStr::new("arg4,with,comma"), + OsStr::new("-Wl,arg5"), + OsStr::new("-Xlinker"), + OsStr::new("arg6,with,comma"), + ] + ); } diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index efccf7687a1..9fd984b6419 100644 --- a/compiler/rustc_codegen_ssa/src/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs @@ -4,7 +4,6 @@ use std::sync::Arc; use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_data_structures::memmap::Mmap; use rustc_errors::FatalError; -use rustc_middle::ty::TyCtxt; use super::write::CodegenContext; use crate::ModuleCodegen; @@ -89,13 +88,12 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> { pub unsafe fn autodiff( self, cgcx: &CodegenContext<B>, - tcx: TyCtxt<'_>, diff_fncs: Vec<AutoDiffItem>, config: &ModuleConfig, ) -> Result<LtoModuleCodegen<B>, FatalError> { match &self { LtoModuleCodegen::Fat(module) => { - B::autodiff(cgcx, tcx, &module, diff_fncs, config)?; + B::autodiff(cgcx, &module, diff_fncs, config)?; } _ => panic!("autodiff called with non-fat LTO module"), } diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index ba7b53321a8..d70413b8a47 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -704,13 +704,17 @@ pub fn create_metadata_file_for_wasm(sess: &Session, data: &[u8], section_name: let mut imports = wasm_encoder::ImportSection::new(); if sess.target.pointer_width == 64 { - imports.import("env", "__linear_memory", wasm_encoder::MemoryType { - minimum: 0, - maximum: None, - memory64: true, - shared: false, - page_size_log2: None, - }); + imports.import( + "env", + "__linear_memory", + wasm_encoder::MemoryType { + minimum: 0, + maximum: None, + memory64: true, + shared: false, + page_size_log2: None, + }, + ); } if imports.len() > 0 { diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 60ab2919352..1dbaffaa577 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -140,11 +140,14 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S .into(); if let Some(id) = tcx.proc_macro_decls_static(()) { - reachable_non_generics.insert(id.to_def_id(), SymbolExportInfo { - level: SymbolExportLevel::C, - kind: SymbolExportKind::Data, - used: false, - }); + reachable_non_generics.insert( + id.to_def_id(), + SymbolExportInfo { + level: SymbolExportLevel::C, + kind: SymbolExportKind::Data, + used: false, + }, + ); } reachable_non_generics @@ -185,11 +188,14 @@ fn exported_symbols_provider_local( if !tcx.sess.target.dll_tls_export { symbols.extend(sorted.iter().filter_map(|(&def_id, &info)| { tcx.needs_thread_local_shim(def_id).then(|| { - (ExportedSymbol::ThreadLocalShim(def_id), SymbolExportInfo { - level: info.level, - kind: SymbolExportKind::Text, - used: info.used, - }) + ( + ExportedSymbol::ThreadLocalShim(def_id), + SymbolExportInfo { + level: info.level, + kind: SymbolExportKind::Text, + used: info.used, + }, + ) }) })) } @@ -198,11 +204,14 @@ fn exported_symbols_provider_local( let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, tcx.sess.target.entry_name.as_ref())); - symbols.push((exported_symbol, SymbolExportInfo { - level: SymbolExportLevel::C, - kind: SymbolExportKind::Text, - used: false, - })); + symbols.push(( + exported_symbol, + SymbolExportInfo { + level: SymbolExportLevel::C, + kind: SymbolExportKind::Text, + used: false, + }, + )); } // Mark allocator shim symbols as exported only if they were generated. @@ -214,20 +223,26 @@ fn exported_symbols_provider_local( { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); - symbols.push((exported_symbol, SymbolExportInfo { - level: SymbolExportLevel::Rust, - kind: SymbolExportKind::Text, - used: false, - })); + symbols.push(( + exported_symbol, + SymbolExportInfo { + level: SymbolExportLevel::Rust, + kind: SymbolExportKind::Text, + used: false, + }, + )); } let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, NO_ALLOC_SHIM_IS_UNSTABLE)); - symbols.push((exported_symbol, SymbolExportInfo { - level: SymbolExportLevel::Rust, - kind: SymbolExportKind::Data, - used: false, - })) + symbols.push(( + exported_symbol, + SymbolExportInfo { + level: SymbolExportLevel::Rust, + kind: SymbolExportKind::Data, + used: false, + }, + )) } if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() { @@ -239,11 +254,14 @@ fn exported_symbols_provider_local( symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym)); - (exported_symbol, SymbolExportInfo { - level: SymbolExportLevel::C, - kind: SymbolExportKind::Data, - used: false, - }) + ( + exported_symbol, + SymbolExportInfo { + level: SymbolExportLevel::C, + kind: SymbolExportKind::Data, + used: false, + }, + ) })); } @@ -261,11 +279,14 @@ fn exported_symbols_provider_local( symbols.extend(msan_weak_symbols.into_iter().map(|sym| { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym)); - (exported_symbol, SymbolExportInfo { - level: SymbolExportLevel::C, - kind: SymbolExportKind::Data, - used: false, - }) + ( + exported_symbol, + SymbolExportInfo { + level: SymbolExportLevel::C, + kind: SymbolExportKind::Data, + used: false, + }, + ) })); } @@ -275,11 +296,14 @@ fn exported_symbols_provider_local( let symbol_name = metadata_symbol_name(tcx); let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); - symbols.push((exported_symbol, SymbolExportInfo { - level: SymbolExportLevel::C, - kind: SymbolExportKind::Data, - used: true, - })); + symbols.push(( + exported_symbol, + SymbolExportInfo { + level: SymbolExportLevel::C, + kind: SymbolExportKind::Data, + used: true, + }, + )); } if tcx.local_crate_exports_generics() { @@ -293,7 +317,7 @@ fn exported_symbols_provider_local( // external linkage is enough for monomorphization to be linked to. let need_visibility = tcx.sess.target.dynamic_linking && !tcx.sess.target.only_cdylib; - let (_, cgus) = tcx.collect_and_partition_mono_items(()); + let cgus = tcx.collect_and_partition_mono_items(()).codegen_units; // The symbols created in this loop are sorted below it #[allow(rustc::potential_query_instability)] @@ -325,21 +349,27 @@ fn exported_symbols_provider_local( MonoItem::Fn(Instance { def: InstanceKind::Item(def), args }) => { if args.non_erasable_generics().next().is_some() { let symbol = ExportedSymbol::Generic(def, args); - symbols.push((symbol, SymbolExportInfo { - level: SymbolExportLevel::Rust, - kind: SymbolExportKind::Text, - used: false, - })); + symbols.push(( + symbol, + SymbolExportInfo { + level: SymbolExportLevel::Rust, + kind: SymbolExportKind::Text, + used: false, + }, + )); } } MonoItem::Fn(Instance { def: InstanceKind::DropGlue(_, Some(ty)), args }) => { // A little sanity-check assert_eq!(args.non_erasable_generics().next(), Some(GenericArgKind::Type(ty))); - symbols.push((ExportedSymbol::DropGlue(ty), SymbolExportInfo { - level: SymbolExportLevel::Rust, - kind: SymbolExportKind::Text, - used: false, - })); + symbols.push(( + ExportedSymbol::DropGlue(ty), + SymbolExportInfo { + level: SymbolExportLevel::Rust, + kind: SymbolExportKind::Text, + used: false, + }, + )); } MonoItem::Fn(Instance { def: InstanceKind::AsyncDropGlueCtorShim(_, Some(ty)), @@ -347,11 +377,14 @@ fn exported_symbols_provider_local( }) => { // A little sanity-check assert_eq!(args.non_erasable_generics().next(), Some(GenericArgKind::Type(ty))); - symbols.push((ExportedSymbol::AsyncDropGlueCtorShim(ty), SymbolExportInfo { - level: SymbolExportLevel::Rust, - kind: SymbolExportKind::Text, - used: false, - })); + symbols.push(( + ExportedSymbol::AsyncDropGlueCtorShim(ty), + SymbolExportInfo { + level: SymbolExportLevel::Rust, + kind: SymbolExportKind::Text, + used: false, + }, + )); } _ => { // Any other symbols don't qualify for sharing diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index b40bb4ed5d2..ce2161a07eb 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -7,6 +7,7 @@ use std::sync::mpsc::{Receiver, Sender, channel}; use std::{fs, io, mem, str, thread}; use rustc_ast::attr; +use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_data_structures::jobserver::{self, Acquired}; use rustc_data_structures::memmap::Mmap; @@ -40,7 +41,7 @@ use tracing::debug; use super::link::{self, ensure_removed}; use super::lto::{self, SerializedModule}; use super::symbol_export::symbol_name_for_instance_in_crate; -use crate::errors::ErrorCreatingRemarkDir; +use crate::errors::{AutodiffWithoutLto, ErrorCreatingRemarkDir}; use crate::traits::*; use crate::{ CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, @@ -118,6 +119,7 @@ pub struct ModuleConfig { pub merge_functions: bool, pub emit_lifetime_markers: bool, pub llvm_plugins: Vec<String>, + pub autodiff: Vec<config::AutoDiff>, } impl ModuleConfig { @@ -266,6 +268,7 @@ impl ModuleConfig { emit_lifetime_markers: sess.emit_lifetime_markers(), llvm_plugins: if_regular!(sess.opts.unstable_opts.llvm_plugins.clone(), vec![]), + autodiff: if_regular!(sess.opts.unstable_opts.autodiff.clone(), vec![]), } } @@ -389,6 +392,7 @@ impl<B: WriteBackendMethods> CodegenContext<B> { fn generate_lto_work<B: ExtraBackendMethods>( cgcx: &CodegenContext<B>, + autodiff: Vec<AutoDiffItem>, needs_fat_lto: Vec<FatLtoInput<B>>, needs_thin_lto: Vec<(String, B::ThinBuffer)>, import_only_modules: Vec<(SerializedModule<B::ModuleBuffer>, WorkProduct)>, @@ -397,11 +401,19 @@ fn generate_lto_work<B: ExtraBackendMethods>( if !needs_fat_lto.is_empty() { assert!(needs_thin_lto.is_empty()); - let module = + let mut module = B::run_fat_lto(cgcx, needs_fat_lto, import_only_modules).unwrap_or_else(|e| e.raise()); + if cgcx.lto == Lto::Fat && !autodiff.is_empty() { + let config = cgcx.config(ModuleKind::Regular); + module = unsafe { module.autodiff(cgcx, autodiff, config).unwrap() }; + } // We are adding a single work item, so the cost doesn't matter. vec![(WorkItem::LTO(module), 0)] } else { + if !autodiff.is_empty() { + let dcx = cgcx.create_dcx(); + dcx.handle().emit_fatal(AutodiffWithoutLto {}); + } assert!(needs_fat_lto.is_empty()); let (lto_modules, copy_jobs) = B::run_thin_lto(cgcx, needs_thin_lto, import_only_modules) .unwrap_or_else(|e| e.raise()); @@ -1021,6 +1033,9 @@ pub(crate) enum Message<B: WriteBackendMethods> { /// Sent from a backend worker thread. WorkItem { result: Result<WorkItemResult<B>, Option<WorkerFatalError>>, worker_id: usize }, + /// A vector containing all the AutoDiff tasks that we have to pass to Enzyme. + AddAutoDiffItems(Vec<AutoDiffItem>), + /// The frontend has finished generating something (backend IR or a /// post-LTO artifact) for a codegen unit, and it should be passed to the /// backend. Sent from the main thread. @@ -1348,6 +1363,7 @@ fn start_executing_work<B: ExtraBackendMethods>( // This is where we collect codegen units that have gone all the way // through codegen and LLVM. + let mut autodiff_items = Vec::new(); let mut compiled_modules = vec![]; let mut compiled_allocator_module = None; let mut needs_link = Vec::new(); @@ -1459,9 +1475,13 @@ fn start_executing_work<B: ExtraBackendMethods>( let needs_thin_lto = mem::take(&mut needs_thin_lto); let import_only_modules = mem::take(&mut lto_import_only_modules); - for (work, cost) in - generate_lto_work(&cgcx, needs_fat_lto, needs_thin_lto, import_only_modules) - { + for (work, cost) in generate_lto_work( + &cgcx, + autodiff_items.clone(), + needs_fat_lto, + needs_thin_lto, + import_only_modules, + ) { let insertion_index = work_items .binary_search_by_key(&cost, |&(_, cost)| cost) .unwrap_or_else(|e| e); @@ -1596,6 +1616,10 @@ fn start_executing_work<B: ExtraBackendMethods>( main_thread_state = MainThreadState::Idle; } + Message::AddAutoDiffItems(mut items) => { + autodiff_items.append(&mut items); + } + Message::CodegenComplete => { if codegen_state != Aborted { codegen_state = Completed; @@ -2070,6 +2094,10 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> { drop(self.coordinator.sender.send(Box::new(Message::CodegenComplete::<B>))); } + pub(crate) fn submit_autodiff_items(&self, items: Vec<AutoDiffItem>) { + drop(self.coordinator.sender.send(Box::new(Message::<B>::AddAutoDiffItems(items)))); + } + pub(crate) fn check_for_errors(&self, sess: &Session) { self.shared_emitter_main.check(sess, false); } |
