Remove tm_factory field from CodegenContext
This is necessary to support serializing the CodegenContext to a .rlink file in the future for moving LTO to the -Zlink-only step.
This commit is contained in:
parent
2d07e81a5c
commit
f49223c443
9 changed files with 157 additions and 119 deletions
|
|
@ -50,7 +50,7 @@ struct LtoData {
|
|||
}
|
||||
|
||||
fn prepare_lto(
|
||||
cgcx: &CodegenContext<GccCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
) -> LtoData {
|
||||
|
|
@ -111,7 +111,7 @@ fn save_as_file(obj: &[u8], path: &Path) -> Result<(), LtoBitcodeFromRlib> {
|
|||
/// Performs fat LTO by merging all modules into a single one and returning it
|
||||
/// for further optimization.
|
||||
pub(crate) fn run_fat(
|
||||
cgcx: &CodegenContext<GccCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
modules: Vec<FatLtoInput<GccCodegenBackend>>,
|
||||
|
|
@ -132,7 +132,7 @@ pub(crate) fn run_fat(
|
|||
}
|
||||
|
||||
fn fat_lto(
|
||||
cgcx: &CodegenContext<GccCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
_dcx: DiagCtxtHandle<'_>,
|
||||
modules: Vec<FatLtoInput<GccCodegenBackend>>,
|
||||
mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
|
||||
|
|
@ -283,7 +283,7 @@ impl ModuleBufferMethods for ModuleBuffer {
|
|||
/// lists, one of the modules that need optimization and another for modules that
|
||||
/// can simply be copied over from the incr. comp. cache.
|
||||
pub(crate) fn run_thin(
|
||||
cgcx: &CodegenContext<GccCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
modules: Vec<(String, ThinBuffer)>,
|
||||
|
|
@ -345,7 +345,7 @@ pub(crate) fn prepare_thin(module: ModuleCodegen<GccContext>) -> (String, ThinBu
|
|||
/// all of the `LtoModuleCodegen` units returned below and destroyed once
|
||||
/// they all go out of scope.
|
||||
fn thin_lto(
|
||||
cgcx: &CodegenContext<GccCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
_dcx: DiagCtxtHandle<'_>,
|
||||
modules: Vec<(String, ThinBuffer)>,
|
||||
serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
|
||||
|
|
@ -520,11 +520,9 @@ fn thin_lto(
|
|||
|
||||
pub fn optimize_thin_module(
|
||||
thin_module: ThinModule<GccCodegenBackend>,
|
||||
_cgcx: &CodegenContext<GccCodegenBackend>,
|
||||
_cgcx: &CodegenContext,
|
||||
) -> ModuleCodegen<GccContext> {
|
||||
//let module_name = &thin_module.shared.module_names[thin_module.idx];
|
||||
/*let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap());
|
||||
let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&dcx, e))?;*/
|
||||
|
||||
// Right now the implementation we've got only works over serialized
|
||||
// modules, so we create a fresh new LLVM context and parse the module
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ use rustc_target::spec::SplitDebuginfo;
|
|||
|
||||
use crate::base::add_pic_option;
|
||||
use crate::errors::CopyBitcode;
|
||||
use crate::{GccCodegenBackend, GccContext, LtoMode};
|
||||
use crate::{GccContext, LtoMode};
|
||||
|
||||
pub(crate) fn codegen(
|
||||
cgcx: &CodegenContext<GccCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
module: ModuleCodegen<GccContext>,
|
||||
config: &ModuleConfig,
|
||||
|
|
@ -227,7 +227,7 @@ pub(crate) fn codegen(
|
|||
}
|
||||
|
||||
pub(crate) fn save_temp_bitcode(
|
||||
cgcx: &CodegenContext<GccCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
_module: &ModuleCodegen<GccContext>,
|
||||
_name: &str,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -426,8 +426,9 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||
type ThinBuffer = ThinBuffer;
|
||||
|
||||
fn run_and_optimize_fat_lto(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
_tm_factory: TargetMachineFactoryFn<Self>,
|
||||
// FIXME(bjorn3): Limit LTO exports to these symbols
|
||||
_exported_symbols_for_lto: &[String],
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
|
|
@ -437,7 +438,7 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||
}
|
||||
|
||||
fn run_thin_lto(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
// FIXME(bjorn3): Limit LTO exports to these symbols
|
||||
_exported_symbols_for_lto: &[String],
|
||||
|
|
@ -457,7 +458,7 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||
}
|
||||
|
||||
fn optimize(
|
||||
_cgcx: &CodegenContext<Self>,
|
||||
_cgcx: &CodegenContext,
|
||||
_shared_emitter: &SharedEmitter,
|
||||
module: &mut ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
|
|
@ -466,15 +467,16 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||
}
|
||||
|
||||
fn optimize_thin(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
_shared_emitter: &SharedEmitter,
|
||||
_tm_factory: TargetMachineFactoryFn<Self>,
|
||||
thin: ThinModule<Self>,
|
||||
) -> ModuleCodegen<Self::Module> {
|
||||
back::lto::optimize_thin_module(thin, cgcx)
|
||||
}
|
||||
|
||||
fn codegen(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
module: ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ use std::{io, iter, slice};
|
|||
use object::read::archive::ArchiveFile;
|
||||
use object::{Object, ObjectSection};
|
||||
use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule, ThinShared};
|
||||
use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, SharedEmitter};
|
||||
use rustc_codegen_ssa::back::write::{
|
||||
CodegenContext, FatLtoInput, SharedEmitter, TargetMachineFactoryFn,
|
||||
};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
|
@ -33,7 +35,7 @@ use crate::{LlvmCodegenBackend, ModuleLlvm};
|
|||
const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin";
|
||||
|
||||
fn prepare_lto(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
exported_symbols_for_lto: &[String],
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
|
|
@ -123,7 +125,7 @@ fn prepare_lto(
|
|||
|
||||
fn get_bitcode_slice_from_object_data<'a>(
|
||||
obj: &'a [u8],
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
) -> Result<&'a [u8], LtoBitcodeFromRlib> {
|
||||
// We're about to assume the data here is an object file with sections, but if it's raw LLVM IR
|
||||
// that won't work. Fortunately, if that's what we have we can just return the object directly,
|
||||
|
|
@ -149,8 +151,9 @@ fn get_bitcode_slice_from_object_data<'a>(
|
|||
/// Performs fat LTO by merging all modules into a single one and returning it
|
||||
/// for further optimization.
|
||||
pub(crate) fn run_fat(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
tm_factory: TargetMachineFactoryFn<LlvmCodegenBackend>,
|
||||
exported_symbols_for_lto: &[String],
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
modules: Vec<FatLtoInput<LlvmCodegenBackend>>,
|
||||
|
|
@ -161,14 +164,22 @@ pub(crate) fn run_fat(
|
|||
prepare_lto(cgcx, exported_symbols_for_lto, each_linked_rlib_for_lto, dcx);
|
||||
let symbols_below_threshold =
|
||||
symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();
|
||||
fat_lto(cgcx, dcx, shared_emitter, modules, upstream_modules, &symbols_below_threshold)
|
||||
fat_lto(
|
||||
cgcx,
|
||||
dcx,
|
||||
shared_emitter,
|
||||
tm_factory,
|
||||
modules,
|
||||
upstream_modules,
|
||||
&symbols_below_threshold,
|
||||
)
|
||||
}
|
||||
|
||||
/// Performs thin LTO by performing necessary global analysis and returning two
|
||||
/// lists, one of the modules that need optimization and another for modules that
|
||||
/// can simply be copied over from the incr. comp. cache.
|
||||
pub(crate) fn run_thin(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
exported_symbols_for_lto: &[String],
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
|
|
@ -195,9 +206,10 @@ pub(crate) fn prepare_thin(module: ModuleCodegen<ModuleLlvm>) -> (String, ThinBu
|
|||
}
|
||||
|
||||
fn fat_lto(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
shared_emitter: &SharedEmitter,
|
||||
tm_factory: TargetMachineFactoryFn<LlvmCodegenBackend>,
|
||||
modules: Vec<FatLtoInput<LlvmCodegenBackend>>,
|
||||
mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
|
||||
symbols_below_threshold: &[*const libc::c_char],
|
||||
|
|
@ -252,7 +264,7 @@ fn fat_lto(
|
|||
assert!(!serialized_modules.is_empty(), "must have at least one serialized module");
|
||||
let (buffer, name) = serialized_modules.remove(0);
|
||||
info!("no in-memory regular modules to choose from, parsing {:?}", name);
|
||||
let llvm_module = ModuleLlvm::parse(cgcx, &name, buffer.data(), dcx);
|
||||
let llvm_module = ModuleLlvm::parse(cgcx, tm_factory, &name, buffer.data(), dcx);
|
||||
ModuleCodegen::new_regular(name.into_string().unwrap(), llvm_module)
|
||||
}
|
||||
};
|
||||
|
|
@ -381,7 +393,7 @@ impl Drop for Linker<'_> {
|
|||
/// all of the `LtoModuleCodegen` units returned below and destroyed once
|
||||
/// they all go out of scope.
|
||||
fn thin_lto(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
modules: Vec<(String, ThinBuffer)>,
|
||||
serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
|
||||
|
|
@ -585,7 +597,7 @@ pub(crate) fn enable_autodiff_settings(ad: &[config::AutoDiff]) {
|
|||
}
|
||||
|
||||
pub(crate) fn run_pass_manager(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
module: &mut ModuleCodegen<ModuleLlvm>,
|
||||
thin: bool,
|
||||
|
|
@ -726,8 +738,9 @@ impl Drop for ThinBuffer {
|
|||
}
|
||||
|
||||
pub(crate) fn optimize_thin_module(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
tm_factory: TargetMachineFactoryFn<LlvmCodegenBackend>,
|
||||
thin_module: ThinModule<LlvmCodegenBackend>,
|
||||
) -> ModuleCodegen<ModuleLlvm> {
|
||||
let dcx = DiagCtxt::new(Box::new(shared_emitter.clone()));
|
||||
|
|
@ -740,7 +753,7 @@ pub(crate) fn optimize_thin_module(
|
|||
// into that context. One day, however, we may do this for upstream
|
||||
// crates but for locally codegened modules we may be able to reuse
|
||||
// that LLVM Context and Module.
|
||||
let module_llvm = ModuleLlvm::parse(cgcx, module_name, thin_module.data(), dcx);
|
||||
let module_llvm = ModuleLlvm::parse(cgcx, tm_factory, module_name, thin_module.data(), dcx);
|
||||
let mut module = ModuleCodegen::new_regular(thin_module.name(), module_llvm);
|
||||
// Given that the newly created module lacks a thinlto buffer for embedding, we need to re-add it here.
|
||||
if cgcx.module_config.embed_bitcode() {
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ pub(crate) fn target_machine_factory(
|
|||
}
|
||||
|
||||
pub(crate) fn save_temp_bitcode(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
module: &ModuleCodegen<ModuleLlvm>,
|
||||
name: &str,
|
||||
) {
|
||||
|
|
@ -358,14 +358,14 @@ pub(crate) enum CodegenDiagnosticsStage {
|
|||
}
|
||||
|
||||
pub(crate) struct DiagnosticHandlers<'a> {
|
||||
data: *mut (&'a CodegenContext<LlvmCodegenBackend>, &'a SharedEmitter),
|
||||
data: *mut (&'a CodegenContext, &'a SharedEmitter),
|
||||
llcx: &'a llvm::Context,
|
||||
old_handler: Option<&'a llvm::DiagnosticHandler>,
|
||||
}
|
||||
|
||||
impl<'a> DiagnosticHandlers<'a> {
|
||||
pub(crate) fn new(
|
||||
cgcx: &'a CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &'a CodegenContext,
|
||||
shared_emitter: &'a SharedEmitter,
|
||||
llcx: &'a llvm::Context,
|
||||
module: &ModuleCodegen<ModuleLlvm>,
|
||||
|
|
@ -431,7 +431,7 @@ impl<'a> Drop for DiagnosticHandlers<'a> {
|
|||
}
|
||||
|
||||
fn report_inline_asm(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
msg: String,
|
||||
level: llvm::DiagnosticLevel,
|
||||
cookie: u64,
|
||||
|
|
@ -463,8 +463,7 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
|
|||
if user.is_null() {
|
||||
return;
|
||||
}
|
||||
let (cgcx, shared_emitter) =
|
||||
unsafe { *(user as *const (&CodegenContext<LlvmCodegenBackend>, &SharedEmitter)) };
|
||||
let (cgcx, shared_emitter) = unsafe { *(user as *const (&CodegenContext, &SharedEmitter)) };
|
||||
|
||||
let dcx = DiagCtxt::new(Box::new(shared_emitter.clone()));
|
||||
let dcx = dcx.handle();
|
||||
|
|
@ -560,7 +559,7 @@ pub(crate) enum AutodiffStage {
|
|||
}
|
||||
|
||||
pub(crate) unsafe fn llvm_optimize(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
module: &ModuleCodegen<ModuleLlvm>,
|
||||
thin_lto_buffer: Option<&mut *mut llvm::ThinLTOBuffer>,
|
||||
|
|
@ -892,7 +891,7 @@ pub(crate) unsafe fn llvm_optimize(
|
|||
|
||||
// Unsafe due to LLVM calls.
|
||||
pub(crate) fn optimize(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
module: &mut ModuleCodegen<ModuleLlvm>,
|
||||
config: &ModuleConfig,
|
||||
|
|
@ -983,7 +982,7 @@ pub(crate) fn optimize(
|
|||
}
|
||||
|
||||
pub(crate) fn codegen(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
module: ModuleCodegen<ModuleLlvm>,
|
||||
config: &ModuleConfig,
|
||||
|
|
@ -1238,7 +1237,7 @@ fn create_section_with_flags_asm(section_name: &str, section_flags: &str, data:
|
|||
asm
|
||||
}
|
||||
|
||||
pub(crate) fn bitcode_section_name(cgcx: &CodegenContext<LlvmCodegenBackend>) -> &'static CStr {
|
||||
pub(crate) fn bitcode_section_name(cgcx: &CodegenContext) -> &'static CStr {
|
||||
if cgcx.target_is_like_darwin {
|
||||
c"__LLVM,__bitcode"
|
||||
} else if cgcx.target_is_like_aix {
|
||||
|
|
@ -1250,7 +1249,7 @@ pub(crate) fn bitcode_section_name(cgcx: &CodegenContext<LlvmCodegenBackend>) ->
|
|||
|
||||
/// Embed the bitcode of an LLVM module for LTO in the LLVM module itself.
|
||||
fn embed_bitcode(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
llcx: &llvm::Context,
|
||||
llmod: &llvm::Module,
|
||||
bitcode: &[u8],
|
||||
|
|
@ -1334,11 +1333,7 @@ fn embed_bitcode(
|
|||
// when using MSVC linker. We do this only for data, as linker can fix up
|
||||
// code references on its own.
|
||||
// See #26591, #27438
|
||||
fn create_msvc_imps(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
llcx: &llvm::Context,
|
||||
llmod: &llvm::Module,
|
||||
) {
|
||||
fn create_msvc_imps(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::Module) {
|
||||
if !cgcx.msvc_imps_needed {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,8 +162,9 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
|||
print!("{stats}");
|
||||
}
|
||||
fn run_and_optimize_fat_lto(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
tm_factory: TargetMachineFactoryFn<LlvmCodegenBackend>,
|
||||
exported_symbols_for_lto: &[String],
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
modules: Vec<FatLtoInput<Self>>,
|
||||
|
|
@ -171,6 +172,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
|||
let mut module = back::lto::run_fat(
|
||||
cgcx,
|
||||
shared_emitter,
|
||||
tm_factory,
|
||||
exported_symbols_for_lto,
|
||||
each_linked_rlib_for_lto,
|
||||
modules,
|
||||
|
|
@ -183,7 +185,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
|||
module
|
||||
}
|
||||
fn run_thin_lto(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
exported_symbols_for_lto: &[String],
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
|
|
@ -200,7 +202,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
|||
)
|
||||
}
|
||||
fn optimize(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
module: &mut ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
|
|
@ -208,14 +210,15 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
|||
back::write::optimize(cgcx, shared_emitter, module, config)
|
||||
}
|
||||
fn optimize_thin(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
tm_factory: TargetMachineFactoryFn<LlvmCodegenBackend>,
|
||||
thin: ThinModule<Self>,
|
||||
) -> ModuleCodegen<Self::Module> {
|
||||
back::lto::optimize_thin_module(cgcx, shared_emitter, thin)
|
||||
back::lto::optimize_thin_module(cgcx, shared_emitter, tm_factory, thin)
|
||||
}
|
||||
fn codegen(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
module: ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
|
|
@ -438,16 +441,9 @@ impl ModuleLlvm {
|
|||
}
|
||||
}
|
||||
|
||||
fn tm_from_cgcx(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
name: &str,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
) -> OwnedTargetMachine {
|
||||
(cgcx.tm_factory)(dcx, TargetMachineFactoryConfig::new(cgcx, name))
|
||||
}
|
||||
|
||||
fn parse(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext,
|
||||
tm_factory: TargetMachineFactoryFn<LlvmCodegenBackend>,
|
||||
name: &CStr,
|
||||
buffer: &[u8],
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
|
|
@ -456,7 +452,7 @@ impl ModuleLlvm {
|
|||
let llcx = llvm::LLVMContextCreate();
|
||||
llvm::LLVMContextSetDiscardValueNames(llcx, cgcx.fewer_names.to_llvm_bool());
|
||||
let llmod_raw = back::lto::parse_module(llcx, name, buffer, dcx);
|
||||
let tm = ModuleLlvm::tm_from_cgcx(cgcx, name.to_str().unwrap(), dcx);
|
||||
let tm = tm_factory(dcx, TargetMachineFactoryConfig::new(cgcx, name.to_str().unwrap()));
|
||||
|
||||
ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,10 +127,7 @@ pub(super) fn exported_symbols_for_lto(
|
|||
symbols_below_threshold
|
||||
}
|
||||
|
||||
pub(super) fn check_lto_allowed<B: WriteBackendMethods>(
|
||||
cgcx: &CodegenContext<B>,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
) {
|
||||
pub(super) fn check_lto_allowed(cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>) {
|
||||
if cgcx.lto == Lto::ThinLocal {
|
||||
// Crate local LTO is always allowed
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
|
|||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::config::{
|
||||
self, CrateType, Lto, OutFileName, OutputFilenames, OutputType, Passes, SwitchWithOptPath,
|
||||
self, CrateType, Lto, OptLevel, OutFileName, OutputFilenames, OutputType, Passes,
|
||||
SwitchWithOptPath,
|
||||
};
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::{FileName, InnerSpan, Span, SpanData};
|
||||
|
|
@ -287,10 +288,7 @@ pub struct TargetMachineFactoryConfig {
|
|||
}
|
||||
|
||||
impl TargetMachineFactoryConfig {
|
||||
pub fn new(
|
||||
cgcx: &CodegenContext<impl WriteBackendMethods>,
|
||||
module_name: &str,
|
||||
) -> TargetMachineFactoryConfig {
|
||||
pub fn new(cgcx: &CodegenContext, module_name: &str) -> TargetMachineFactoryConfig {
|
||||
let split_dwarf_file = if cgcx.target_can_use_split_dwarf {
|
||||
cgcx.output_filenames.split_dwarf_path(
|
||||
cgcx.split_debuginfo,
|
||||
|
|
@ -322,7 +320,7 @@ pub type TargetMachineFactoryFn<B> = Arc<
|
|||
|
||||
/// Additional resources used by optimize_and_codegen (not module specific)
|
||||
#[derive(Clone)]
|
||||
pub struct CodegenContext<B: WriteBackendMethods> {
|
||||
pub struct CodegenContext {
|
||||
// Resources needed when running LTO
|
||||
pub prof: SelfProfilerRef,
|
||||
pub lto: Lto,
|
||||
|
|
@ -336,7 +334,8 @@ pub struct CodegenContext<B: WriteBackendMethods> {
|
|||
pub output_filenames: Arc<OutputFilenames>,
|
||||
pub invocation_temp: Option<String>,
|
||||
pub module_config: Arc<ModuleConfig>,
|
||||
pub tm_factory: TargetMachineFactoryFn<B>,
|
||||
pub opt_level: OptLevel,
|
||||
pub backend_features: Vec<String>,
|
||||
pub msvc_imps_needed: bool,
|
||||
pub is_pe_coff: bool,
|
||||
pub target_can_use_split_dwarf: bool,
|
||||
|
|
@ -363,7 +362,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
|
|||
}
|
||||
|
||||
fn generate_thin_lto_work<B: ExtraBackendMethods>(
|
||||
cgcx: &CodegenContext<B>,
|
||||
cgcx: &CodegenContext,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
exported_symbols_for_lto: &[String],
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
|
|
@ -409,7 +408,7 @@ enum MaybeLtoModules<B: WriteBackendMethods> {
|
|||
allocator_module: Option<CompiledModule>,
|
||||
},
|
||||
FatLto {
|
||||
cgcx: CodegenContext<B>,
|
||||
cgcx: CodegenContext,
|
||||
exported_symbols_for_lto: Arc<Vec<String>>,
|
||||
each_linked_rlib_file_for_lto: Vec<PathBuf>,
|
||||
needs_fat_lto: Vec<FatLtoInput<B>>,
|
||||
|
|
@ -417,7 +416,7 @@ enum MaybeLtoModules<B: WriteBackendMethods> {
|
|||
Vec<(SerializedModule<<B as WriteBackendMethods>::ModuleBuffer>, WorkProduct)>,
|
||||
},
|
||||
ThinLto {
|
||||
cgcx: CodegenContext<B>,
|
||||
cgcx: CodegenContext,
|
||||
exported_symbols_for_lto: Arc<Vec<String>>,
|
||||
each_linked_rlib_file_for_lto: Vec<PathBuf>,
|
||||
needs_thin_lto: Vec<(String, <B as WriteBackendMethods>::ThinBuffer)>,
|
||||
|
|
@ -841,7 +840,7 @@ pub(crate) fn compute_per_cgu_lto_type(
|
|||
}
|
||||
|
||||
fn execute_optimize_work_item<B: ExtraBackendMethods>(
|
||||
cgcx: &CodegenContext<B>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: SharedEmitter,
|
||||
mut module: ModuleCodegen<B::Module>,
|
||||
) -> WorkItemResult<B> {
|
||||
|
|
@ -896,8 +895,8 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
|
|||
}
|
||||
}
|
||||
|
||||
fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
|
||||
cgcx: &CodegenContext<B>,
|
||||
fn execute_copy_from_cache_work_item(
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: SharedEmitter,
|
||||
module: CachedModuleCodegen,
|
||||
) -> CompiledModule {
|
||||
|
|
@ -985,8 +984,9 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
|
|||
}
|
||||
|
||||
fn do_fat_lto<B: ExtraBackendMethods>(
|
||||
cgcx: &CodegenContext<B>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: SharedEmitter,
|
||||
tm_factory: TargetMachineFactoryFn<B>,
|
||||
exported_symbols_for_lto: &[String],
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
mut needs_fat_lto: Vec<FatLtoInput<B>>,
|
||||
|
|
@ -1006,6 +1006,7 @@ fn do_fat_lto<B: ExtraBackendMethods>(
|
|||
let module = B::run_and_optimize_fat_lto(
|
||||
cgcx,
|
||||
&shared_emitter,
|
||||
tm_factory,
|
||||
exported_symbols_for_lto,
|
||||
each_linked_rlib_for_lto,
|
||||
needs_fat_lto,
|
||||
|
|
@ -1014,8 +1015,9 @@ fn do_fat_lto<B: ExtraBackendMethods>(
|
|||
}
|
||||
|
||||
fn do_thin_lto<'a, B: ExtraBackendMethods>(
|
||||
cgcx: &'a CodegenContext<B>,
|
||||
cgcx: &'a CodegenContext,
|
||||
shared_emitter: SharedEmitter,
|
||||
tm_factory: TargetMachineFactoryFn<B>,
|
||||
exported_symbols_for_lto: Arc<Vec<String>>,
|
||||
each_linked_rlib_for_lto: Vec<PathBuf>,
|
||||
needs_thin_lto: Vec<(String, <B as WriteBackendMethods>::ThinBuffer)>,
|
||||
|
|
@ -1052,7 +1054,7 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>(
|
|||
// bunch of work items onto our queue to do LTO. This all
|
||||
// happens on the coordinator thread but it's very quick so
|
||||
// we don't worry about tokens.
|
||||
for (work, cost) in generate_thin_lto_work(
|
||||
for (work, cost) in generate_thin_lto_work::<B>(
|
||||
cgcx,
|
||||
dcx,
|
||||
&exported_symbols_for_lto,
|
||||
|
|
@ -1096,7 +1098,13 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>(
|
|||
while used_token_count < tokens.len() + 1
|
||||
&& let Some((item, _)) = work_items.pop()
|
||||
{
|
||||
spawn_thin_lto_work(&cgcx, shared_emitter.clone(), coordinator_send.clone(), item);
|
||||
spawn_thin_lto_work(
|
||||
&cgcx,
|
||||
shared_emitter.clone(),
|
||||
Arc::clone(&tm_factory),
|
||||
coordinator_send.clone(),
|
||||
item,
|
||||
);
|
||||
used_token_count += 1;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1157,13 +1165,14 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>(
|
|||
}
|
||||
|
||||
fn execute_thin_lto_work_item<B: ExtraBackendMethods>(
|
||||
cgcx: &CodegenContext<B>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: SharedEmitter,
|
||||
tm_factory: TargetMachineFactoryFn<B>,
|
||||
module: lto::ThinModule<B>,
|
||||
) -> CompiledModule {
|
||||
let _timer = cgcx.prof.generic_activity_with_arg("codegen_module_perform_lto", module.name());
|
||||
|
||||
let module = B::optimize_thin(cgcx, &shared_emitter, module);
|
||||
let module = B::optimize_thin(cgcx, &shared_emitter, tm_factory, module);
|
||||
B::codegen(cgcx, &shared_emitter, module, &cgcx.module_config)
|
||||
}
|
||||
|
||||
|
|
@ -1291,8 +1300,9 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
})
|
||||
.expect("failed to spawn helper thread");
|
||||
|
||||
let ol = tcx.backend_optimization_level(());
|
||||
let backend_features = tcx.global_backend_features(());
|
||||
let opt_level = tcx.backend_optimization_level(());
|
||||
let backend_features = tcx.global_backend_features(()).clone();
|
||||
let tm_factory = backend.target_machine_factory(tcx.sess, opt_level, &backend_features);
|
||||
|
||||
let remark_dir = if let Some(ref dir) = sess.opts.unstable_opts.remark_dir {
|
||||
let result = fs::create_dir_all(dir).and_then(|_| dir.canonicalize());
|
||||
|
|
@ -1304,7 +1314,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
None
|
||||
};
|
||||
|
||||
let cgcx = CodegenContext::<B> {
|
||||
let cgcx = CodegenContext {
|
||||
crate_types: tcx.crate_types().to_vec(),
|
||||
lto: sess.lto(),
|
||||
use_linker_plugin_lto: sess.opts.cg.linker_plugin_lto.enabled(),
|
||||
|
|
@ -1319,7 +1329,8 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()),
|
||||
output_filenames: Arc::clone(tcx.output_filenames(())),
|
||||
module_config: regular_config,
|
||||
tm_factory: backend.target_machine_factory(tcx.sess, ol, backend_features),
|
||||
opt_level,
|
||||
backend_features,
|
||||
msvc_imps_needed: msvc_imps_needed(tcx),
|
||||
is_pe_coff: tcx.sess.target.is_like_windows,
|
||||
target_can_use_split_dwarf: tcx.sess.target_can_use_split_dwarf(),
|
||||
|
|
@ -1775,9 +1786,10 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
assert!(needs_fat_lto.is_empty());
|
||||
|
||||
if cgcx.lto == Lto::ThinLocal {
|
||||
compiled_modules.extend(do_thin_lto(
|
||||
compiled_modules.extend(do_thin_lto::<B>(
|
||||
&cgcx,
|
||||
shared_emitter.clone(),
|
||||
tm_factory,
|
||||
exported_symbols_for_lto,
|
||||
each_linked_rlib_file_for_lto,
|
||||
needs_thin_lto,
|
||||
|
|
@ -1871,7 +1883,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
pub(crate) struct WorkerFatalError;
|
||||
|
||||
fn spawn_work<'a, B: ExtraBackendMethods>(
|
||||
cgcx: &'a CodegenContext<B>,
|
||||
cgcx: &'a CodegenContext,
|
||||
shared_emitter: SharedEmitter,
|
||||
coordinator_send: Sender<Message<B>>,
|
||||
llvm_start_time: &mut Option<VerboseTimingGuard<'a>>,
|
||||
|
|
@ -1909,8 +1921,9 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
|
|||
}
|
||||
|
||||
fn spawn_thin_lto_work<'a, B: ExtraBackendMethods>(
|
||||
cgcx: &'a CodegenContext<B>,
|
||||
cgcx: &'a CodegenContext,
|
||||
shared_emitter: SharedEmitter,
|
||||
tm_factory: TargetMachineFactoryFn<B>,
|
||||
coordinator_send: Sender<ThinLtoMessage>,
|
||||
work: ThinLtoWorkItem<B>,
|
||||
) {
|
||||
|
|
@ -1921,7 +1934,9 @@ fn spawn_thin_lto_work<'a, B: ExtraBackendMethods>(
|
|||
ThinLtoWorkItem::CopyPostLtoArtifacts(m) => {
|
||||
execute_copy_from_cache_work_item(&cgcx, shared_emitter, m)
|
||||
}
|
||||
ThinLtoWorkItem::ThinLto(m) => execute_thin_lto_work_item(&cgcx, shared_emitter, m),
|
||||
ThinLtoWorkItem::ThinLto(m) => {
|
||||
execute_thin_lto_work_item(&cgcx, shared_emitter, tm_factory, m)
|
||||
}
|
||||
}));
|
||||
|
||||
let msg = match result {
|
||||
|
|
@ -2158,34 +2173,52 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
|
|||
each_linked_rlib_file_for_lto,
|
||||
needs_fat_lto,
|
||||
lto_import_only_modules,
|
||||
} => CompiledModules {
|
||||
modules: vec![do_fat_lto(
|
||||
&cgcx,
|
||||
shared_emitter,
|
||||
&exported_symbols_for_lto,
|
||||
&each_linked_rlib_file_for_lto,
|
||||
needs_fat_lto,
|
||||
lto_import_only_modules,
|
||||
)],
|
||||
allocator_module: None,
|
||||
},
|
||||
} => {
|
||||
let tm_factory = self.backend.target_machine_factory(
|
||||
sess,
|
||||
cgcx.opt_level,
|
||||
&cgcx.backend_features,
|
||||
);
|
||||
|
||||
CompiledModules {
|
||||
modules: vec![do_fat_lto(
|
||||
&cgcx,
|
||||
shared_emitter,
|
||||
tm_factory,
|
||||
&exported_symbols_for_lto,
|
||||
&each_linked_rlib_file_for_lto,
|
||||
needs_fat_lto,
|
||||
lto_import_only_modules,
|
||||
)],
|
||||
allocator_module: None,
|
||||
}
|
||||
}
|
||||
MaybeLtoModules::ThinLto {
|
||||
cgcx,
|
||||
exported_symbols_for_lto,
|
||||
each_linked_rlib_file_for_lto,
|
||||
needs_thin_lto,
|
||||
lto_import_only_modules,
|
||||
} => CompiledModules {
|
||||
modules: do_thin_lto(
|
||||
&cgcx,
|
||||
shared_emitter,
|
||||
exported_symbols_for_lto,
|
||||
each_linked_rlib_file_for_lto,
|
||||
needs_thin_lto,
|
||||
lto_import_only_modules,
|
||||
),
|
||||
allocator_module: None,
|
||||
},
|
||||
} => {
|
||||
let tm_factory = self.backend.target_machine_factory(
|
||||
sess,
|
||||
cgcx.opt_level,
|
||||
&cgcx.backend_features,
|
||||
);
|
||||
|
||||
CompiledModules {
|
||||
modules: do_thin_lto::<B>(
|
||||
&cgcx,
|
||||
shared_emitter,
|
||||
tm_factory,
|
||||
exported_symbols_for_lto,
|
||||
each_linked_rlib_file_for_lto,
|
||||
needs_thin_lto,
|
||||
lto_import_only_modules,
|
||||
),
|
||||
allocator_module: None,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
shared_emitter_main.check(sess, true);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ use rustc_errors::DiagCtxtHandle;
|
|||
use rustc_middle::dep_graph::WorkProduct;
|
||||
|
||||
use crate::back::lto::{SerializedModule, ThinModule};
|
||||
use crate::back::write::{CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter};
|
||||
use crate::back::write::{
|
||||
CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter, TargetMachineFactoryFn,
|
||||
};
|
||||
use crate::{CompiledModule, ModuleCodegen};
|
||||
|
||||
pub trait WriteBackendMethods: Clone + 'static {
|
||||
|
|
@ -17,8 +19,9 @@ pub trait WriteBackendMethods: Clone + 'static {
|
|||
/// Performs fat LTO by merging all modules into a single one, running autodiff
|
||||
/// if necessary and running any further optimizations
|
||||
fn run_and_optimize_fat_lto(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
tm_factory: TargetMachineFactoryFn<Self>,
|
||||
exported_symbols_for_lto: &[String],
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
modules: Vec<FatLtoInput<Self>>,
|
||||
|
|
@ -27,7 +30,7 @@ pub trait WriteBackendMethods: Clone + 'static {
|
|||
/// lists, one of the modules that need optimization and another for modules that
|
||||
/// can simply be copied over from the incr. comp. cache.
|
||||
fn run_thin_lto(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
exported_symbols_for_lto: &[String],
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
|
|
@ -37,18 +40,19 @@ pub trait WriteBackendMethods: Clone + 'static {
|
|||
fn print_pass_timings(&self);
|
||||
fn print_statistics(&self);
|
||||
fn optimize(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
module: &mut ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
);
|
||||
fn optimize_thin(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
tm_factory: TargetMachineFactoryFn<Self>,
|
||||
thin: ThinModule<Self>,
|
||||
) -> ModuleCodegen<Self::Module>;
|
||||
fn codegen(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
cgcx: &CodegenContext,
|
||||
shared_emitter: &SharedEmitter,
|
||||
module: ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue