Rollup merge of #96587 - bjorn3:refactor_backend_write, r=michaelwoerister
Refactor the WriteBackendMethods and ExtraBackendMethods traits The new interface is slightly less confusing and is easier to implement for non-LLVM backends.
This commit is contained in:
commit
329a73dbd6
@ -139,14 +139,12 @@ fn target_features(&self, sess: &Session) -> Vec<Symbol> {
|
||||
}
|
||||
|
||||
impl ExtraBackendMethods for GccCodegenBackend {
|
||||
fn new_metadata<'tcx>(&self, _tcx: TyCtxt<'tcx>, _mod_name: &str) -> Self::Module {
|
||||
GccContext {
|
||||
fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, has_alloc_error_handler: bool) -> Self::Module {
|
||||
let mut mods = GccContext {
|
||||
context: Context::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, mods: &mut Self::Module, module_name: &str, kind: AllocatorKind, has_alloc_error_handler: bool) {
|
||||
unsafe { allocator::codegen(tcx, mods, module_name, kind, has_alloc_error_handler) }
|
||||
};
|
||||
unsafe { allocator::codegen(tcx, &mut mods, module_name, kind, has_alloc_error_handler); }
|
||||
mods
|
||||
}
|
||||
|
||||
fn compile_codegen_unit<'tcx>(&self, tcx: TyCtxt<'tcx>, cgu_name: Symbol) -> (ModuleCodegen<Self::Module>, u64) {
|
||||
@ -213,7 +211,7 @@ fn run_fat_lto(_cgcx: &CodegenContext<Self>, mut modules: Vec<FatLTOInput<Self>>
|
||||
unimplemented!();
|
||||
}
|
||||
};
|
||||
Ok(LtoModuleCodegen::Fat { module: Some(module), _serialized_bitcode: vec![] })
|
||||
Ok(LtoModuleCodegen::Fat { module, _serialized_bitcode: vec![] })
|
||||
}
|
||||
|
||||
fn run_thin_lto(_cgcx: &CodegenContext<Self>, _modules: Vec<(String, Self::ThinBuffer)>, _cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError> {
|
||||
@ -229,7 +227,12 @@ unsafe fn optimize(_cgcx: &CodegenContext<Self>, _diag_handler: &Handler, module
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn optimize_thin(_cgcx: &CodegenContext<Self>, _thin: &mut ThinModule<Self>) -> Result<ModuleCodegen<Self::Module>, FatalError> {
|
||||
fn optimize_fat(_cgcx: &CodegenContext<Self>, _module: &mut ModuleCodegen<Self::Module>) -> Result<(), FatalError> {
|
||||
// TODO(antoyo)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn optimize_thin(_cgcx: &CodegenContext<Self>, _thin: ThinModule<Self>) -> Result<ModuleCodegen<Self::Module>, FatalError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
@ -245,11 +248,6 @@ fn serialize_module(_module: ModuleCodegen<Self::Module>) -> (String, Self::Modu
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn run_lto_pass_manager(_cgcx: &CodegenContext<Self>, _module: &ModuleCodegen<Self::Module>, _config: &ModuleConfig, _thin: bool) -> Result<(), FatalError> {
|
||||
// TODO(antoyo)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_link(cgcx: &CodegenContext<Self>, diag_handler: &Handler, modules: Vec<ModuleCodegen<Self::Module>>) -> Result<ModuleCodegen<Self::Module>, FatalError> {
|
||||
back::write::link(cgcx, diag_handler, modules)
|
||||
}
|
||||
|
@ -6,9 +6,7 @@
|
||||
use crate::{llvm_util, LlvmCodegenBackend, ModuleLlvm};
|
||||
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
|
||||
use rustc_codegen_ssa::back::symbol_export;
|
||||
use rustc_codegen_ssa::back::write::{
|
||||
CodegenContext, FatLTOInput, ModuleConfig, TargetMachineFactoryConfig,
|
||||
};
|
||||
use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, TargetMachineFactoryConfig};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
@ -353,7 +351,7 @@ fn fat_lto(
|
||||
}
|
||||
}
|
||||
|
||||
Ok(LtoModuleCodegen::Fat { module: Some(module), _serialized_bitcode: serialized_bitcode })
|
||||
Ok(LtoModuleCodegen::Fat { module, _serialized_bitcode: serialized_bitcode })
|
||||
}
|
||||
|
||||
crate struct Linker<'a>(&'a mut llvm::Linker<'a>);
|
||||
@ -578,11 +576,11 @@ fn thin_lto(
|
||||
pub(crate) fn run_pass_manager(
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
diag_handler: &Handler,
|
||||
module: &ModuleCodegen<ModuleLlvm>,
|
||||
config: &ModuleConfig,
|
||||
module: &mut ModuleCodegen<ModuleLlvm>,
|
||||
thin: bool,
|
||||
) -> Result<(), FatalError> {
|
||||
let _timer = cgcx.prof.extra_verbose_generic_activity("LLVM_lto_optimize", &*module.name);
|
||||
let config = cgcx.config(module.kind);
|
||||
|
||||
// Now we have one massive module inside of llmod. Time to run the
|
||||
// LTO-specific optimization passes that LLVM provides.
|
||||
@ -726,7 +724,7 @@ fn drop(&mut self) {
|
||||
}
|
||||
|
||||
pub unsafe fn optimize_thin_module(
|
||||
thin_module: &mut ThinModule<LlvmCodegenBackend>,
|
||||
thin_module: ThinModule<LlvmCodegenBackend>,
|
||||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
) -> Result<ModuleCodegen<ModuleLlvm>, FatalError> {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
@ -743,7 +741,7 @@ pub unsafe fn optimize_thin_module(
|
||||
// that LLVM Context and Module.
|
||||
let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
|
||||
let llmod_raw = parse_module(llcx, module_name, thin_module.data(), &diag_handler)? as *const _;
|
||||
let module = ModuleCodegen {
|
||||
let mut module = ModuleCodegen {
|
||||
module_llvm: ModuleLlvm { llmod_raw, llcx, tm },
|
||||
name: thin_module.name().to_string(),
|
||||
kind: ModuleKind::Regular,
|
||||
@ -859,8 +857,7 @@ pub unsafe fn optimize_thin_module(
|
||||
// little differently.
|
||||
{
|
||||
info!("running thin lto passes over {}", module.name);
|
||||
let config = cgcx.config(module.kind);
|
||||
run_pass_manager(cgcx, &diag_handler, &module, config, true)?;
|
||||
run_pass_manager(cgcx, &diag_handler, &mut module, true)?;
|
||||
save_temp_bitcode(cgcx, &module, "thin-lto-after-pm");
|
||||
}
|
||||
}
|
||||
|
@ -104,19 +104,18 @@ fn drop(&mut self) {
|
||||
}
|
||||
|
||||
impl ExtraBackendMethods for LlvmCodegenBackend {
|
||||
fn new_metadata(&self, tcx: TyCtxt<'_>, mod_name: &str) -> ModuleLlvm {
|
||||
ModuleLlvm::new_metadata(tcx, mod_name)
|
||||
}
|
||||
|
||||
fn codegen_allocator<'tcx>(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
module_llvm: &mut ModuleLlvm,
|
||||
module_name: &str,
|
||||
kind: AllocatorKind,
|
||||
has_alloc_error_handler: bool,
|
||||
) {
|
||||
unsafe { allocator::codegen(tcx, module_llvm, module_name, kind, has_alloc_error_handler) }
|
||||
) -> ModuleLlvm {
|
||||
let mut module_llvm = ModuleLlvm::new_metadata(tcx, module_name);
|
||||
unsafe {
|
||||
allocator::codegen(tcx, &mut module_llvm, module_name, kind, has_alloc_error_handler);
|
||||
}
|
||||
module_llvm
|
||||
}
|
||||
fn compile_codegen_unit(
|
||||
&self,
|
||||
@ -210,9 +209,16 @@ unsafe fn optimize(
|
||||
) -> Result<(), FatalError> {
|
||||
back::write::optimize(cgcx, diag_handler, module, config)
|
||||
}
|
||||
fn optimize_fat(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
module: &mut ModuleCodegen<Self::Module>,
|
||||
) -> Result<(), FatalError> {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
back::lto::run_pass_manager(cgcx, &diag_handler, module, false)
|
||||
}
|
||||
unsafe fn optimize_thin(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
thin: &mut ThinModule<Self>,
|
||||
thin: ThinModule<Self>,
|
||||
) -> Result<ModuleCodegen<Self::Module>, FatalError> {
|
||||
back::lto::optimize_thin_module(thin, cgcx)
|
||||
}
|
||||
@ -230,15 +236,6 @@ fn prepare_thin(module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffe
|
||||
fn serialize_module(module: ModuleCodegen<Self::Module>) -> (String, Self::ModuleBuffer) {
|
||||
(module.name, back::lto::ModuleBuffer::new(module.module_llvm.llmod()))
|
||||
}
|
||||
fn run_lto_pass_manager(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
module: &ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
thin: bool,
|
||||
) -> Result<(), FatalError> {
|
||||
let diag_handler = cgcx.create_diag_handler();
|
||||
back::lto::run_pass_manager(cgcx, &diag_handler, module, config, thin)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for LlvmCodegenBackend {} // Llvm is on a per-thread basis
|
||||
|
@ -42,7 +42,7 @@ pub struct ThinShared<B: WriteBackendMethods> {
|
||||
|
||||
pub enum LtoModuleCodegen<B: WriteBackendMethods> {
|
||||
Fat {
|
||||
module: Option<ModuleCodegen<B::Module>>,
|
||||
module: ModuleCodegen<B::Module>,
|
||||
_serialized_bitcode: Vec<SerializedModule<B::ModuleBuffer>>,
|
||||
},
|
||||
|
||||
@ -64,19 +64,15 @@ pub fn name(&self) -> &str {
|
||||
/// It's intended that the module returned is immediately code generated and
|
||||
/// dropped, and then this LTO module is dropped.
|
||||
pub unsafe fn optimize(
|
||||
&mut self,
|
||||
self,
|
||||
cgcx: &CodegenContext<B>,
|
||||
) -> Result<ModuleCodegen<B::Module>, FatalError> {
|
||||
match *self {
|
||||
LtoModuleCodegen::Fat { ref mut module, .. } => {
|
||||
let module = module.take().unwrap();
|
||||
{
|
||||
let config = cgcx.config(module.kind);
|
||||
B::run_lto_pass_manager(cgcx, &module, config, false)?;
|
||||
}
|
||||
match self {
|
||||
LtoModuleCodegen::Fat { mut module, .. } => {
|
||||
B::optimize_fat(cgcx, &mut module)?;
|
||||
Ok(module)
|
||||
}
|
||||
LtoModuleCodegen::Thin(ref mut thin) => B::optimize_thin(cgcx, thin),
|
||||
LtoModuleCodegen::Thin(thin) => B::optimize_thin(cgcx, thin),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -889,7 +889,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
|
||||
|
||||
fn execute_lto_work_item<B: ExtraBackendMethods>(
|
||||
cgcx: &CodegenContext<B>,
|
||||
mut module: lto::LtoModuleCodegen<B>,
|
||||
module: lto::LtoModuleCodegen<B>,
|
||||
module_config: &ModuleConfig,
|
||||
) -> Result<WorkItemResult<B>, FatalError> {
|
||||
let module = unsafe { module.optimize(cgcx)? };
|
||||
|
@ -575,15 +575,8 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
||||
} else if let Some(kind) = tcx.allocator_kind(()) {
|
||||
let llmod_id =
|
||||
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string();
|
||||
let mut module_llvm = backend.new_metadata(tcx, &llmod_id);
|
||||
tcx.sess.time("write_allocator_module", || {
|
||||
backend.codegen_allocator(
|
||||
tcx,
|
||||
&mut module_llvm,
|
||||
&llmod_id,
|
||||
kind,
|
||||
tcx.lang_items().oom().is_some(),
|
||||
)
|
||||
let module_llvm = tcx.sess.time("write_allocator_module", || {
|
||||
backend.codegen_allocator(tcx, &llmod_id, kind, tcx.lang_items().oom().is_some())
|
||||
});
|
||||
|
||||
Some(ModuleCodegen { name: llmod_id, module_llvm, kind: ModuleKind::Allocator })
|
||||
|
@ -114,15 +114,13 @@ fn link(
|
||||
}
|
||||
|
||||
pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send + Sync {
|
||||
fn new_metadata(&self, sess: TyCtxt<'_>, mod_name: &str) -> Self::Module;
|
||||
fn codegen_allocator<'tcx>(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
module_llvm: &mut Self::Module,
|
||||
module_name: &str,
|
||||
kind: AllocatorKind,
|
||||
has_alloc_error_handler: bool,
|
||||
);
|
||||
) -> Self::Module;
|
||||
/// This generates the codegen unit and returns it along with
|
||||
/// a `u64` giving an estimate of the unit's processing cost.
|
||||
fn compile_codegen_unit(
|
||||
|
@ -41,9 +41,13 @@ unsafe fn optimize(
|
||||
module: &ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
) -> Result<(), FatalError>;
|
||||
fn optimize_fat(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
llmod: &mut ModuleCodegen<Self::Module>,
|
||||
) -> Result<(), FatalError>;
|
||||
unsafe fn optimize_thin(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
thin: &mut ThinModule<Self>,
|
||||
thin: ThinModule<Self>,
|
||||
) -> Result<ModuleCodegen<Self::Module>, FatalError>;
|
||||
unsafe fn codegen(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
@ -53,12 +57,6 @@ unsafe fn codegen(
|
||||
) -> Result<CompiledModule, FatalError>;
|
||||
fn prepare_thin(module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer);
|
||||
fn serialize_module(module: ModuleCodegen<Self::Module>) -> (String, Self::ModuleBuffer);
|
||||
fn run_lto_pass_manager(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
llmod: &ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
thin: bool,
|
||||
) -> Result<(), FatalError>;
|
||||
}
|
||||
|
||||
pub trait ThinBufferMethods: Send + Sync {
|
||||
|
Loading…
Reference in New Issue
Block a user