diff options
| author | Antoni Boucher <bouanto@zoho.com> | 2025-01-13 10:53:58 -0500 |
|---|---|---|
| committer | Antoni Boucher <bouanto@zoho.com> | 2025-01-13 10:53:58 -0500 |
| commit | 06f0a9bc785ad8654e1bf505f60ce7146b3850f3 (patch) | |
| tree | cedfc1ddcceaf4e0709e1a71fe36f8b4b6d9396e /compiler/rustc_codegen_gcc/src/back | |
| parent | 3ff1b6410e87a237559ab76ecd50f180afbe861f (diff) | |
| parent | 59a81c2ca1edc88ad3ac4b27a8e03977ffb8e73a (diff) | |
| download | rust-06f0a9bc785ad8654e1bf505f60ce7146b3850f3.tar.gz rust-06f0a9bc785ad8654e1bf505f60ce7146b3850f3.zip | |
Merge commit '59a81c2ca1edc88ad3ac4b27a8e03977ffb8e73a' into subtree-update_cg_gcc_2025_01_12
Diffstat (limited to 'compiler/rustc_codegen_gcc/src/back')
| -rw-r--r-- | compiler/rustc_codegen_gcc/src/back/lto.rs | 37 | ||||
| -rw-r--r-- | compiler/rustc_codegen_gcc/src/back/write.rs | 157 |
2 files changed, 132 insertions, 62 deletions
diff --git a/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs index f7173d4d2ff..e419bd18099 100644 --- a/compiler/rustc_codegen_gcc/src/back/lto.rs +++ b/compiler/rustc_codegen_gcc/src/back/lto.rs @@ -35,16 +35,13 @@ use rustc_middle::bug; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel}; use rustc_session::config::{CrateType, Lto}; +use rustc_target::spec::RelocModel; use tempfile::{TempDir, tempdir}; use crate::back::write::save_temp_bitcode; use crate::errors::{DynamicLinkingWithLTO, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib}; use crate::{GccCodegenBackend, GccContext, SyncContext, to_gcc_opt_level}; -/// We keep track of the computed LTO cache keys from the previous -/// session to determine which CGUs we can reuse. -//pub const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin"; - pub fn crate_type_allows_lto(crate_type: CrateType) -> bool { match crate_type { CrateType::Executable | CrateType::Dylib | CrateType::Staticlib | CrateType::Cdylib => true, @@ -54,7 +51,7 @@ pub fn crate_type_allows_lto(crate_type: CrateType) -> bool { struct LtoData { // TODO(antoyo): use symbols_below_threshold. - //symbols_below_threshold: Vec<CString>, + //symbols_below_threshold: Vec<String>, upstream_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>, tmp_path: TempDir, } @@ -83,7 +80,7 @@ fn prepare_lto( let symbol_filter = &|&(ref name, info): &(String, SymbolExportInfo)| { if info.level.is_below_threshold(export_threshold) || info.used { - Some(CString::new(name.as_str()).unwrap()) + Some(name.clone()) } else { None } @@ -91,7 +88,7 @@ fn prepare_lto( let exported_symbols = cgcx.exported_symbols.as_ref().expect("needs exported symbols for LTO"); let mut symbols_below_threshold = { let _timer = cgcx.prof.generic_activity("GCC_lto_generate_symbols_below_threshold"); - exported_symbols[&LOCAL_CRATE].iter().filter_map(symbol_filter).collect::<Vec<CString>>() + exported_symbols[&LOCAL_CRATE].iter().filter_map(symbol_filter).collect::<Vec<String>>() }; info!("{} symbols to preserve in this crate", symbols_below_threshold.len()); @@ -159,11 +156,7 @@ fn prepare_lto( } } - Ok(LtoData { - //symbols_below_threshold, - upstream_modules, - tmp_path, - }) + Ok(LtoData { upstream_modules, tmp_path }) } fn save_as_file(obj: &[u8], path: &Path) -> Result<(), LtoBitcodeFromRlib> { @@ -191,7 +184,7 @@ pub(crate) fn run_fat( cached_modules, lto_data.upstream_modules, lto_data.tmp_path, - //&symbols_below_threshold, + //<o_data.symbols_below_threshold, ) } @@ -202,7 +195,7 @@ fn fat_lto( cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>, mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>, tmp_path: TempDir, - //symbols_below_threshold: &[*const libc::c_char], + //symbols_below_threshold: &[String], ) -> Result<LtoModuleCodegen<GccCodegenBackend>, FatalError> { let _timer = cgcx.prof.generic_activity("GCC_fat_lto_build_monolithic_module"); info!("going for a fat lto"); @@ -327,6 +320,7 @@ fn fat_lto( ptr as *const *const libc::c_char, symbols_below_threshold.len() as libc::size_t, );*/ + save_temp_bitcode(cgcx, &module, "lto.after-restriction"); //} } @@ -363,8 +357,6 @@ pub(crate) fn run_thin( let dcx = cgcx.create_dcx(); let dcx = dcx.handle(); let lto_data = prepare_lto(cgcx, dcx)?; - /*let symbols_below_threshold = - symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();*/ if cgcx.opts.cg.linker_plugin_lto.enabled() { unreachable!( "We should never reach this case if the LTO step \ @@ -377,7 +369,8 @@ pub(crate) fn run_thin( modules, lto_data.upstream_modules, lto_data.tmp_path, - cached_modules, /*, &symbols_below_threshold*/ + cached_modules, + //<o_data.symbols_below_threshold, ) } @@ -428,7 +421,7 @@ fn thin_lto( serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>, tmp_path: TempDir, cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>, - //symbols_below_threshold: &[*const libc::c_char], + //_symbols_below_threshold: &[String], ) -> Result<(Vec<LtoModuleCodegen<GccCodegenBackend>>, Vec<WorkProduct>), FatalError> { let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_global_analysis"); info!("going for that thin, thin LTO"); @@ -640,7 +633,13 @@ pub unsafe fn optimize_thin_module( } }; let module = ModuleCodegen { - module_llvm: GccContext { context, should_combine_object_files, temp_dir: None }, + module_llvm: GccContext { + context, + should_combine_object_files, + // TODO(antoyo): use the correct relocation model here. + relocation_model: RelocModel::Pic, + temp_dir: None, + }, name: thin_module.name().to_string(), kind: ModuleKind::Regular, }; diff --git a/compiler/rustc_codegen_gcc/src/back/write.rs b/compiler/rustc_codegen_gcc/src/back/write.rs index 802968979c7..51c5ba73e32 100644 --- a/compiler/rustc_codegen_gcc/src/back/write.rs +++ b/compiler/rustc_codegen_gcc/src/back/write.rs @@ -1,6 +1,6 @@ use std::{env, fs}; -use gccjit::OutputKind; +use gccjit::{Context, OutputKind}; use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig}; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; @@ -10,6 +10,7 @@ use rustc_session::config::OutputType; use rustc_span::fatal_error::FatalError; use rustc_target::spec::SplitDebuginfo; +use crate::base::add_pic_option; use crate::errors::CopyBitcode; use crate::{GccCodegenBackend, GccContext}; @@ -31,51 +32,87 @@ pub(crate) unsafe fn codegen( // NOTE: Only generate object files with GIMPLE when this environment variable is set for // now because this requires a particular setup (same gcc/lto1/lto-wrapper commit as libgccjit). - // TODO: remove this environment variable. + // TODO(antoyo): remove this environment variable. let fat_lto = env::var("EMBED_LTO_BITCODE").as_deref() == Ok("1"); let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name); let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name); - if config.bitcode_needed() && fat_lto { - let _timer = cgcx - .prof - .generic_activity_with_arg("GCC_module_codegen_make_bitcode", &*module.name); - - // TODO(antoyo) - /*if let Some(bitcode_filename) = bc_out.file_name() { - cgcx.prof.artifact_size( - "llvm_bitcode", - bitcode_filename.to_string_lossy(), - data.len() as u64, - ); - }*/ - - if config.emit_bc || config.emit_obj == EmitObj::Bitcode { + if config.bitcode_needed() { + if fat_lto { let _timer = cgcx .prof - .generic_activity_with_arg("GCC_module_codegen_emit_bitcode", &*module.name); - context.add_command_line_option("-flto=auto"); - context.add_command_line_option("-flto-partition=one"); - // TODO: remove since we don't want fat objects when it is for Bitcode only. - context.add_command_line_option("-ffat-lto-objects"); - context - .compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str")); - } + .generic_activity_with_arg("GCC_module_codegen_make_bitcode", &*module.name); - if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { - let _timer = cgcx - .prof - .generic_activity_with_arg("GCC_module_codegen_embed_bitcode", &*module.name); - // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes? - //embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data); - - context.add_command_line_option("-flto=auto"); - context.add_command_line_option("-flto-partition=one"); - context.add_command_line_option("-ffat-lto-objects"); - // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument). - context - .compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str")); + // TODO(antoyo) + /*if let Some(bitcode_filename) = bc_out.file_name() { + cgcx.prof.artifact_size( + "llvm_bitcode", + bitcode_filename.to_string_lossy(), + data.len() as u64, + ); + }*/ + + if config.emit_bc || config.emit_obj == EmitObj::Bitcode { + let _timer = cgcx.prof.generic_activity_with_arg( + "GCC_module_codegen_emit_bitcode", + &*module.name, + ); + context.add_command_line_option("-flto=auto"); + context.add_command_line_option("-flto-partition=one"); + // TODO(antoyo): remove since we don't want fat objects when it is for Bitcode only. + context.add_command_line_option("-ffat-lto-objects"); + context.compile_to_file( + OutputKind::ObjectFile, + bc_out.to_str().expect("path to str"), + ); + } + + if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { + let _timer = cgcx.prof.generic_activity_with_arg( + "GCC_module_codegen_embed_bitcode", + &*module.name, + ); + // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes? + //embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data); + + context.add_command_line_option("-flto=auto"); + context.add_command_line_option("-flto-partition=one"); + context.add_command_line_option("-ffat-lto-objects"); + // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument). + context.compile_to_file( + OutputKind::ObjectFile, + bc_out.to_str().expect("path to str"), + ); + } + } else { + if config.emit_bc || config.emit_obj == EmitObj::Bitcode { + let _timer = cgcx.prof.generic_activity_with_arg( + "GCC_module_codegen_emit_bitcode", + &*module.name, + ); + context.compile_to_file( + OutputKind::ObjectFile, + bc_out.to_str().expect("path to str"), + ); + } + + if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { + // TODO(antoyo): we might want to emit to emit an error here, saying to set the + // environment variable EMBED_LTO_BITCODE. + let _timer = cgcx.prof.generic_activity_with_arg( + "GCC_module_codegen_embed_bitcode", + &*module.name, + ); + // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes? + //embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data); + + // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument). + context.compile_to_file( + OutputKind::ObjectFile, + bc_out.to_str().expect("path to str"), + ); + } } } @@ -123,6 +160,8 @@ pub(crate) unsafe fn codegen( // NOTE: without -fuse-linker-plugin, we get the following error: // lto1: internal compiler error: decompressed stream: Destination buffer is too small + // TODO(antoyo): since we do not do LTO when the linker is invoked anymore, perhaps + // the following flag is not necessary anymore. context.add_driver_option("-fuse-linker-plugin"); } @@ -131,11 +170,43 @@ pub(crate) unsafe fn codegen( // /usr/bin/ld: cannot find -lgcc_s: No such file or directory context.add_driver_option("-nostdlib"); - // NOTE: this doesn't actually generate an executable. With the above flags, it combines the .o files together in another .o. - context.compile_to_file( - OutputKind::Executable, - obj_out.to_str().expect("path to str"), - ); + let path = obj_out.to_str().expect("path to str"); + + if fat_lto { + let lto_path = format!("{}.lto", path); + // FIXME(antoyo): The LTO frontend generates the following warning: + // ../build_sysroot/sysroot_src/library/core/src/num/dec2flt/lemire.rs:150:15: warning: type of ā_ZN4core3num7dec2flt5table17POWER_OF_FIVE_12817ha449a68fb31379e4Eā does not match original declaration [-Wlto-type-mismatch] + // 150 | let (lo5, hi5) = POWER_OF_FIVE_128[index]; + // | ^ + // lto1: note: ā_ZN4core3num7dec2flt5table17POWER_OF_FIVE_12817ha449a68fb31379e4Eā was previously declared here + // + // This option is to mute it to make the UI tests pass with LTO enabled. + context.add_driver_option("-Wno-lto-type-mismatch"); + // NOTE: this doesn't actually generate an executable. With the above + // flags, it combines the .o files together in another .o. + context.compile_to_file(OutputKind::Executable, <o_path); + + let context = Context::default(); + if cgcx.target_arch == "x86" || cgcx.target_arch == "x86_64" { + // NOTE: it seems we need to use add_driver_option instead of + // add_command_line_option here because we use the LTO frontend via gcc. + context.add_driver_option("-masm=intel"); + } + + // NOTE: these two options are needed to invoke LTO to produce an object file. + // We need to initiate a second compilation because the arguments "-x lto" + // needs to be at the very beginning. + context.add_driver_option("-x"); + context.add_driver_option("lto"); + add_pic_option(&context, module.module_llvm.relocation_model); + context.add_driver_option(lto_path); + + context.compile_to_file(OutputKind::ObjectFile, path); + } else { + // NOTE: this doesn't actually generate an executable. With the above + // flags, it combines the .o files together in another .o. + context.compile_to_file(OutputKind::Executable, path); + } } else { context.compile_to_file( OutputKind::ObjectFile, |
